Skip to content

Commit

Permalink
Logging instr hook (#1117)
Browse files Browse the repository at this point in the history
  • Loading branch information
nata7che authored Jun 9, 2022
1 parent 0bd8e4c commit ad15f7b
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 2 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- cleanup type hints for textmap `Getter` and `Setter` classes
([1106](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1106))


### Added
- `opentelemetry-instrumentation-logging` add log hook support
([#1117](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1117))
- `opentelemetry-instrumentation-remoulade` Initial release
([#1082](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1082))

### Added
- Added `opentelemetry-instrumention-confluent-kafka`
([#1111](https://github.com/open-telemetry/opentelemetry-python-contrib/pull/1111))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class LoggingInstrumentor(BaseInstrumentor): # pylint: disable=empty-docstring
{DEFAULT_LOGGING_FORMAT}
def log_hook(span: Span, record: LogRecord):
if span and span.is_recording():
record.custom_user_attribute_from_log_hook = "some-value"
Args:
tracer_provider: Tracer provider instance that can be used to fetch a tracer.
set_logging_format: When set to True, it calls logging.basicConfig() and sets a logging format.
Expand All @@ -66,11 +70,13 @@ class LoggingInstrumentor(BaseInstrumentor): # pylint: disable=empty-docstring
logging.WARN
logging.ERROR
logging.FATAL
log_hook: execute custom logic when record is created
See `BaseInstrumentor`
"""

_old_factory = None
_log_hook = None

def instrumentation_dependencies(self) -> Collection[str]:
return _instruments
Expand All @@ -80,6 +86,7 @@ def _instrument(self, **kwargs):
provider = kwargs.get("tracer_provider", None) or get_tracer_provider()
old_factory = logging.getLogRecordFactory()
LoggingInstrumentor._old_factory = old_factory
LoggingInstrumentor._log_hook = kwargs.get("log_hook", None)

service_name = None

Expand Down Expand Up @@ -107,6 +114,14 @@ def record_factory(*args, **kwargs):
if ctx != INVALID_SPAN_CONTEXT:
record.otelSpanID = format(ctx.span_id, "016x")
record.otelTraceID = format(ctx.trace_id, "032x")
if callable(LoggingInstrumentor._log_hook):
try:
LoggingInstrumentor._log_hook( # pylint: disable=E1102
span, record
)
except Exception: # pylint: disable=W0703
pass

return record

logging.setLogRecordFactory(record_factory)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ def test_trace_context_injection(self):
self.assertEqual(record.otelServiceName, "")


def log_hook(span, record):
record.custom_user_attribute_from_log_hook = "some-value"


class TestLoggingInstrumentor(TestBase):
@pytest.fixture(autouse=True)
def inject_fixtures(self, caplog):
Expand Down Expand Up @@ -150,6 +154,27 @@ def test_custom_format_and_level_api(
format="%(message)s span_id=%(otelSpanID)s", level=logging.WARNING
)

def test_log_hook(self):
LoggingInstrumentor().uninstrument()
LoggingInstrumentor().instrument(
set_logging_format=True,
log_hook=log_hook,
)
with self.tracer.start_as_current_span("s1") as span:
span_id = format(span.get_span_context().span_id, "016x")
trace_id = format(span.get_span_context().trace_id, "032x")
with self.caplog.at_level(level=logging.INFO):
logger = logging.getLogger("test logger")
logger.info("hello")
self.assertEqual(len(self.caplog.records), 1)
record = self.caplog.records[0]
self.assertEqual(record.otelSpanID, span_id)
self.assertEqual(record.otelTraceID, trace_id)
self.assertEqual(record.otelServiceName, "unknown_service")
self.assertEqual(
record.custom_user_attribute_from_log_hook, "some-value"
)

def test_uninstrumented(self):
with self.tracer.start_as_current_span("s1") as span:
span_id = format(span.get_span_context().span_id, "016x")
Expand Down

0 comments on commit ad15f7b

Please sign in to comment.