product-updateotlpopentelemetry

Introducing OTLP Support: OpenTelemetry Native Log Ingestion

Purl now natively supports OpenTelemetry Protocol (OTLP) for log ingestion. Send logs from any OTLP-compatible source without format conversion.

Otabek IsmoilovJanuary 15, 20265 min read

What is OTLP?

OpenTelemetry Protocol (OTLP) is the standard wire protocol for the OpenTelemetry project. It defines how telemetry data (traces, metrics, and logs) is encoded and transmitted between services.

In 2026, OTLP is the de facto standard for observability data. Every major language has an OpenTelemetry SDK, and most cloud-native tools support OTLP natively.

Why We Added OTLP Support

  • Sending JSON to our REST API (/api/v1/logs)
  • Using a log forwarder like Fluent Bit with HTTP output

This worked well, but it meant teams using OpenTelemetry had to add a separate pipeline for logs. Now, your existing OTel Collector can send logs directly to Purl.

How It Works

Purl's OTLP endpoint accepts the standard OTLP/HTTP JSON format:

POST /api/v1/otlp/logs Content-Type: application/json X-API-Key: your-api-key ```
POST /api/v1/otlp/logs
Content-Type: application/json
X-API-Key: your-api-key
  • Resource attributes (service.name, host.name, etc.)
  • Log record fields (timestamp, severity, body, attributes)
  • Scope information (instrumentation library)

Configuring OpenTelemetry Collector

Add Purl as an OTLP exporter in your OTel Collector config:

yaml exporters: otlphttp/purl: endpoint: http://your-purl:3000/api/v1/otlp headers: X-API-Key: your-api-key
service:
  pipelines:
    logs:
      receivers: [otlp, filelog]
      processors: [batch, resource]
      exporters: [otlphttp/purl]

That's it. No format conversion, no custom plugins, no middleware.

Using OpenTelemetry SDKs Directly

You can also send logs directly from your application using any OpenTelemetry SDK:

python # Python example from opentelemetry.sdk._logs import LoggerProvider from opentelemetry.sdk._logs.export import BatchLogRecordProcessor from opentelemetry.exporter.otlp.proto.http._log_exporter import OTLPLogExporter
exporter = OTLPLogExporter(
    endpoint="http://your-purl:3000/api/v1/otlp/logs",
    headers={"X-API-Key": "your-api-key"},
)

logger_provider = LoggerProvider()
logger_provider.add_log_record_processor(BatchLogRecordProcessor(exporter))

Resource Attribute Mapping

Purl automatically maps OTLP resource attributes to log fields:

  • service.namesource
  • host.namehost
  • severity_textlevel
  • bodymessage
  • All other attributes → metadata (stored as ClickHouse Map)

What's Next

OTLP support is just the beginning of our OpenTelemetry journey. Coming soon:

  • OTLP/gRPC support for lower overhead
  • Trace-log correlation — click from a trace span to its associated logs
  • OpenTelemetry Collector distribution — a pre-configured collector optimized for Purl

Try it today — update to the latest Purl image and start sending OTLP logs.