Skip to main content
In this lesson you’ll convert simple print statements in a small flight-booking demo into structured OpenTelemetry logs. We’ll configure a LoggerProvider, attach a Console exporter and a Batch processor, then emit LogRecord entries instead of using print(). This guide contains:
  • The original minimal application with print() statements
  • Installation instructions
  • A consolidated runnable example using OpenTelemetry logging
  • Notes on processors, severity values, and example output
  • Links and resources to extend this setup

Initial application (before OpenTelemetry)

This is the minimal starting point that uses print() for diagnostic output:
Goal: replace these print() calls with OpenTelemetry LogRecord emissions for richer, structured logging.

Installation

Install the OpenTelemetry API and SDK packages for Python:
You can also add exporters (OTLP) later if you want to send logs to a collector.

OpenTelemetry logging — components overview

Below are the main components you’ll configure when using OpenTelemetry logging:

Important note about module paths

Some OpenTelemetry logging modules live under names that begin with an underscore (for example, opentelemetry.sdk._logs). This signals an experimental or not-yet-stable API surface. If you see import errors after upgrading packages, check the library release notes or the OpenTelemetry Python releases for updated module paths.

Consolidated runnable example

The example below replaces the print() calls with LogRecord emissions and configures a Console exporter and a BatchLogRecordProcessor. Save as main.py and run python main.py to see JSON-like LogRecord entries printed to the terminal.
Run the script:

Notes on BatchLogRecordProcessor

  • The BatchLogRecordProcessor buffers LogRecord objects and sends them to the exporter in batches on a schedule or when the queue fills. This improves throughput by avoiding the overhead of exporting each record synchronously.
  • For quick debugging or demos you can swap in a SimpleLogRecordProcessor which sends each record immediately; however, BatchLogRecordProcessor is preferred for production-like workloads.

Severity text and numbers

OpenTelemetry provides a SeverityNumber enum (for example SeverityNumber.INFO) which is more readable and maintainable than hard-coding numeric severity values. Use severity_text for a human-readable level and severity_number for the numeric enum.

Example output

Running the example above prints JSON-like LogRecord entries via the ConsoleLogExporter. Below is a formatted example of what one entry may look like:
You can programmatically populate additional fields such as attributes, resource attributes, or trace/span correlation fields to enrich your logs.

Summary & next steps

  • Replace print() statements with logger.emit(LogRecord(...)) to produce structured logs.
  • Configure and set a global LoggerProvider, attach an exporter (Console used here) and a processor (BatchLogRecordProcessor).
  • Use get_logger() to obtain a logger wired to your provider, and populate body, timestamp, severity_text, severity_number, and attributes for richer diagnostics.
  • Extend this minimal setup by exporting to an OTLP collector, adding service-specific resource attributes, or correlating logs with traces.

Watch Video