You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We use python logging filters to automatically add labels to all our log entries without having to provide them individually for each log entry (similar to #750, but we need it with specific values for each request instead of for the entire app).
Usually, you add your filters through handler.addFilter(), but this results in our filter being called too late, because the CloudLoggingFilter already parsed the labels from the log record when itself got run and later additions to record.labels are ignored.
Interestingly, it works correctly if we use json_fields instead of labels, because the json_fields are evaluated only once the emit happens at which point all the filters have already run.
It would be great if this could be changed so that labels (and other properties) are also only evaluated once the entry is about to be emitted so that all logging filters have run already. In the meantime, this can be worked around by explicitly inserting our log filter as first filter in the filters list of a handler, but this involves messing around with internals of the logging library, which we'd like to avoid.
Is there a reason why the fields are added with a log filter anyways and not during explicitly during emit?
Environment details
OS type and version: Ubuntu 24.04
Python version: 3.9.18
pip version: 23.0.1
google-cloud-logging version: 3.11.2
Code example
defadd_request_id_filter(record):
ifnothasattr(record, "labels"):
record.labels= {}
record.labels["request_id"] =g.request_idreturnTrue# Does not work.root_logger=logging.getLogger()
forhandlerinroot_logger.handlers:
handler.addFilter(add_request_id_filter)
# This works insteadroot_logger=logging.getLogger()
forhandlerinroot_logger.handlers:
handler.filters.insert(0, add_request_id_filter)
The text was updated successfully, but these errors were encountered:
We use record._labels instead of record.labels because there are different labels managed at different parts of the lifecycle, and we need to distinguish them. Our logging handlers work off of record._labels and things added to the logging record by CloudLoggingFilter.
As for your question regarding why fields are added in the filter stage rather than the emit stage, we have different handlers that have different emit logic, and adding the fields through a Filter class makes the fields accessible for both handlers in a way that can be accessed by other handlers/filters if needed.
In addition to the workaround you have found, you can also try adding to record._labels and seeing if that also works for you.
Thanks for the suggestion! From a quick glance at the CloudLoggingHandler code it seems like this would indeed work. Would it be possible to add this as official documentation or maybe even expose some kind of API for it to make it clear that it is allowed to add stuff to the internal record._labels? We try to avoid messing with internals of other APIs, because they might break at any point and this might even go unnoticed.
We use python logging filters to automatically add labels to all our log entries without having to provide them individually for each log entry (similar to #750, but we need it with specific values for each request instead of for the entire app).
Usually, you add your filters through
handler.addFilter()
, but this results in our filter being called too late, because the CloudLoggingFilter already parsed the labels from the log record when itself got run and later additions torecord.labels
are ignored.Interestingly, it works correctly if we use
json_fields
instead of labels, because thejson_fields
are evaluated only once theemit
happens at which point all the filters have already run.It would be great if this could be changed so that labels (and other properties) are also only evaluated once the entry is about to be emitted so that all logging filters have run already. In the meantime, this can be worked around by explicitly inserting our log filter as first filter in the
filters
list of a handler, but this involves messing around with internals of the logging library, which we'd like to avoid.Is there a reason why the fields are added with a log filter anyways and not during explicitly during emit?
Environment details
google-cloud-logging
version: 3.11.2Code example
The text was updated successfully, but these errors were encountered: