Skip to main content

OpenTelemetry (OTEL)

InfraSage is a native OpenTelemetry receiver. It accepts OTLP over HTTP for metrics, traces, and logs at 100,000+ messages per second.


Supported OTLP Endpoints

SignalEndpointFormat
MetricsPOST /v1/metricsOTLP JSON or protobuf
TracesPOST /v1/tracesOTLP JSON or protobuf
LogsPOST /v1/logsOTLP JSON or protobuf

All endpoints are served by the Ingestion Gateway on port 8080.


Option A — OTEL Collector

Configure the OpenTelemetry Collector to forward data to InfraSage:

# otel-collector-config.yaml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318

processors:
batch:
send_batch_size: 10000
timeout: 5s

exporters:
otlphttp:
endpoint: http://localhost:8080
headers:
Content-Type: application/x-protobuf

service:
pipelines:
metrics:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
traces:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]
logs:
receivers: [otlp]
processors: [batch]
exporters: [otlphttp]

Start the collector:

otelcol --config otel-collector-config.yaml

Option B — Direct SDK Integration

Go

import (
"go.opentelemetry.io/otel"
"go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp"
"go.opentelemetry.io/otel/sdk/metric"
)

func initMetrics(ctx context.Context) (*metric.MeterProvider, error) {
exporter, err := otlpmetrichttp.New(ctx,
otlpmetrichttp.WithEndpoint("localhost:8080"),
otlpmetrichttp.WithInsecure(),
)
if err != nil {
return nil, err
}
mp := metric.NewMeterProvider(metric.WithReader(
metric.NewPeriodicReader(exporter, metric.WithInterval(15*time.Second)),
))
otel.SetMeterProvider(mp)
return mp, nil
}

Python

from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader

exporter = OTLPMetricExporter(endpoint="http://localhost:8080/v1/metrics")
reader = PeriodicExportingMetricReader(exporter, export_interval_millis=15000)
provider = MeterProvider(metric_readers=[reader])

Node.js

const { OTLPMetricExporter } = require('@opentelemetry/exporter-otlp-http');
const { MeterProvider, PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics');

const exporter = new OTLPMetricExporter({
url: 'http://localhost:8080/v1/metrics',
});
const provider = new MeterProvider({
readers: [new PeriodicExportingMetricReader({ exporter, exportIntervalMillis: 15000 })],
});

TLS Configuration

For production, enable TLS on the Ingestion Gateway:

GATEWAY_TLS_CERT=/etc/ssl/infrasage/cert.pem
GATEWAY_TLS_KEY=/etc/ssl/infrasage/key.pem
GATEWAY_TLS_ENABLED=true

Then configure your OTEL exporter to use HTTPS:

exporters:
otlphttp:
endpoint: https://ingest.mycompany.com
tls:
cert_file: /etc/ssl/client/cert.pem
key_file: /etc/ssl/client/key.pem

Trace Sampling

For high-volume trace ingestion, configure a tail-based sampler in the OTEL Collector to reduce volume before sending to InfraSage:

processors:
tail_sampling:
decision_wait: 10s
policies:
- name: error-policy
type: status_code
status_code: { status_codes: [ERROR] }
- name: slow-traces
type: latency
latency: { threshold_ms: 500 }

Verification

# Check ingestion received OTLP data
curl -s 'http://localhost:9999/api/v1/query?query=infrasage_ingestion_events_total' | \
jq '.data.result[] | select(.metric.format == "otlp")'

# Query a specific OTEL service in ClickHouse
docker exec infrasage-clickhouse clickhouse-client \
--user infrasage --password infrasage-dev \
--query "SELECT service_id, count() FROM infrasage.infrasage_raw_firehose
WHERE service_id = 'my-otel-service' GROUP BY service_id"

Performance

MetricResult
Max throughput (OTLP/HTTP)100,000+ msg/sec
Batch size (recommended)10,000 records
Supported formatsOTLP JSON, OTLP protobuf
AuthAPI key (header: X-API-Key) or no-auth in dev