@@ -61,10 +61,99 @@ def _int_or_none(value):
61
61
return value
62
62
63
63
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
+
66
150
received_timestamp = None
67
151
152
+ @classmethod
153
+ def _extract_payload (cls , resource ):
154
+ """Helper for :meth:`from_api_repr`"""
155
+ return None
156
+
68
157
@classmethod
69
158
def from_api_repr (cls , resource , client , loggers = None ):
70
159
"""Factory: construct an entry given its API representation
@@ -92,10 +181,7 @@ def from_api_repr(cls, resource, client, loggers=None):
92
181
if logger is None :
93
182
logger_name = logger_name_from_path (logger_fullname )
94
183
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 )
99
185
insert_id = resource .get ('insertId' )
100
186
timestamp = resource .get ('timestamp' )
101
187
if timestamp is not None :
@@ -118,10 +204,7 @@ def from_api_repr(cls, resource, client, loggers=None):
118
204
monitored_resource = Resource ._from_dict (monitored_resource_dict )
119
205
120
206
inst = cls (
121
- entry_type = cls ._TYPE_NAME ,
122
207
log_name = logger_fullname ,
123
- payload = payload ,
124
- logger = logger ,
125
208
insert_id = insert_id ,
126
209
timestamp = timestamp ,
127
210
labels = labels ,
@@ -132,7 +215,9 @@ def from_api_repr(cls, resource, client, loggers=None):
132
215
span_id = span_id ,
133
216
trace_sampled = trace_sampled ,
134
217
source_location = source_location ,
135
- operation = operation
218
+ operation = operation ,
219
+ logger = logger ,
220
+ payload = payload ,
136
221
)
137
222
received = resource .get ('receiveTimestamp' )
138
223
if received is not None :
@@ -142,20 +227,7 @@ def from_api_repr(cls, resource, client, loggers=None):
142
227
def to_api_repr (self ):
143
228
"""API repr (JSON format) for entry.
144
229
"""
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 = {}
159
231
if self .log_name is not None :
160
232
info ['logName' ] = self .log_name
161
233
if self .resource is not None :
@@ -185,160 +257,66 @@ def to_api_repr(self):
185
257
return info
186
258
187
259
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 ):
300
261
__doc__ = """
301
262
Log entry with text payload.
302
263
264
+ """ + _LOG_ENTRY_PARAM_DOCSTRING + """
265
+
303
266
:type payload: str | unicode
304
267
: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
308
269
270
+ @classmethod
271
+ def _extract_payload (cls , resource ):
272
+ """Helper for :meth:`from_api_repr`"""
273
+ return resource ['textPayload' ]
309
274
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
314
281
315
282
316
- class StructEntry (_StructEntryTuple , _ApiReprMixin ):
283
+ class StructEntry (LogEntry ):
317
284
__doc__ = """
318
285
Log entry with JSON payload.
319
286
287
+ """ + _LOG_ENTRY_PARAM_DOCSTRING + """
288
+
320
289
:type payload: dict
321
290
: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
325
292
293
+ @classmethod
294
+ def _extract_payload (cls , resource ):
295
+ """Helper for :meth:`from_api_repr`"""
296
+ return resource ['jsonPayload' ]
326
297
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
331
304
332
305
333
- class ProtobufEntry (_ProtobufEntryTuple , _ApiReprMixin ):
306
+ class ProtobufEntry (LogEntry ):
334
307
__doc__ = """
335
308
Log entry with protobuf message payload.
336
309
310
+ """ + _LOG_ENTRY_PARAM_DOCSTRING + """
311
+
337
312
:type payload: protobuf message
338
313
: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' ]
342
320
343
321
@property
344
322
def payload_pb (self ):
@@ -350,6 +328,13 @@ def payload_json(self):
350
328
if not isinstance (self .payload , Any ):
351
329
return self .payload
352
330
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
+
353
338
def parse_message (self , message ):
354
339
"""Parse payload into a protobuf message.
355
340
0 commit comments