Adapters
OTLP
Send logs via OpenTelemetry Protocol to Grafana, Datadog, Honeycomb, and any OTLP-compatible backend.
The OTLP (OpenTelemetry Protocol) adapter sends logs in the standard OpenTelemetry format. This works with any OTLP-compatible backend including:
- Grafana Cloud (Loki)
- Datadog
- Honeycomb
- Jaeger
- Splunk
- New Relic
- Self-hosted OpenTelemetry Collector
Installation
The OTLP adapter is included in the main evlog package:
import { createOTLPDrain } from 'evlog/otlp'
Quick Start
1. Set your OTLP endpoint
.env
NUXT_OTLP_ENDPOINT=http://localhost:4318
2. Create the drain plugin
server/plugins/evlog-drain.ts
import { createOTLPDrain } from 'evlog/otlp'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:drain', createOTLPDrain())
})
Configuration
The adapter reads configuration from multiple sources (highest priority first):
- Overrides passed to
createOTLPDrain() - Runtime config at
runtimeConfig.evlog.otlp - Runtime config at
runtimeConfig.otlp - Environment variables (
NUXT_OTLP_*orOTEL_*)
Environment Variables
| Variable | Description |
|---|---|
NUXT_OTLP_ENDPOINT | OTLP HTTP endpoint (e.g., http://localhost:4318) |
NUXT_OTLP_SERVICE_NAME | Override service name |
NUXT_OTLP_HEADERS | Custom headers (format: Key=Value,Key2=Value2) |
NUXT_OTLP_AUTH | Shortcut for Authorization header |
Standard OpenTelemetry variables are also supported:
| Variable | Description |
|---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | OTLP endpoint (fallback) |
OTEL_EXPORTER_OTLP_HEADERS | Headers in OTEL format |
OTEL_SERVICE_NAME | Service name (fallback) |
Runtime Config
nuxt.config.ts
export default defineNuxtConfig({
runtimeConfig: {
otlp: {
endpoint: '', // Set via NUXT_OTLP_ENDPOINT
},
},
})
Override Options
server/plugins/evlog-drain.ts
import { createOTLPDrain } from 'evlog/otlp'
export default defineNitroPlugin((nitroApp) => {
nitroApp.hooks.hook('evlog:drain', createOTLPDrain({
endpoint: 'http://localhost:4318',
serviceName: 'my-api',
headers: {
'Authorization': 'Bearer xxx',
},
resourceAttributes: {
'deployment.environment': 'staging',
},
}))
})
Full Configuration Reference
| Option | Type | Default | Description |
|---|---|---|---|
endpoint | string | - | OTLP HTTP endpoint (required) |
serviceName | string | From event | Override service.name resource attribute |
headers | object | - | Custom HTTP headers for authentication |
resourceAttributes | object | - | Additional OTLP resource attributes |
timeout | number | 5000 | Request timeout in milliseconds |
Provider-Specific Setup
Grafana Cloud
- Go to your Grafana Cloud portal
- Navigate to Connections > Collector > OpenTelemetry
- Copy your OTLP endpoint and generate credentials
.env
NUXT_OTLP_ENDPOINT=https://otlp-gateway-prod-us-central-0.grafana.net/otlp
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Basic%20base64-encoded-credentials
Grafana uses URL-encoded headers. The
%20 is a space character. The adapter automatically decodes this format.Datadog
.env
NUXT_OTLP_ENDPOINT=https://http-intake.logs.datadoghq.com
NUXT_OTLP_HEADERS=DD-API-KEY=your-api-key
Local OpenTelemetry Collector
For development and testing, run a local collector:
otel-collector.yaml
receivers:
otlp:
protocols:
http:
endpoint: 0.0.0.0:4318
exporters:
debug:
verbosity: detailed
service:
pipelines:
logs:
receivers: [otlp]
exporters: [debug]
docker run --rm -p 4318:4318 \
-v $(pwd)/otel-collector.yaml:/etc/otelcol/config.yaml \
otel/opentelemetry-collector:latest
.env
NUXT_OTLP_ENDPOINT=http://localhost:4318
OTLP Log Format
evlog maps wide events to the OTLP log format:
| evlog Field | OTLP Field |
|---|---|
level | severityNumber / severityText |
timestamp | timeUnixNano |
service | Resource attribute service.name |
environment | Resource attribute deployment.environment |
version | Resource attribute service.version |
region | Resource attribute cloud.region |
traceId | traceId |
spanId | spanId |
| All other fields | Log attributes |
Severity Mapping
| evlog Level | OTLP Severity Number | OTLP Severity Text |
|---|---|---|
debug | 5 | DEBUG |
info | 9 | INFO |
warn | 13 | WARN |
error | 17 | ERROR |
Troubleshooting
Missing endpoint error
[evlog/otlp] Missing endpoint. Set NUXT_OTLP_ENDPOINT or OTEL_EXPORTER_OTLP_ENDPOINT
Make sure your endpoint environment variable is set and the server was restarted.
401 Unauthorized
Your authentication headers may be missing or incorrect. Check:
- The
OTEL_EXPORTER_OTLP_HEADERSformat is correct - Credentials are valid and not expired
- The endpoint URL is correct
404 Not Found
The adapter sends to /v1/logs. Make sure your endpoint:
- Supports OTLP HTTP (not gRPC)
- Is the base URL without
/v1/logssuffix
Logs not appearing
- Check the server console for
[evlog/otlp]error messages - Test with a local collector first to verify the format
- Check your backend's ingestion delay (some have 1-2 minute delays)
Direct API Usage
For advanced use cases:
import { sendToOTLP, sendBatchToOTLP, toOTLPLogRecord } from 'evlog/otlp'
// Send a single event
await sendToOTLP(event, {
endpoint: 'http://localhost:4318',
})
// Send multiple events
await sendBatchToOTLP(events, {
endpoint: 'http://localhost:4318',
})
// Convert event to OTLP format (for inspection)
const otlpRecord = toOTLPLogRecord(event)