17
17
from google .cloud import logging as google_logging
18
18
19
19
20
- def setup_gcp_logging (service_name ):
21
- """Set up GCP logging and error reporting."""
20
+ class _ErrorReportingFilter :
21
+ """
22
+ A logging filter that adds necessary JSON fields to error logs so that they
23
+ can be picked up by Error Reporting.
24
+
25
+ https://cloud.google.com/error-reporting/docs/formatting-error-messages#log-text
26
+ https://docs.python.org/3/howto/logging-cookbook.html#using-filters-to-impart-contextual-information
27
+ """
22
28
23
- logging_client = google_logging . Client ()
24
- logging_client . setup_logging ()
29
+ def __init__ ( self , service_name : str ) -> None :
30
+ self . service_name = service_name
25
31
26
- old_factory = logging .getLogRecordFactory ()
27
-
28
- def record_factory (* args , ** kwargs ):
29
- """Insert jsonPayload fields to all logs."""
30
-
31
- record = old_factory (* args , ** kwargs )
32
+ def filter (self , record : logging .LogRecord ) -> bool :
33
+ """Add the error reporting fields to json_fields."""
32
34
if not hasattr (record , 'json_fields' ):
33
35
record .json_fields = {}
34
36
35
- # Add jsonPayload fields to logs that don't contain stack traces to enable
36
- # capturing and grouping by error reporting.
37
- # https://cloud.google.com/error-reporting/docs/formatting-error-messages#log-text
38
37
if record .levelno >= logging .ERROR and not record .exc_info :
39
38
record .json_fields .update ({
40
39
'@type' :
41
40
'type.googleapis.com/google.devtools.clouderrorreporting.v1beta1.ReportedErrorEvent' , # pylint: disable=line-too-long
42
41
'serviceContext' : {
43
- 'service' : service_name ,
42
+ 'service' : self . service_name ,
44
43
},
45
44
'context' : {
46
45
'reportLocation' : {
@@ -51,9 +50,16 @@ def record_factory(*args, **kwargs):
51
50
},
52
51
})
53
52
54
- return record
53
+ return True
54
+
55
+
56
+ def setup_gcp_logging (service_name ):
57
+ """Set up GCP logging and error reporting."""
58
+
59
+ logging_client = google_logging .Client ()
60
+ logging_client .setup_logging ()
55
61
56
- logging .setLogRecordFactory ( record_factory )
62
+ logging .getLogger (). addFilter ( _ErrorReportingFilter ( service_name ) )
57
63
logging .getLogger ().setLevel (logging .INFO )
58
64
59
65
# Suppress noisy logs in some of our dependencies.
0 commit comments