OpenTelemetry Logging Instrumentation¶
The OpenTelemetry logging
integration automatically injects tracing context into log statements.
The integration registers a custom log record factory with the the standard library logging module that automatically inject
tracing context into log record objects. Optionally, the integration can also call logging.basicConfig()
to set a logging
format with placeholders for span ID, trace ID and service name.
The following keys are injected into log record objects by the factory:
otelSpanID
otelTraceID
otelServiceName
otelTraceSampled
The integration uses the following logging format by default:
%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s trace_sampled=%(otelTraceSampled)s] - %(message)s
Enable trace context injection¶
The integration is opt-in and must be enabled explicitly by setting the environment variable OTEL_PYTHON_LOG_CORRELATION
to true
.
The integration always registers the custom factory that injects the tracing context into the log record objects. Setting
OTEL_PYTHON_LOG_CORRELATION
to true
calls logging.basicConfig()
to set a logging format that actually makes
use of the injected variables.
Environment variables¶
- OTEL_PYTHON_LOG_CORRELATION¶
This env var must be set to true
in order to enable trace context injection into logs by calling logging.basicConfig()
and
setting a logging format that makes use of the injected tracing variables.
Alternatively, set_logging_format
argument can be set to True
when initializing the LoggingInstrumentor
class to achieve the
same effect.
LoggingInstrumentor(set_logging_format=True)
The default value is false
.
- OTEL_PYTHON_LOG_FORMAT¶
This env var can be used to instruct the instrumentation to use a custom logging format.
Alternatively, a custom logging format can be passed to the LoggingInstrumentor
as the logging_format
argument. For example:
LoggingInstrumentor(logging_format='%(msg)s [span_id=%(span_id)s]')
The default value is:
%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s trace_sampled=%(otelTraceSampled)s] - %(message)s
- OTEL_PYTHON_LOG_LEVEL¶
This env var can be used to set a custom logging level.
Alternatively, log level can be passed to the LoggingInstrumentor
during initialization. For example:
LoggingInstrumentor(log_level=logging.DEBUG)
The default value is info
.
Options are:
info
error
debug
warning
Manually calling logging.basicConfig¶
logging.basicConfig()
can be called to set a global logging level and format. Only the first ever call has any effect on the global logger.
Any subsequent calls have no effect and do not override a previously configured global logger. This integration calls logging.basicConfig()
for you
when OTEL_PYTHON_LOG_CORRELATION
is set to true
. It uses the format and level specified by OTEL_PYTHON_LOG_FORMAT
and OTEL_PYTHON_LOG_LEVEL
environment variables respectively.
If you code or some other library/framework you are using calls logging.basicConfig before this integration is enabled, then this integration’s logging format will not be used and log statements will not contain tracing context. For this reason, you’ll need to make sure this integration is enabled as early as possible in the service lifecycle or your framework is configured to use a logging format with placeholders for tracing context. This can be achieved by adding the following placeholders to your logging format:
%(otelSpanID)s %(otelTraceID)s %(otelServiceName)s %(otelTraceSampled)s
API¶
from opentelemetry.instrumentation.logging import LoggingInstrumentor
LoggingInstrumentor().instrument(set_logging_format=True)
Note
If you do not set OTEL_PYTHON_LOG_CORRELATION
to true
but instead set the logging format manually or through your framework, you must ensure that this
integration is enabled before you set the logging format. This is important because unless the integration is enabled, the tracing context variables
are not injected into the log record objects. This means any attempted log statements made after setting the logging format and before enabling this integration
will result in KeyError exceptions. Such exceptions are automatically swallowed by the logging module and do not result in crashes but you may still lose out
on important log messages.
- class opentelemetry.instrumentation.logging.LoggingInstrumentor(*args, **kwargs)[source]¶
Bases:
opentelemetry.instrumentation.instrumentor.BaseInstrumentor
An instrumentor for stdlib logging module.
This instrumentor injects tracing context into logging records and optionally sets the global logging format to the following:
%(asctime)s %(levelname)s [%(name)s] [%(filename)s:%(lineno)d] [trace_id=%(otelTraceID)s span_id=%(otelSpanID)s resource.service.name=%(otelServiceName)s trace_sampled=%(otelTraceSampled)s] - %(message)s def log_hook(span: Span, record: LogRecord): if span and span.is_recording(): record.custom_user_attribute_from_log_hook = "some-value"
- Parameters
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.
logging_format – Accepts a string and sets it as the logging format when set_logging_format is set to True.
log_level – Accepts one of the following values and sets the logging level to it. logging.INFO logging.DEBUG logging.WARN logging.ERROR logging.FATAL
log_hook – execute custom logic when record is created
See
BaseInstrumentor
- instrumentation_dependencies()[source]¶
Return a list of python packages with versions that the will be instrumented.
The format should be the same as used in requirements.txt or pyproject.toml.
For example, if an instrumentation instruments requests 1.x, this method should look like:
- def instrumentation_dependencies(self) -> Collection[str]:
return [‘requests ~= 1.0’]
This will ensure that the instrumentation will only be used when the specified library is present in the environment.
- Return type