Skip to main content
In this lesson we compare two approaches to emitting logs with OpenTelemetry in Python:
  • Verbose: manually creating and emitting LogRecord objects via an OpenTelemetry logger.
  • Concise: using the Python standard library logging module and forwarding those records into OpenTelemetry.
We first show the verbose approach (explicit, but repetitive), then the standard-library approach (concise), and finally how to wire the stdlib logger into OpenTelemetry so your existing logging.info(...) calls produce OpenTelemetry log records automatically.

At-a-glance comparison

1) Verbose: emitting OpenTelemetry LogRecord directly

This approach constructs LogRecord objects and emits them through an OpenTelemetry Logger. It’s explicit, but repetitive: every log must include timestamp, severity, body, and other fields.
This is useful when you need precise control over the OpenTelemetry LogRecord payload, but it quickly becomes cumbersome for everyday application logging.

2) Simpler: Python standard library logging

The Python standard logging module is concise and widely used. By default it writes human-readable text to the console (or to files/handlers you configure), but those records are not OpenTelemetry LogRecords until you forward them.
Running the script produces the typical stdlib output:
This is concise and convenient for everyday development, but those messages are not structured OpenTelemetry logs unless forwarded.

3) Forward stdlib logging to OpenTelemetry

You can wire the Python stdlib logger into OpenTelemetry using a LoggingHandler provided by the OpenTelemetry SDK. The handler converts logging.LogRecord instances into OpenTelemetry LogRecords and forwards them to the configured LoggerProvider. With this in place, existing logging.info(...) calls generate structured OpenTelemetry logs automatically. Example: forward stdlib logs to OpenTelemetry and export to the console as JSON.
Notes:
  • If you still want the original stdlib text output on the console in addition to OpenTelemetry JSON output, attach a standard logging.StreamHandler() alongside the LoggingHandler.
  • The LoggingHandler will populate fields such as severity text/number, timestamps, and code attributes (file path, function name, line number) automatically.
Exporter output (ConsoleLogExporter) β€” formatted for readability:
Forwarding the Python stdlib logger to OpenTelemetry lets existing codebases emit structured OpenTelemetry logs with minimal changes β€” configure the handler once and continue using logging everywhere.
If you want a quick checklist for adopting stdlib-forwarding: This setup gives you the familiarity of the Python logging API with the structured, observable benefits of OpenTelemetry logging.

Watch Video