Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: record source locations #254

Merged
merged 29 commits into from Apr 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
dc2e4a8
added structured log handler
daniel-sanche Mar 18, 2021
0e37217
Merge branch 'master' into structured-log-handler-2
daniel-sanche Mar 18, 2021
3a32c3d
improved structured log handler
daniel-sanche Mar 18, 2021
e454c38
refactored GCPFilter
daniel-sanche Mar 18, 2021
761eccd
moved and renamed filter
daniel-sanche Mar 18, 2021
4495cf5
fixed up broken filter
daniel-sanche Mar 18, 2021
6a3a595
blackened
daniel-sanche Apr 1, 2021
3c1af26
fixed typo
daniel-sanche Apr 1, 2021
cb8b57b
fixed lint
daniel-sanche Apr 1, 2021
f25da46
expanded on comment
daniel-sanche Apr 2, 2021
b686173
updated environment tests
daniel-sanche Apr 5, 2021
dc85dd3
Merge branch 'master' into structured-log-handler-2
daniel-sanche Apr 5, 2021
133c584
moved location of stdout log template
daniel-sanche Apr 5, 2021
637f95c
added new test for structured log class
daniel-sanche Apr 5, 2021
570bc2d
added a test with http_request data
daniel-sanche Apr 5, 2021
3aa5baa
improved structured log tests
daniel-sanche Apr 5, 2021
d1014f2
export CloudLoggingFilter in __init__ file
daniel-sanche Apr 5, 2021
5bec0ea
added more tests
daniel-sanche Apr 5, 2021
7392bd2
added a test for user overrides
daniel-sanche Apr 5, 2021
cf20b69
fixed lint issues
daniel-sanche Apr 5, 2021
12d2d37
removed timestamp from structured log output
daniel-sanche Apr 6, 2021
237e68c
added source location to filter
daniel-sanche Apr 7, 2021
bd84214
remove appengine tests
daniel-sanche Apr 7, 2021
ed7b070
reverted span naming scheme
daniel-sanche Apr 7, 2021
4ae78d4
removed unused timestamp field
daniel-sanche Apr 7, 2021
636dc3c
Merge branch 'structured-log-handler-2' into add-source-locations
daniel-sanche Apr 7, 2021
614d1bf
remove unneeded imports
daniel-sanche Apr 7, 2021
c861b12
Merge branch 'structured-log-handler-2' into add-source-locations
daniel-sanche Apr 7, 2021
dcf0fed
Merge branch 'v2_update_2' into add-source-locations
daniel-sanche Apr 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
24 changes: 16 additions & 8 deletions google/cloud/logging_v2/handlers/handlers.py
Expand Up @@ -126,6 +126,8 @@ def __init__(
self.project_id = client.project
self.resource = resource
self.labels = labels
# add extra keys to log record
self.addFilter(CloudLoggingFilter(self.project_id))

def emit(self, record):
"""Actually log the specified logging record.
Expand All @@ -138,25 +140,31 @@ def emit(self, record):
record (logging.LogRecord): The record to be logged.
"""
message = super(CloudLoggingHandler, self).format(record)
trace_id = getattr(record, "trace", None)
span_id = getattr(record, "span_id", None)
http_request = getattr(record, "http_request", None)
resource = getattr(record, "resource", self.resource)
user_labels = getattr(record, "labels", {})
# merge labels
total_labels = self.labels if self.labels is not None else {}
total_labels.update(user_labels)
if len(total_labels) == 0:
total_labels = None
# create source location object
if record.lineno and record.funcName and record.pathname:

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can some of the 3 be empty? For example, code that's not part of any function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, these are all part of the official record object spec, so the attributes will all exist.

They could be None, but that would be caught by this check

source_location = {
"file": record.pathname,
"line": str(record.lineno),
"function": record.funcName,
}
else:
source_location = None
# send off request
self.transport.send(
record,
message,
resource=resource,
resource=getattr(record, "resource", self.resource),
labels=(total_labels if total_labels else None),
trace=trace_id,
span_id=span_id,
http_request=http_request,
trace=(record.trace if record.trace else None),
span_id=getattr(record, "span_id", None),
http_request=(record.http_request if record.http_request else None),
source_location=source_location,
)


Expand Down
16 changes: 14 additions & 2 deletions tests/unit/handlers/test_handlers.py
Expand Up @@ -257,11 +257,11 @@ def test_emit(self):
logname = "loggername"
message = "hello world"
record = logging.LogRecord(logname, logging, None, None, message, None, None)
handler.filter(record)
handler.emit(record)

self.assertEqual(
handler.transport.send_called_with,
(record, message, _GLOBAL_RESOURCE, None, None, None, None),
(record, message, _GLOBAL_RESOURCE, None, None, None, None, None),
)

def test_emit_manual_field_override(self):
Expand All @@ -286,6 +286,15 @@ def test_emit_manual_field_override(self):
setattr(record, "resource", expected_resource)
expected_labels = {"test-label": "manual"}
setattr(record, "labels", expected_labels)
expected_source = {
"file": "test-file",
"line": str(1),
"function": "test-func",
}
setattr(record, "lineno", int(expected_source["line"]))
setattr(record, "funcName", expected_source["function"])
setattr(record, "pathname", expected_source["file"])
handler.filter(record)
handler.emit(record)

self.assertEqual(
Expand All @@ -298,6 +307,7 @@ def test_emit_manual_field_override(self):
expected_trace,
expected_span,
expected_http,
expected_source,
),
)

Expand Down Expand Up @@ -413,6 +423,7 @@ def send(
trace=None,
span_id=None,
http_request=None,
source_location=None,
):
self.send_called_with = (
record,
Expand All @@ -422,4 +433,5 @@ def send(
trace,
span_id,
http_request,
source_location,
)