@@ -606,25 +606,55 @@ def __init__(
606606 self ._default_request = request
607607
608608 def filter (self , record : logging .LogRecord ) -> Literal [True ]:
609- """Add each fields from the logging contexts to the record.
609+ """
610+ Add each fields from the logging contexts to the record.
611+
612+ Please be mindful of 3rd-party code outside of Synapse as this is running as a
613+ global log record filter. Other code may have set their own attributes on the
614+ record and the log record may not be relevant to Synapse at all so we should not
615+ mangle it.
616+
617+ We can have some defaults but we should avoid overwriting existing attributes on
618+ any log record unless we actually have a Synapse logcontext (not just the
619+ default sentinel logcontext).
620+
610621 Returns:
611622 True to include the record in the log output.
612623 """
613624 context = current_context ()
614625 record .request = self ._default_request
615- record .server_name = "unknown_server_from_no_context"
626+
627+ # Avoid overwriting an existing `server_name` on the record. This is running in
628+ # the context of a global log record filter so there may be 3rd-party code that
629+ # adds their own `server_name` and we don't want to interfere with that.
630+ if not hasattr (record , "server_name" ):
631+ record .server_name = "unknown_server_from_no_logcontext"
616632
617633 # context should never be None, but if it somehow ends up being, then
618634 # we end up in a death spiral of infinite loops, so let's check, for
619635 # robustness' sake.
620636 if context is not None :
621- record .server_name = context .server_name
637+
638+ def safe_set (attr : str , value : Any ) -> None :
639+ """
640+ Only write the attribute if it hasn't already been set or we actually have
641+ a Synapse logcontext (indicating that this log record is relevant to
642+ Synapse).
643+ """
644+ if context is not SENTINEL_CONTEXT or not hasattr (record , attr ):
645+ setattr (record , attr , value )
646+
647+ safe_set ("server_name" , context .server_name )
648+
622649 # Logging is interested in the request ID. Note that for backwards
623650 # compatibility this is stored as the "request" on the record.
624- record . request = str (context )
651+ safe_set ( " request" , str (context ) )
625652
626653 # Add some data from the HTTP request.
627654 request = context .request
655+ # The sentinel logcontext has no request so if we get past this point, we
656+ # know we have some actual Synapse logcontext and don't need to worry about
657+ # using `safe_set`.
628658 if request is None :
629659 return True
630660
0 commit comments