Skip to content

Commit 397152c

Browse files
chore: patch imported log entries to handle dict to protobuf parsing (#12711)
* chore: patch imported log entries to handle dict to protobuf parsing problem patch logs to replace /protoPayload/serviceData with /protoPayload/metadata. handle the problem with python logging library that fails to parse dict to protobuf when dict has deprecated field serviceData. * chore: fix linting errors * chore: fix lint error and incorrect call of _patch_entry method * chore: fix another lint error * chore: minor update in README link reflects adding new lines to the code. --------- Co-authored-by: Maciej Strzelczyk <strzelczyk@google.com>
1 parent 5ccacad commit 397152c

File tree

3 files changed

+113
-2
lines changed

3 files changed

+113
-2
lines changed

logging/import-logs/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,4 +129,4 @@ After applying the changes, [build](#build) a custom container image and use it
129129
[retention]: https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry#FIELDS.timestamp
130130
[current]: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/e2709a218072c86ec1a9b9101db45057ebfdbff0/logging/import-logs/main.py
131131
[code1]: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/86f12a752a4171e137adaa855c7247be9d5d39a2/logging/import-logs/main.py#L81-L83
132-
[code2]: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/86f12a752a4171e137adaa855c7247be9d5d39a2/logging/import-logs/main.py#L186-L187
132+
[code2]: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/86f12a752a4171e137adaa855c7247be9d5d39a2/logging/import-logs/main.py#L188-L189

logging/import-logs/main.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,8 @@ def _patch_entry(log: dict, project_id: str) -> None:
173173
"""Modify entry fields to allow importing entry to destination project.
174174
175175
Save logName as a user label.
176-
Replace logName with the fixed value "projects/PROJECT_ID/logs/imported_logs"
176+
Replace logName with the fixed value "projects/PROJECT_ID/logs/imported_logs".
177+
Rename the obsolete key "serviceData" with "metadata".
177178
"""
178179
log_name = log.get("logName")
179180
labels = log.get("labels")
@@ -182,6 +183,13 @@ def _patch_entry(log: dict, project_id: str) -> None:
182183
labels = dict()
183184
log["labels"] = labels
184185
labels["original_logName"] = log_name
186+
# TODO: remove after the following issue is fixed:
187+
# https://github.com/googleapis/python-logging/issues/945
188+
if "protoPayload" in log:
189+
payload = log.get("protoPayload")
190+
if "serviceData" in payload:
191+
# the following line changes the place of metadata in the dictionary
192+
payload["metadata"] = payload.pop("serviceData")
185193
# uncomment the following 2 lines if import range includes dates older than 29 days from now
186194
# labels["original_timestamp"] = log["timestamp"]
187195
# log["timestamp"] = None

logging/import-logs/main_test.py

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,106 @@ def test_parse_date() -> None:
369369
assert (
370370
test_date_str == TEST_DATE_STR
371371
), f"expected {TEST_DATE_STR}, got {test_date_str}"
372+
373+
374+
TEST_LOG_WITH_SERVICEDATA = {
375+
"logName": "projects/someproject/logs/somelog",
376+
"protoPayload": {
377+
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
378+
"authenticationInfo": {
379+
"principalEmail": "service@gcp-sa-scc-notification.iam.gserviceaccount.com"
380+
},
381+
"authorizationInfo": [
382+
{
383+
"granted": True,
384+
"permission": "bigquery.tables.update",
385+
"resource": "projects/someproject/datasets/someds/tables/sometbl",
386+
"resourceAttributes": {}
387+
}
388+
],
389+
"serviceData": {
390+
'@type': 'type.googleapis.com/google.cloud.bigquery.logging.v1.AuditData',
391+
'tableUpdateRequest': {
392+
'resource': {
393+
'info': {},
394+
'schemaJson': '{}',
395+
'updateTime': '2024-08-20T15:01:48.399Z',
396+
'view': {}
397+
}
398+
}
399+
},
400+
"methodName": "google.cloud.bigquery.v2.TableService.PatchTable",
401+
"requestMetadata": {
402+
"callerIp": "private",
403+
"destinationAttributes": {},
404+
"requestAttributes": {}
405+
},
406+
"resourceName": "projects/someproject/datasets/someds/tables/sometbl",
407+
"serviceName": "bigquery.googleapis.com",
408+
"status": {}
409+
},
410+
"resource": {
411+
"labels": {
412+
"dataset_id": "someds",
413+
"project_id": "someproject"
414+
},
415+
"type": "bigquery_dataset"
416+
},
417+
"severity": "NOTICE",
418+
}
419+
TEST_LOG_WITH_PATCHED_SERVICEDATA = {
420+
"logName": f"projects/{TEST_PROJECT_ID}/logs/imported_logs",
421+
"protoPayload": {
422+
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
423+
"authenticationInfo": {
424+
"principalEmail": "service@gcp-sa-scc-notification.iam.gserviceaccount.com"
425+
},
426+
"authorizationInfo": [
427+
{
428+
"granted": True,
429+
"permission": "bigquery.tables.update",
430+
"resource": "projects/someproject/datasets/someds/tables/sometbl",
431+
"resourceAttributes": {}
432+
}
433+
],
434+
# this field is renamed from 'serviceData'
435+
"metadata": {
436+
'@type': 'type.googleapis.com/google.cloud.bigquery.logging.v1.AuditData',
437+
'tableUpdateRequest': {
438+
'resource': {
439+
'info': {},
440+
'schemaJson': '{}',
441+
'updateTime': '2024-08-20T15:01:48.399Z',
442+
'view': {}
443+
}
444+
}
445+
},
446+
"methodName": "google.cloud.bigquery.v2.TableService.PatchTable",
447+
"requestMetadata": {
448+
"callerIp": "private",
449+
"destinationAttributes": {},
450+
"requestAttributes": {}
451+
},
452+
"resourceName": "projects/someproject/datasets/someds/tables/sometbl",
453+
"serviceName": "bigquery.googleapis.com",
454+
"status": {}
455+
},
456+
"resource": {
457+
"labels": {
458+
"dataset_id": "someds",
459+
"project_id": "someproject"
460+
},
461+
"type": "bigquery_dataset"
462+
},
463+
"labels": {
464+
"original_logName": "projects/someproject/logs/somelog",
465+
},
466+
"severity": "NOTICE",
467+
}
468+
469+
470+
def test_patch_serviceData_field() -> None:
471+
log = dict(TEST_LOG_WITH_SERVICEDATA)
472+
main._patch_entry(log, TEST_PROJECT_ID)
473+
474+
assert (log == TEST_LOG_WITH_PATCHED_SERVICEDATA)

0 commit comments

Comments
 (0)