Send Your First Telemetry
InfraSage accepts telemetry in three formats. This guide shows you how to send each type and verify the data was received.
Format 1 — Plain JSON (Recommended for Getting Started)
The simplest way to send a single metric:
curl -X POST http://localhost:8080/api/v1/telemetry \
-H "Content-Type: application/json" \
-d '{
"service_id": "payment-api",
"metric_name": "request_latency_ms",
"value": 142.5,
"timestamp": "2026-04-10T12:00:00Z",
"attributes": {
"region": "us-east-1",
"env": "production",
"version": "v2.3.1"
}
}'
Batch ingestion (up to 10,000 records per request)
curl -X POST http://localhost:8080/api/v1/telemetry/batch \
-H "Content-Type: application/json" \
-d '[
{
"service_id": "payment-api",
"metric_name": "request_latency_ms",
"value": 142.5,
"timestamp": "2026-04-10T12:00:00Z"
},
{
"service_id": "payment-api",
"metric_name": "error_rate",
"value": 0.02,
"timestamp": "2026-04-10T12:00:00Z"
},
{
"service_id": "user-service",
"metric_name": "cpu_usage_percent",
"value": 72.1,
"timestamp": "2026-04-10T12:00:00Z"
}
]'
Format 2 — OpenTelemetry (OTLP)
Configure your OTEL collector to export to InfraSage:
# otel-collector-config.yaml
exporters:
otlphttp:
endpoint: http://localhost:8080
headers:
Content-Type: application/x-protobuf
service:
pipelines:
metrics:
exporters: [otlphttp]
traces:
exporters: [otlphttp]
logs:
exporters: [otlphttp]
Or send raw OTLP JSON:
curl -X POST http://localhost:8080/v1/metrics \
-H "Content-Type: application/json" \
-d '{
"resourceMetrics": [{
"resource": {
"attributes": [{"key": "service.name", "value": {"stringValue": "checkout-service"}}]
},
"scopeMetrics": [{
"metrics": [{
"name": "http.request.duration",
"gauge": {
"dataPoints": [{
"asDouble": 0.125,
"timeUnixNano": "1712750400000000000"
}]
}
}]
}]
}]
}'
Format 3 — Prometheus Remote Write
Add InfraSage as a remote-write target in your prometheus.yml:
remote_write:
- url: http://localhost:8080/api/v1/prometheus/write
queue_config:
max_samples_per_send: 10000
batch_send_deadline: 5s
Telemetry Types
InfraSage supports six telemetry types. Specify the type in the type field (defaults to metric):
| Type | hasValue | hasBody | hasTrace | Use Case |
|---|---|---|---|---|
metric | Yes | No | No | CPU, memory, latency, throughput |
log | No | Yes | No | Application logs |
trace | Yes | No | Yes | Distributed tracing, spans |
event | No | Yes | No | Kubernetes events, deploys |
profile | Yes | Yes | No | CPU/memory profiling |
slo | Yes | No | No | SLI/SLO compliance tracking |
Sending a log entry
curl -X POST http://localhost:8080/api/v1/telemetry \
-H "Content-Type: application/json" \
-d '{
"service_id": "auth-service",
"type": "log",
"body": "User login failed: invalid credentials",
"timestamp": "2026-04-10T12:00:00Z",
"attributes": {
"level": "warn",
"user_id": "u-12345"
}
}'
Sending a trace span
curl -X POST http://localhost:8080/api/v1/telemetry \
-H "Content-Type: application/json" \
-d '{
"service_id": "checkout-service",
"type": "trace",
"metric_name": "checkout.duration",
"value": 0.342,
"trace_id": "abc123def456",
"timestamp": "2026-04-10T12:00:00Z"
}'
Sending an SLO reading
curl -X POST http://localhost:8080/api/v1/telemetry \
-H "Content-Type: application/json" \
-d '{
"service_id": "api-gateway",
"type": "slo",
"metric_name": "availability",
"value": 99.97,
"timestamp": "2026-04-10T12:00:00Z"
}'
Verify Data Was Received
Check the ingestion counter
curl -s 'http://localhost:9999/api/v1/query?query=infrasage_ingestion_events_total' | \
jq '.data.result[].value[1]'
Query ClickHouse directly
docker exec infrasage-clickhouse clickhouse-client \
--user infrasage --password infrasage-dev \
--query "
SELECT
service_id,
metric_name,
count() AS events,
max(timestamp) AS last_seen
FROM infrasage.infrasage_raw_firehose
GROUP BY service_id, metric_name
ORDER BY last_seen DESC
LIMIT 20
"
List supported telemetry types via API
curl http://localhost:8080/api/v1/telemetry-types
Validation Rules
InfraSage validates every record before queueing. Records that fail validation are sent to the dead-letter queue (DLQ) — not silently dropped.
| Rule | Details |
|---|---|
service_id required | Must be non-empty |
timestamp age | Must be within ±24 hours of current time |
value range | Must be a finite float64 (no NaN, no Inf) |
metric_name length | Maximum 256 characters |
type enum | Must be one of: metric, log, trace, event, profile, slo |
Failed records are stored in the DLQ with their original payload for manual inspection and replay:
curl http://localhost:8080/api/v1/debug/dlq-stats