-
Notifications
You must be signed in to change notification settings - Fork 656
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
Record logger name as the instrumentation scope name #3810
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,7 @@ | |
import logging | ||
import threading | ||
import traceback | ||
from functools import lru_cache | ||
from os import environ | ||
from time import time_ns | ||
from typing import Any, Callable, Optional, Tuple, Union # noqa | ||
|
@@ -452,9 +453,6 @@ def __init__( | |
) -> None: | ||
super().__init__(level=level) | ||
self._logger_provider = logger_provider or get_logger_provider() | ||
self._logger = get_logger( | ||
__name__, logger_provider=self._logger_provider | ||
) | ||
|
||
@staticmethod | ||
def _get_attributes(record: logging.LogRecord) -> Attributes: | ||
|
@@ -534,6 +532,7 @@ def _translate(self, record: logging.LogRecord) -> LogRecord: | |
"WARN" if record.levelname == "WARNING" else record.levelname | ||
) | ||
|
||
logger = get_logger(record.name, logger_provider=self._logger_provider) | ||
return LogRecord( | ||
timestamp=timestamp, | ||
observed_timestamp=observered_timestamp, | ||
|
@@ -543,7 +542,7 @@ def _translate(self, record: logging.LogRecord) -> LogRecord: | |
severity_text=level_name, | ||
severity_number=severity_number, | ||
body=body, | ||
resource=self._logger.resource, | ||
resource=logger.resource, | ||
attributes=attributes, | ||
) | ||
|
||
|
@@ -553,15 +552,15 @@ def emit(self, record: logging.LogRecord) -> None: | |
|
||
The record is translated to OTel format, and then sent across the pipeline. | ||
""" | ||
if not isinstance(self._logger, NoOpLogger): | ||
self._logger.emit(self._translate(record)) | ||
logger = get_logger(record.name, logger_provider=self._logger_provider) | ||
if not isinstance(logger, NoOpLogger): | ||
logger.emit(self._translate(record)) | ||
|
||
def flush(self) -> None: | ||
""" | ||
Flushes the logging output. Skip flushing if logger is NoOp. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we update this comment? |
||
""" | ||
if not isinstance(self._logger, NoOpLogger): | ||
self._logger_provider.force_flush() | ||
self._logger_provider.force_flush() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why remove the if statement here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is no longer a single There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Got it. It doesn't seem like there would be an issue with flushing a no op either so I think this works fine. Resolved. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there an issue here with typing, because the |
||
|
||
|
||
class Logger(APILogger): | ||
|
@@ -622,6 +621,7 @@ def __init__( | |
def resource(self): | ||
return self._resource | ||
|
||
@lru_cache(maxsize=None) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is the point of this only to speed up the multiple calls to get logger? Or is there a functionality benefit. Given that the logs will be coming from multiple loggers, I am not sure this cache is necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, this is only to speed up the multiple calls to get_logger. We can be more explicit in keeping track of one logger instance per logger name encountered. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "@lru_cache may not be the right approach here if we want to be able to retrieve all logger instances after they've been placed in the cache" Please add cache tests and the pytest benchmarking you mentioned. Otherwise, looks great to me! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since we are not defining maxsize this is the same as just |
||
def get_logger( | ||
self, | ||
name: str, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like a very significant change. But I am also confused about why the logging handler was storing a logger for it's own source namespace and not even the namespace of the logger it's added to. Can anyone explain the purpose of this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be more clear. This seems like a good change. I'm just surprised by how strange the existing code's functionality is. So, I wanted to make sure there was not a good reason for it to be that way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems a single logger instance stored in
_logger
was chosen based on perceived need for performance, based on the discussion in the original issue #2485Based on the discussion yesterday, I'm planning to use pytest-benchmark to test if there is a performance regression with creating one logger instance per logger name.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tm0nk
Are you planning on including these tests as part of this pr?