| Status | |
|---|---|
| Stability | alpha: logs, metrics, traces |
| Distributions | contrib |
| Issues |
The LGTM exporter is an OpenTelemetry Collector component that sends logs, metrics, and traces to Grafana's LGTM stack (Loki, Grafana, Tempo, Mimir). This exporter is designed to work with the native OTLP endpoints provided by each component of the LGTM stack while handling multi-tenancy through flexible tenant configuration.
Key features:
- OpenTelemetry Collector exporter for logs, metrics, and traces
- Native integration with Loki, Mimir, and Tempo OTLP endpoints
- Multi-tenancy support with flexible tenant ID extraction from resource attributes
- Separate HTTP client configuration for each signal type
- Support for authentication extensions (Basic Auth, Bearer Token, OAuth2, etc.)
- Built-in retry and queue configurations
- Telemetry metrics for monitoring exporter performance
The following settings are required:
- At least one of
logs,metrics, ortracesmust be configured with anendpoint
The following settings are optional:
Configure endpoints for the signals you want to export. Each signal (logs, metrics, traces) can be configured independently with its own HTTP client settings.
logs.endpoint(no default): The Loki OTLP endpoint URL (e.g.,http://loki:3100/otlp/v1/logs)- Supports all HTTP Client Configuration options below (prefixed with
logs.)
metrics.endpoint(no default): The Mimir OTLP endpoint URL (e.g.,http://mimir:8080/otlp/v1/metrics)- Supports all HTTP Client Configuration options below (prefixed with
metrics.)
traces.endpoint(no default): The Tempo endpoint URL (e.g.,http://tempo:3201/v1/traces)- Supports all HTTP Client Configuration options below (prefixed with
traces.)
Each signal type (logs, metrics, traces) supports the following HTTP client configuration options. Simply prefix the option with the signal name (e.g., logs.timeout, metrics.compression, traces.tls):
endpoint(no default): The target URL to send data totimeout(default = 0s/unlimited): HTTP request timeoutheaders(no default): Additional HTTP headers to send with requeststls(no default): TLS configuration settings (see configtls)proxy_url(no default): Proxy URL to use for HTTP requestsauth(no default): Authentication extension configuration. Supports all standard OpenTelemetry authentication extensions including Basic Auth, Bearer Token, OAuth2, and more. Each signal can use a different authenticator. (see configauth)compression(default = gzip): Compression type (gzip, snappy, zstd, zlib, deflate, or none)compression_params(no default): Advanced compression configurationread_buffer_size(default = 0): HTTP client read buffer sizewrite_buffer_size(default = 0): HTTP client write buffer sizemax_idle_conns(default = 100): Maximum idle HTTP connections (0 = no limit)max_idle_conns_per_host(default = system default): Maximum idle HTTP connections per hostmax_conns_per_host(default = 0/unlimited): Maximum total connections per hostidle_conn_timeout(default = 90s): Maximum time a connection remains open before closingdisable_keep_alives(default = false): Disable HTTP keep-aliveshttp2_read_idle_timeout(default = 0s): HTTP/2 health check ping intervalhttp2_ping_timeout(default = 15s): HTTP/2 ping response timeoutforce_attempt_http2(default = true): Force HTTP/2 protocol usage
For the complete list of HTTP client configuration options, see confighttp.
The exporter supports OpenTelemetry Collector authentication extensions through the auth configuration option. Each signal (logs, metrics, traces) can be configured with its own authenticator, allowing you to use different authentication methods for different backends.
To use authentication:
- Configure one or more authentication extensions in the
extensionssection - Reference the extension ID in the signal's
auth.authenticatorfield - Add the extension to the service's
extensionslist
Supported authentication extensions include:
- Basic Auth (basicauthextension): Username/password authentication
- Bearer Token (bearertokenauthextension): Token-based authentication
- OAuth2 (oauth2clientauthextension): OAuth 2.0 client credentials flow
- OIDC (oidcauthextension): OpenID Connect authentication
- Sigv4 (sigv4authextension): AWS Signature Version 4 authentication
Example configuration with different authenticators per signal:
extensions:
basicauth/loki:
client_auth:
username: loki-user
password: loki-pass
bearertokenauth/mimir:
token: mimir-token-here
exporters:
lgtm:
logs:
endpoint: https://loki.example.com/otlp/v1/logs
auth:
authenticator: basicauth/loki
metrics:
endpoint: https://mimir.example.com/otlp/v1/metrics
auth:
authenticator: bearertokenauth/mimir
traces:
endpoint: https://tempo.example.com/v1/traces
# No auth configured for traces
service:
extensions: [basicauth/loki, bearertokenauth/mimir]
pipelines:
logs:
exporters: [lgtm]For more details on authentication, see configauth.
The exporter supports configuring the content type for the request body sent to LGTM backends:
content_type(default =protobuf): The format used to encode telemetry data in the request bodyprotobuf: Sends data in Protocol Buffers binary format withContent-Type: application/x-protobufheader (recommended)json: Sends data in JSON format withContent-Type: application/jsonheader
Protocol Buffers (protobuf) is the recommended format as it is more efficient in terms of size and serialization performance. JSON format may be useful for debugging or compatibility with specific backend configurations.
The exporter supports multi-tenancy by extracting tenant IDs from resource attributes and setting them in HTTP headers:
tenant.label(default =tenant.id): Primary resource attribute name to look for tenant IDtenant.labels(default =[]): Additional resource attribute names to search for tenant ID (fallback order)tenant.format(default =%s): Format string for the tenant ID value (uses Go fmt syntax)tenant.header(default =X-Scope-OrgID): HTTP header name to set with the tenant IDtenant.default(default =default): Default tenant ID when no tenant attribute is found
The exporter searches for tenant IDs in the following order:
tenant.labelattribute- Each attribute in
tenant.labels(in order) - Falls back to
tenant.defaultif none found
The exporter supports standard OpenTelemetry Collector queue and retry settings:
-
sending_queue:enabled(default = true): Enable the sending queuenum_consumers(default = 10): Number of consumers that dequeue batchesqueue_size(default = 1000): Maximum number of batches kept in memory before dropping data
-
retry_on_failure:enabled(default = true): Enable retry on failureinitial_interval(default = 5s): Time to wait after the first failure before retryingmax_interval(default = 30s): Upper bound on backoff intervalmax_elapsed_time(default = 300s): Maximum amount of time spent trying to send a batch
For more details, see exporterhelper configuration.
This example shows a basic HTTP configuration:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
lgtm:
logs:
endpoint: http://loki:3100/otlp/v1/logs
timeout: 30s
tls:
insecure: true
metrics:
endpoint: http://mimir:8080/otlp/v1/metrics
timeout: 30s
tls:
insecure: true
traces:
endpoint: http://tempo:3200/v1/traces
timeout: 30s
tls:
insecure: true
tenant:
label: tenant.id
labels:
- tenant_id
- tenantID
- tenantId
header: X-Scope-OrgID
format: "%s-dev"
default: default
content_type: protobuf
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
sending_queue:
enabled: true
num_consumers: 10
queue_size: 1000
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]
traces:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]This example shows HTTPS configuration with TLS certificates, custom headers, and different authentication methods for each signal:
extensions:
# Basic auth for Loki
basicauth/loki:
client_auth:
username: ${LOKI_USERNAME}
password: ${LOKI_PASSWORD}
# Bearer token for Mimir
bearertokenauth/mimir:
token: ${MIMIR_TOKEN}
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
lgtm:
logs:
endpoint: https://loki.example.com/otlp/v1/logs
timeout: 30s
auth:
authenticator: basicauth/loki
headers:
- name: X-Custom-Header
value: custom-value
tls:
insecure: false
cert_file: /etc/certs/client-cert.pem
key_file: /etc/certs/client-key.pem
ca_file: /etc/certs/ca.pem
compression: gzip
metrics:
endpoint: https://mimir.example.com/otlp/v1/metrics
timeout: 30s
auth:
authenticator: bearertokenauth/mimir
headers:
- name: X-Custom-Header
value: custom-value
- name: X-Environment
value: production
tls:
insecure: false
cert_file: /etc/certs/client-cert.pem
key_file: /etc/certs/client-key.pem
ca_file: /etc/certs/ca.pem
compression: gzip
traces:
endpoint: https://tempo.example.com/v1/traces
timeout: 30s
headers:
- name: X-Custom-Header
value: custom-value
- name: X-Trace-Source
value: collector
tls:
insecure: false
cert_file: /etc/certs/client-cert.pem
key_file: /etc/certs/client-key.pem
ca_file: /etc/certs/ca.pem
compression: gzip
tenant:
label: tenant.id
labels:
- tenant_id
- k8s.namespace.name
format: "%s"
header: X-Scope-OrgID
default: anonymous
content_type: protobuf
retry_on_failure:
enabled: true
initial_interval: 5s
max_interval: 30s
max_elapsed_time: 300s
sending_queue:
enabled: true
num_consumers: 10
queue_size: 1000
service:
extensions: [basicauth/loki, bearertokenauth/mimir]
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]
traces:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]This example shows how to configure the exporter to send data in JSON format instead of the default Protocol Buffers format:
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
processors:
batch:
exporters:
lgtm:
content_type: json # Send data as JSON instead of protobuf
logs:
endpoint: http://loki:3100/otlp/v1/logs
metrics:
endpoint: http://mimir:8080/otlp/v1/metrics
traces:
endpoint: http://tempo:3200/v1/traces
tenant:
label: tenant.id
default: default
service:
pipelines:
logs:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]
metrics:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]
traces:
receivers: [otlp]
processors: [batch]
exporters: [lgtm]Note: Protocol Buffers (protobuf) is recommended for production use as it provides better performance and smaller payload sizes. JSON format is primarily useful for debugging or specific backend requirements.
The exporter emits the following metrics to monitor its performance:
otelcol_exporter_lgtm_sent_samples_total: Number of samples sent to LGTM (split by signal type, tenant, and HTTP status code)otelcol_exporter_lgtm_sent_requests_total: Number of requests sent to LGTM (split by signal type, tenant, and HTTP status code)otelcol_exporter_lgtm_write_latency_milliseconds: Latency of write requests to LGTM in milliseconds (split by HTTP status code and URL)
The exporter includes a comprehensive test suite with equal coverage across all signal types (logs, metrics, traces):
- Unit Tests: Complete test coverage for processor operations including partitioning, sending, and dispatching telemetry data
- Integration Tests: Docker Compose-based integration test environment in the
test/directory
The test/ directory contains a complete Docker Compose stack for testing the exporter:
docker-compose.yml: Orchestrates the full LGTM stack with the OpenTelemetry Collectorgrafana/: Grafana configuration with pre-configured datasources for Loki, Mimir, and Tempoloki/: Loki configuration for receiving OTLP logsmimir/: Mimir configuration for receiving OTLP metricstempo/: Tempo configuration for receiving OTLP tracesotel-collector/: OpenTelemetry Collector configuration using the LGTM exportertest-client/: Test scripts for sending sample telemetry datasend-logs.sh: Send sample logs via OTLPsend-metrics.sh: Send sample metrics via OTLPsend-traces.sh: Send sample traces via OTLPsend-telemetry.sh: Send all signal types (runs automatically in docker-compose)
The test/ directory contains a complete integration test environment using Docker Compose with the full LGTM stack:
The docker-compose setup includes:
- Loki: Log aggregation system
- Mimir: Metrics storage
- Tempo: Distributed tracing backend
- Grafana: Visualization and dashboards
- OpenTelemetry Collector: Configured with the LGTM exporter
- test-client: Automated telemetry generator
cd test
docker compose upThe test-client service automatically generates and sends sample logs, metrics, and traces to the OTEL Collector, which then exports them to the appropriate LGTM stack components. No manual data sending is required - the test-client runs the send-telemetry.sh script automatically on startup.
Access Grafana at http://localhost:3000 (admin/admin) to visualize the exported data:
- Logs: Query Loki datasource for tenant labels
- Metrics: Browse Mimir metrics
- Traces: Search Tempo traces
The test-client generates telemetry for multiple tenants (tenant-a, tenant-b) and services (web-app, api-service, database, cache, auth-service), demonstrating multi-tenancy support. Plus randomly removes the tenant label to generate data for the default tenant.
This exporter is compatible with:
- Grafana Loki v2.9+ (OTLP endpoint)
- Grafana Mimir v2.10+ (OTLP endpoint)
- Grafana Tempo v2.2+
- Any other system compatible with the LGTM stack's OTLP endpoints