Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 11f6ef6

Browse filesBrowse files
committed
Refactor:
- Remove 'entry_type' and 'PAYLOAD_KEY' warts, dispatching instead based on class to load / save payload. Normalize inheritance hierarchy, removing spurious named tuples. Drop 'EmptyEntry': just use 'LogEntry'.
1 parent 2f0f4df commit 11f6ef6
Copy full SHA for 11f6ef6

File tree

Expand file treeCollapse file tree

7 files changed

+278
-280
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+278
-280
lines changed

‎logging/docs/entries.rst

Copy file name to clipboardExpand all lines: logging/docs/entries.rst
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ Entries
33

44
.. automodule:: google.cloud.logging.entries
55
:members:
6-
:inherited-members:
6+
:show-inheritance:
77
:member-order: groupwise

‎logging/google/cloud/logging/_helpers.py

Copy file name to clipboardExpand all lines: logging/google/cloud/logging/_helpers.py
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
import requests
1818

19-
from google.cloud.logging.entries import EmptyEntry
19+
from google.cloud.logging.entries import LogEntry
2020
from google.cloud.logging.entries import ProtobufEntry
2121
from google.cloud.logging.entries import StructEntry
2222
from google.cloud.logging.entries import TextEntry
@@ -54,7 +54,7 @@ def entry_from_resource(resource, client, loggers):
5454
if 'protoPayload' in resource:
5555
return ProtobufEntry.from_api_repr(resource, client, loggers)
5656

57-
return EmptyEntry.from_api_repr(resource, client, loggers)
57+
return LogEntry.from_api_repr(resource, client, loggers)
5858

5959

6060
def retrieve_metadata_server(metadata_key):

‎logging/google/cloud/logging/entries.py

Copy file name to clipboardExpand all lines: logging/google/cloud/logging/entries.py
+140-155Lines changed: 140 additions & 155 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,99 @@ def _int_or_none(value):
6161
return value
6262

6363

64-
class _ApiReprMixin(object):
65-
"""Mixin for the various log entry types."""
64+
_LOG_ENTRY_FIELDS = ( # (name, default)
65+
('log_name', None),
66+
('labels', None),
67+
('insert_id', None),
68+
('severity', None),
69+
('http_request', None),
70+
('timestamp', None),
71+
('resource', _GLOBAL_RESOURCE),
72+
('trace', None),
73+
('span_id', None),
74+
('trace_sampled', None),
75+
('source_location', None),
76+
('operation', None),
77+
('logger', None),
78+
('payload', None),
79+
)
80+
81+
82+
_LogEntryTuple = collections.namedtuple(
83+
'LogEntry', (field for field, _ in _LOG_ENTRY_FIELDS))
84+
85+
_LogEntryTuple.__new__.__defaults__ = tuple(
86+
default for _, default in _LOG_ENTRY_FIELDS)
87+
88+
89+
_LOG_ENTRY_PARAM_DOCSTRING = """\
90+
91+
:type log_name: str
92+
:param log_name: the name of the logger used to post the entry.
93+
94+
:type labels: dict
95+
:param labels: (optional) mapping of labels for the entry
96+
97+
:type insert_id: text
98+
:param insert_id: (optional) the ID used to identify an entry uniquely.
99+
100+
:type severity: str
101+
:param severity: (optional) severity of event being logged.
102+
103+
:type http_request: dict
104+
:param http_request: (optional) info about HTTP request associated with
105+
the entry.
106+
107+
:type timestamp: :class:`datetime.datetime`
108+
:param timestamp: (optional) timestamp for the entry
109+
110+
:type resource: :class:`~google.cloud.logging.resource.Resource`
111+
:param resource: (Optional) Monitored resource of the entry
112+
113+
:type trace: str
114+
:param trace: (optional) traceid to apply to the entry.
115+
116+
:type span_id: str
117+
:param span_id: (optional) span_id within the trace for the log entry.
118+
Specify the trace parameter if span_id is set.
119+
120+
:type trace_sampled: bool
121+
:param trace_sampled: (optional) the sampling decision of the trace
122+
associated with the log entry.
123+
124+
:type source_location: dict
125+
:param source_location: (optional) location in source code from which
126+
the entry was emitted.
127+
128+
:type operation: dict
129+
:param operation: (optional) additional information about a potentially
130+
long-running operation associated with the log entry.
131+
132+
:type logger: :class:`google.cloud.logging.logger.Logger`
133+
:param logger: the logger used to write the entry.
134+
135+
"""
136+
137+
_LOG_ENTRY_SEE_ALSO_DOCSTRING = """\
138+
139+
See:
140+
https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
141+
"""
142+
143+
144+
class LogEntry(_LogEntryTuple):
145+
__doc__ = """
146+
Log entry.
147+
148+
""" + _LOG_ENTRY_PARAM_DOCSTRING + _LOG_ENTRY_SEE_ALSO_DOCSTRING
149+
66150
received_timestamp = None
67151

152+
@classmethod
153+
def _extract_payload(cls, resource):
154+
"""Helper for :meth:`from_api_repr`"""
155+
return None
156+
68157
@classmethod
69158
def from_api_repr(cls, resource, client, loggers=None):
70159
"""Factory: construct an entry given its API representation
@@ -92,10 +181,7 @@ def from_api_repr(cls, resource, client, loggers=None):
92181
if logger is None:
93182
logger_name = logger_name_from_path(logger_fullname)
94183
logger = loggers[logger_fullname] = client.logger(logger_name)
95-
if cls._PAYLOAD_KEY is not None:
96-
payload = resource[cls._PAYLOAD_KEY]
97-
else:
98-
payload = None
184+
payload = cls._extract_payload(resource)
99185
insert_id = resource.get('insertId')
100186
timestamp = resource.get('timestamp')
101187
if timestamp is not None:
@@ -118,10 +204,7 @@ def from_api_repr(cls, resource, client, loggers=None):
118204
monitored_resource = Resource._from_dict(monitored_resource_dict)
119205

120206
inst = cls(
121-
entry_type=cls._TYPE_NAME,
122207
log_name=logger_fullname,
123-
payload=payload,
124-
logger=logger,
125208
insert_id=insert_id,
126209
timestamp=timestamp,
127210
labels=labels,
@@ -132,7 +215,9 @@ def from_api_repr(cls, resource, client, loggers=None):
132215
span_id=span_id,
133216
trace_sampled=trace_sampled,
134217
source_location=source_location,
135-
operation=operation
218+
operation=operation,
219+
logger=logger,
220+
payload=payload,
136221
)
137222
received = resource.get('receiveTimestamp')
138223
if received is not None:
@@ -142,20 +227,7 @@ def from_api_repr(cls, resource, client, loggers=None):
142227
def to_api_repr(self):
143228
"""API repr (JSON format) for entry.
144229
"""
145-
if self.entry_type == 'text':
146-
info = {'textPayload': self.payload}
147-
elif self.entry_type == 'struct':
148-
info = {'jsonPayload': self.payload}
149-
elif self.entry_type == 'proto':
150-
# NOTE: If ``self`` contains an ``Any`` field with an
151-
# unknown type, this will fail with a ``TypeError``.
152-
# However, since ``self`` was provided by a user in
153-
# ``Batch.log_proto``, the assumption is that any types
154-
# needed for the protobuf->JSON conversion will be known
155-
# from already imported ``pb2`` modules.
156-
info = {'protoPayload': MessageToDict(self.payload)}
157-
else: # no payload
158-
info = {}
230+
info = {}
159231
if self.log_name is not None:
160232
info['logName'] = self.log_name
161233
if self.resource is not None:
@@ -185,160 +257,66 @@ def to_api_repr(self):
185257
return info
186258

187259

188-
_LOG_ENTRY_FIELDS = ( # (name, default)
189-
('entry_type', None),
190-
('log_name', None),
191-
('payload', None),
192-
('logger', None),
193-
('labels', None),
194-
('insert_id', None),
195-
('severity', None),
196-
('http_request', None),
197-
('timestamp', None),
198-
('resource', _GLOBAL_RESOURCE),
199-
('trace', None),
200-
('span_id', None),
201-
('trace_sampled', None),
202-
('source_location', None),
203-
('operation', None),
204-
)
205-
206-
207-
_LogEntryTuple = collections.namedtuple(
208-
'LogEntry', (field for field, _ in _LOG_ENTRY_FIELDS))
209-
210-
_LogEntryTuple.__new__.__defaults__ = tuple(
211-
default for _, default in _LOG_ENTRY_FIELDS[1:])
212-
213-
214-
_LOG_ENTRY_PARAM_DOCSTRING = """\
215-
216-
:type logger: :class:`google.cloud.logging.logger.Logger`
217-
:param logger: the logger used to write the entry.
218-
219-
:type log_name: str
220-
:param log_name: the name of the logger used to post the entry.
221-
222-
:type labels: dict
223-
:param labels: (optional) mapping of labels for the entry
224-
225-
:type insert_id: text
226-
:param insert_id: (optional) the ID used to identify an entry uniquely.
227-
228-
:type severity: str
229-
:param severity: (optional) severity of event being logged.
230-
231-
:type http_request: dict
232-
:param http_request: (optional) info about HTTP request associated with
233-
the entry.
234-
235-
:type timestamp: :class:`datetime.datetime`
236-
:param timestamp: (optional) timestamp for the entry
237-
238-
:type resource: :class:`~google.cloud.logging.resource.Resource`
239-
:param resource: (Optional) Monitored resource of the entry
240-
241-
:type trace: str
242-
:param trace: (optional) traceid to apply to the entry.
243-
244-
:type span_id: str
245-
:param span_id: (optional) span_id within the trace for the log entry.
246-
Specify the trace parameter if span_id is set.
247-
248-
:type trace_sampled: bool
249-
:param trace_sampled: (optional) the sampling decision of the trace
250-
associated with the log entry.
251-
252-
:type source_location: dict
253-
:param source_location: (optional) location in source code from which
254-
the entry was emitted.
255-
256-
:type operation: dict
257-
:param operation: (optional) additional information about a potentially
258-
long-running operation associated with the log entry.
259-
260-
See:
261-
https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry
262-
"""
263-
264-
265-
class LogEntry(_LogEntryTuple, _ApiReprMixin):
266-
__doc__ = """
267-
Log entry.
268-
269-
:type entry_type: str
270-
:param entry_type: one of 'empty', 'text', 'struct', or 'proto'. Indicates
271-
how the payload field is handled.
272-
273-
:type payload: None, str | unicode, dict, protobuf message
274-
:param payload: payload for the message, based on :attr:`entry_type`
275-
""" + _LOG_ENTRY_PARAM_DOCSTRING
276-
277-
278-
_EmptyEntryTuple = collections.namedtuple(
279-
'EmptyEntry', (field for field, _ in _LOG_ENTRY_FIELDS))
280-
_EmptyEntryTuple.__new__.__defaults__ = (
281-
('empty',) + tuple(default for _, default in _LOG_ENTRY_FIELDS[1:]))
282-
283-
284-
class EmptyEntry(_EmptyEntryTuple, _ApiReprMixin):
285-
__doc__ = """
286-
Log entry without payload.
287-
288-
""" + _LOG_ENTRY_PARAM_DOCSTRING
289-
_PAYLOAD_KEY = None
290-
_TYPE_NAME = 'empty'
291-
292-
293-
_TextEntryTuple = collections.namedtuple(
294-
'TextEntry', (field for field, _ in _LOG_ENTRY_FIELDS))
295-
_TextEntryTuple.__new__.__defaults__ = (
296-
('text',) + tuple(default for _, default in _LOG_ENTRY_FIELDS[1:]))
297-
298-
299-
class TextEntry(_TextEntryTuple, _ApiReprMixin):
260+
class TextEntry(LogEntry):
300261
__doc__ = """
301262
Log entry with text payload.
302263
264+
""" + _LOG_ENTRY_PARAM_DOCSTRING + """
265+
303266
:type payload: str | unicode
304267
:param payload: payload for the log entry.
305-
""" + _LOG_ENTRY_PARAM_DOCSTRING
306-
_PAYLOAD_KEY = 'textPayload'
307-
_TYPE_NAME = 'text'
268+
""" + _LOG_ENTRY_SEE_ALSO_DOCSTRING
308269

270+
@classmethod
271+
def _extract_payload(cls, resource):
272+
"""Helper for :meth:`from_api_repr`"""
273+
return resource['textPayload']
309274

310-
_StructEntryTuple = collections.namedtuple(
311-
'StructEntry', (field for field, _ in _LOG_ENTRY_FIELDS))
312-
_StructEntryTuple.__new__.__defaults__ = (
313-
('struct',) + tuple(default for _, default in _LOG_ENTRY_FIELDS[1:]))
275+
def to_api_repr(self):
276+
"""API repr (JSON format) for entry.
277+
"""
278+
info = super(TextEntry, self).to_api_repr()
279+
info['textPayload'] = self.payload
280+
return info
314281

315282

316-
class StructEntry(_StructEntryTuple, _ApiReprMixin):
283+
class StructEntry(LogEntry):
317284
__doc__ = """
318285
Log entry with JSON payload.
319286
287+
""" + _LOG_ENTRY_PARAM_DOCSTRING + """
288+
320289
:type payload: dict
321290
:param payload: payload for the log entry.
322-
""" + _LOG_ENTRY_PARAM_DOCSTRING
323-
_PAYLOAD_KEY = 'jsonPayload'
324-
_TYPE_NAME = 'struct'
291+
""" + _LOG_ENTRY_SEE_ALSO_DOCSTRING
325292

293+
@classmethod
294+
def _extract_payload(cls, resource):
295+
"""Helper for :meth:`from_api_repr`"""
296+
return resource['jsonPayload']
326297

327-
_ProtobufEntryTuple = collections.namedtuple(
328-
'ProtobufEntry', (field for field, _ in _LOG_ENTRY_FIELDS))
329-
_ProtobufEntryTuple.__new__.__defaults__ = (
330-
('proto',) + tuple(default for _, default in _LOG_ENTRY_FIELDS[1:]))
298+
def to_api_repr(self):
299+
"""API repr (JSON format) for entry.
300+
"""
301+
info = super(StructEntry, self).to_api_repr()
302+
info['jsonPayload'] = self.payload
303+
return info
331304

332305

333-
class ProtobufEntry(_ProtobufEntryTuple, _ApiReprMixin):
306+
class ProtobufEntry(LogEntry):
334307
__doc__ = """
335308
Log entry with protobuf message payload.
336309
310+
""" + _LOG_ENTRY_PARAM_DOCSTRING + """
311+
337312
:type payload: protobuf message
338313
:param payload: payload for the log entry.
339-
""" + _LOG_ENTRY_PARAM_DOCSTRING
340-
_PAYLOAD_KEY = 'protoPayload'
341-
_TYPE_NAME = 'proto'
314+
""" + _LOG_ENTRY_SEE_ALSO_DOCSTRING
315+
316+
@classmethod
317+
def _extract_payload(cls, resource):
318+
"""Helper for :meth:`from_api_repr`"""
319+
return resource['protoPayload']
342320

343321
@property
344322
def payload_pb(self):
@@ -350,6 +328,13 @@ def payload_json(self):
350328
if not isinstance(self.payload, Any):
351329
return self.payload
352330

331+
def to_api_repr(self):
332+
"""API repr (JSON format) for entry.
333+
"""
334+
info = super(ProtobufEntry, self).to_api_repr()
335+
info['protoPayload'] = MessageToDict(self.payload)
336+
return info
337+
353338
def parse_message(self, message):
354339
"""Parse payload into a protobuf message.
355340

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.