Skip to content

Commit b1e0f06

Browse files
salrashid123tseaver
authored andcommitted
Add span_id to LogEntry (#5885)
1 parent 396d079 commit b1e0f06

File tree

4 files changed

+193
-46
lines changed

4 files changed

+193
-46
lines changed

google/cloud/logging/entries.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,14 @@ class _BaseEntry(object):
7979
8080
:type trace: str
8181
:param trace: (optional) traceid to apply to the entry.
82+
83+
:type span_id: str
84+
:param span_id: (optional) span_id within the trace for the log entry.
85+
Specify the trace parameter if span_id is set.
8286
"""
8387
def __init__(self, payload, logger, insert_id=None, timestamp=None,
8488
labels=None, severity=None, http_request=None, resource=None,
85-
trace=None):
89+
trace=None, span_id=None):
8690
self.payload = payload
8791
self.logger = logger
8892
self.insert_id = insert_id
@@ -92,6 +96,7 @@ def __init__(self, payload, logger, insert_id=None, timestamp=None,
9296
self.http_request = http_request
9397
self.resource = resource
9498
self.trace = trace
99+
self.span_id = span_id
95100

96101
@classmethod
97102
def from_api_repr(cls, resource, client, loggers=None):
@@ -129,6 +134,7 @@ def from_api_repr(cls, resource, client, loggers=None):
129134
severity = resource.get('severity')
130135
http_request = resource.get('httpRequest')
131136
trace = resource.get('trace')
137+
span_id = resource.get('spanId')
132138

133139
monitored_resource_dict = resource.get('resource')
134140
monitored_resource = None
@@ -137,7 +143,7 @@ def from_api_repr(cls, resource, client, loggers=None):
137143

138144
return cls(payload, logger, insert_id=insert_id, timestamp=timestamp,
139145
labels=labels, severity=severity, http_request=http_request,
140-
resource=monitored_resource, trace=trace)
146+
resource=monitored_resource, trace=trace, span_id=span_id)
141147

142148

143149
class TextEntry(_BaseEntry):
@@ -194,16 +200,20 @@ class ProtobufEntry(_BaseEntry):
194200
195201
:type trace: str
196202
:param trace: (optional) traceid to apply to the entry.
203+
204+
:type span_id: str
205+
:param span_id: (optional) span_id within the trace for the log entry.
206+
Specify the trace parameter if span_id is set.
197207
"""
198208
_PAYLOAD_KEY = 'protoPayload'
199209

200210
def __init__(self, payload, logger, insert_id=None, timestamp=None,
201211
labels=None, severity=None, http_request=None, resource=None,
202-
trace=None):
212+
trace=None, span_id=None):
203213
super(ProtobufEntry, self).__init__(
204214
payload, logger, insert_id=insert_id, timestamp=timestamp,
205215
labels=labels, severity=severity, http_request=http_request,
206-
resource=resource, trace=trace)
216+
resource=resource, trace=trace, span_id=span_id)
207217
if isinstance(self.payload, any_pb2.Any):
208218
self.payload_pb = self.payload
209219
self.payload = None

google/cloud/logging/logger.py

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,8 @@ def batch(self, client=None):
9696
def _make_entry_resource(self, text=None, info=None, message=None,
9797
labels=None, insert_id=None, severity=None,
9898
http_request=None, timestamp=None,
99-
resource=_GLOBAL_RESOURCE, trace=None):
99+
resource=_GLOBAL_RESOURCE, trace=None,
100+
span_id=None):
100101
"""Return a log entry resource of the appropriate type.
101102
102103
Helper for :meth:`log_text`, :meth:`log_struct`, and :meth:`log_proto`.
@@ -134,6 +135,10 @@ def _make_entry_resource(self, text=None, info=None, message=None,
134135
:type trace: str
135136
:param trace: (optional) traceid to apply to the entry.
136137
138+
:type span_id: str
139+
:param span_id: (optional) span_id within the trace for the log entry.
140+
Specify the trace parameter if span_id is set.
141+
137142
:rtype: dict
138143
:returns: The JSON resource created.
139144
"""
@@ -178,11 +183,14 @@ def _make_entry_resource(self, text=None, info=None, message=None,
178183
if trace is not None:
179184
entry['trace'] = trace
180185

186+
if span_id is not None:
187+
entry['spanId'] = span_id
188+
181189
return entry
182190

183191
def log_text(self, text, client=None, labels=None, insert_id=None,
184192
severity=None, http_request=None, timestamp=None,
185-
resource=_GLOBAL_RESOURCE, trace=None):
193+
resource=_GLOBAL_RESOURCE, trace=None, span_id=None):
186194
"""API call: log a text message via a POST request
187195
188196
See
@@ -218,17 +226,21 @@ def log_text(self, text, client=None, labels=None, insert_id=None,
218226
219227
:type trace: str
220228
:param trace: (optional) traceid to apply to the entry.
229+
230+
:type span_id: str
231+
:param span_id: (optional) span_id within the trace for the log entry.
232+
Specify the trace parameter if span_id is set.
221233
"""
222234
client = self._require_client(client)
223235
entry_resource = self._make_entry_resource(
224236
text=text, labels=labels, insert_id=insert_id, severity=severity,
225237
http_request=http_request, timestamp=timestamp, resource=resource,
226-
trace=trace)
238+
trace=trace, span_id=span_id)
227239
client.logging_api.write_entries([entry_resource])
228240

229241
def log_struct(self, info, client=None, labels=None, insert_id=None,
230242
severity=None, http_request=None, timestamp=None,
231-
resource=_GLOBAL_RESOURCE, trace=None):
243+
resource=_GLOBAL_RESOURCE, trace=None, span_id=None):
232244
"""API call: log a structured message via a POST request
233245
234246
See
@@ -264,17 +276,21 @@ def log_struct(self, info, client=None, labels=None, insert_id=None,
264276
265277
:type trace: str
266278
:param trace: (optional) traceid to apply to the entry.
279+
280+
:type span_id: str
281+
:param span_id: (optional) span_id within the trace for the log entry.
282+
Specify the trace parameter if span_id is set.
267283
"""
268284
client = self._require_client(client)
269285
entry_resource = self._make_entry_resource(
270286
info=info, labels=labels, insert_id=insert_id, severity=severity,
271287
http_request=http_request, timestamp=timestamp, resource=resource,
272-
trace=trace)
288+
trace=trace, span_id=span_id)
273289
client.logging_api.write_entries([entry_resource])
274290

275291
def log_proto(self, message, client=None, labels=None, insert_id=None,
276292
severity=None, http_request=None, timestamp=None,
277-
resource=_GLOBAL_RESOURCE, trace=None):
293+
resource=_GLOBAL_RESOURCE, trace=None, span_id=None):
278294
"""API call: log a protobuf message via a POST request
279295
280296
See
@@ -310,12 +326,16 @@ def log_proto(self, message, client=None, labels=None, insert_id=None,
310326
311327
:type trace: str
312328
:param trace: (optional) traceid to apply to the entry.
329+
330+
:type span_id: str
331+
:param span_id: (optional) span_id within the trace for the log entry.
332+
Specify the trace parameter if span_id is set.
313333
"""
314334
client = self._require_client(client)
315335
entry_resource = self._make_entry_resource(
316336
message=message, labels=labels, insert_id=insert_id,
317337
severity=severity, http_request=http_request, timestamp=timestamp,
318-
resource=resource, trace=trace)
338+
resource=resource, trace=trace, span_id=span_id)
319339
client.logging_api.write_entries([entry_resource])
320340

321341
def delete(self, client=None):
@@ -410,7 +430,7 @@ def __exit__(self, exc_type, exc_val, exc_tb):
410430

411431
def log_text(self, text, labels=None, insert_id=None, severity=None,
412432
http_request=None, timestamp=None, resource=_GLOBAL_RESOURCE,
413-
trace=None):
433+
trace=None, span_id=None):
414434
"""Add a text entry to be logged during :meth:`commit`.
415435
416436
:type text: str
@@ -441,14 +461,18 @@ def log_text(self, text, labels=None, insert_id=None, severity=None,
441461
442462
:type trace: str
443463
:param trace: (optional) traceid to apply to the entry.
464+
465+
:type span_id: str
466+
:param span_id: (optional) span_id within the trace for the log entry.
467+
Specify the trace parameter if span_id is set.
444468
"""
445469
self.entries.append(
446470
('text', text, labels, insert_id, severity, http_request,
447-
timestamp, resource, trace))
471+
timestamp, resource, trace, span_id))
448472

449473
def log_struct(self, info, labels=None, insert_id=None, severity=None,
450474
http_request=None, timestamp=None,
451-
resource=_GLOBAL_RESOURCE, trace=None):
475+
resource=_GLOBAL_RESOURCE, trace=None, span_id=None):
452476
"""Add a struct entry to be logged during :meth:`commit`.
453477
454478
:type info: dict
@@ -479,14 +503,18 @@ def log_struct(self, info, labels=None, insert_id=None, severity=None,
479503
480504
:type trace: str
481505
:param trace: (optional) traceid to apply to the entry.
506+
507+
:type span_id: str
508+
:param span_id: (optional) span_id within the trace for the log entry.
509+
Specify the trace parameter if span_id is set.
482510
"""
483511
self.entries.append(
484512
('struct', info, labels, insert_id, severity, http_request,
485-
timestamp, resource, trace))
513+
timestamp, resource, trace, span_id))
486514

487515
def log_proto(self, message, labels=None, insert_id=None, severity=None,
488516
http_request=None, timestamp=None,
489-
resource=_GLOBAL_RESOURCE, trace=None):
517+
resource=_GLOBAL_RESOURCE, trace=None, span_id=None):
490518
"""Add a protobuf entry to be logged during :meth:`commit`.
491519
492520
:type message: protobuf message
@@ -517,10 +545,14 @@ def log_proto(self, message, labels=None, insert_id=None, severity=None,
517545
518546
:type trace: str
519547
:param trace: (optional) traceid to apply to the entry.
548+
549+
:type span_id: str
550+
:param span_id: (optional) span_id within the trace for the log entry.
551+
Specify the trace parameter if span_id is set.
520552
"""
521553
self.entries.append(
522554
('proto', message, labels, insert_id, severity, http_request,
523-
timestamp, resource, trace))
555+
timestamp, resource, trace, span_id))
524556

525557
def commit(self, client=None):
526558
"""Send saved log entries as a single API call.
@@ -544,7 +576,7 @@ def commit(self, client=None):
544576

545577
entries = []
546578
for (entry_type, entry, labels, iid, severity, http_req,
547-
timestamp, resource, trace) in self.entries:
579+
timestamp, resource, trace, span_id) in self.entries:
548580
if entry_type == 'text':
549581
info = {'textPayload': entry}
550582
elif entry_type == 'struct':
@@ -573,6 +605,8 @@ def commit(self, client=None):
573605
info['timestamp'] = _datetime_to_rfc3339(timestamp)
574606
if trace is not None:
575607
info['trace'] = trace
608+
if span_id is not None:
609+
info['spanId'] = span_id
576610
entries.append(info)
577611

578612
client.logging_api.write_entries(entries, **kwargs)

tests/unit/test_entries.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ def test_ctor_defaults(self):
6969
self.assertIsNone(entry.http_request)
7070
self.assertIsNone(entry.resource)
7171
self.assertIsNone(entry.trace)
72+
self.assertIsNone(entry.span_id)
7273

7374
def test_ctor_explicit(self):
7475
import datetime
@@ -89,6 +90,7 @@ def test_ctor_explicit(self):
8990
}
9091
resource = Resource(type='global', labels={})
9192
TRACE = '12345678-1234-5678-1234-567812345678'
93+
SPANID = '000000000000004a'
9294

9395
logger = _Logger(self.LOGGER_NAME, self.PROJECT)
9496
entry = self._make_one(PAYLOAD, logger,
@@ -98,7 +100,8 @@ def test_ctor_explicit(self):
98100
severity=SEVERITY,
99101
http_request=REQUEST,
100102
resource=resource,
101-
trace=TRACE)
103+
trace=TRACE,
104+
span_id=SPANID)
102105
self.assertEqual(entry.payload, PAYLOAD)
103106
self.assertIs(entry.logger, logger)
104107
self.assertEqual(entry.insert_id, IID)
@@ -110,6 +113,7 @@ def test_ctor_explicit(self):
110113
self.assertEqual(entry.http_request['status'], STATUS)
111114
self.assertEqual(entry.resource, resource)
112115
self.assertEqual(entry.trace, TRACE)
116+
self.assertEqual(entry.span_id, SPANID)
113117

114118
def test_from_api_repr_missing_data_no_loggers(self):
115119
client = _Client(self.PROJECT)
@@ -127,6 +131,7 @@ def test_from_api_repr_missing_data_no_loggers(self):
127131
self.assertIsNone(entry.severity)
128132
self.assertIsNone(entry.http_request)
129133
self.assertIsNone(entry.trace)
134+
self.assertIsNone(entry.span_id)
130135
logger = entry.logger
131136
self.assertIsInstance(logger, _Logger)
132137
self.assertIs(logger.client, client)
@@ -160,6 +165,7 @@ def test_from_api_repr_w_loggers_no_logger_match(self):
160165
)
161166
STATUS = '500'
162167
TRACE = '12345678-1234-5678-1234-567812345678'
168+
SPANID = '000000000000004a'
163169
API_REPR = {
164170
'dummyPayload': PAYLOAD,
165171
'logName': LOG_NAME,
@@ -173,7 +179,8 @@ def test_from_api_repr_w_loggers_no_logger_match(self):
173179
'status': STATUS,
174180
},
175181
'resource': RESOURCE._to_dict(),
176-
'trace': TRACE
182+
'trace': TRACE,
183+
'spanId': SPANID
177184
}
178185
loggers = {}
179186
entry = klass.from_api_repr(API_REPR, client, loggers=loggers)
@@ -192,6 +199,7 @@ def test_from_api_repr_w_loggers_no_logger_match(self):
192199
self.assertEqual(loggers, {LOG_NAME: logger})
193200
self.assertEqual(entry.resource, RESOURCE)
194201
self.assertEqual(entry.trace, TRACE)
202+
self.assertEqual(entry.span_id, SPANID)
195203

196204
def test_from_api_repr_w_loggers_w_logger_match(self):
197205
from datetime import datetime
@@ -205,13 +213,15 @@ def test_from_api_repr_w_loggers_w_logger_match(self):
205213
LOG_NAME = 'projects/%s/logs/%s' % (self.PROJECT, self.LOGGER_NAME)
206214
LABELS = {'foo': 'bar', 'baz': 'qux'}
207215
TRACE = '12345678-1234-5678-1234-567812345678'
216+
SPANID = '000000000000004a'
208217
API_REPR = {
209218
'dummyPayload': PAYLOAD,
210219
'logName': LOG_NAME,
211220
'insertId': IID,
212221
'timestamp': TIMESTAMP,
213222
'labels': LABELS,
214-
'trace': TRACE
223+
'trace': TRACE,
224+
'spanId': SPANID
215225
}
216226
LOGGER = object()
217227
loggers = {LOG_NAME: LOGGER}
@@ -222,6 +232,7 @@ def test_from_api_repr_w_loggers_w_logger_match(self):
222232
self.assertEqual(entry.timestamp, NOW)
223233
self.assertEqual(entry.labels, LABELS)
224234
self.assertEqual(entry.trace, TRACE)
235+
self.assertEqual(entry.span_id, SPANID)
225236
self.assertIs(entry.logger, LOGGER)
226237

227238

@@ -251,6 +262,7 @@ def test_constructor_basic(self):
251262
self.assertIsNone(pb_entry.severity)
252263
self.assertIsNone(pb_entry.http_request)
253264
self.assertIsNone(pb_entry.trace)
265+
self.assertIsNone(pb_entry.span_id)
254266

255267
def test_constructor_with_any(self):
256268
from google.protobuf.any_pb2 import Any
@@ -266,6 +278,7 @@ def test_constructor_with_any(self):
266278
self.assertIsNone(pb_entry.severity)
267279
self.assertIsNone(pb_entry.http_request)
268280
self.assertIsNone(pb_entry.trace)
281+
self.assertIsNone(pb_entry.span_id)
269282

270283
def test_parse_message(self):
271284
import json

0 commit comments

Comments
 (0)