Collector And curl Examples
LiveProduct tests cover the smoke runner, Collector-shaped fixtures, endpoint behavior, and queries. Those tests do not execute an external Collector process.
Guide
Configure local Collector forwarding and send JSON logs and traces to LogDB with complete files, separate terminals, and local tenant checks.
Current availability
Private Beta. Public beta is scheduled for .
Product tests cover the smoke runner, Collector-shaped fixtures, endpoint behavior, and queries. Those tests do not execute an external Collector process.
Use the local examples with the documented tenant headers and policy boundaries. Confirm the current collector deployment scope before adapting them to a shared or live environment.
| Workflow | Status | Validation | Source |
|---|---|---|---|
| Collector HTTP and gRPC configuration | Local configuration | Runner and fixture tests | otelcol-logdb-smoke.yaml |
| Service terminal | Complete local script | Startup and cleanup checks | start-logdb.sh |
| Collector smoke runner | Local smoke procedure | Runner tests | run-collector-smoke.sh |
| JSON log ingest | Local JSON compatibility | Endpoint tests | curl-otlp-json-log.sh |
| JSON trace ingest and query | Local JSON compatibility | Endpoint and query tests | curl-otlp-json-trace-query.sh |
| Tenant rejection | Negative local check | Query policy tests | check-tenant-policy.sh |
Collector exporters and curl commands must include x-logdb-tenant: local and authorization: Bearer local-dev-token for the local development policy.
The smoke runner needs an installed otelcol executable with OTLP receivers and exporters. Use the JSON curl examples when you only need to exercise local ingest and query.
These examples cover logs, traces, local retained-record query, and tenant policy only; metrics, profiles, dashboards, SIEM replacement, and production claims stay out of scope.
This procedure assumes you already have the LogDB source and Rust toolchain used by the local quickstart, plus Bash, curl, and mktemp. Use fresh terminals with no other LogDB environment overrides. Check that ports 4318 and 4317 are available. These examples use loopback listeners, synthetic local credentials, and plaintext gRPC. Keep them on your own machine.
LOGDB_SOURCE_DIR with the absolute path of your existing LogDB source directory using export LOGDB_SOURCE_DIR="/absolute/path/to/logdb". Replace that path with your checkout, then save and run start-logdb.sh. It prints its unique temporary data directory and waits for its service process. Leave the script running.LOGDB_SOURCE_DIRagain there; the first terminal's variables are not shared. To run the Collector smoke, also export LOGDB_COLLECTOR_SMOKE_OTELCOL_BINto the absolute path of your installed Collector executable. The JSON curl examples do not require a Collector. collector/otelcol-logdb-smoke.yaml under the LogDB crate directory before running the smoke script. The runner supplies LOGDB_COLLECTOR_HTTP_INPUT_ENDPOINT and LOGDB_COLLECTOR_GRPC_INPUT_ENDPOINT as disposable loopback receiver addresses, and supplies LOGDB_COLLECTOR_LOGDB_HTTP_ENDPOINT and LOGDB_COLLECTOR_LOGDB_GRPC_ENDPOINT from its LogDB target settings. Run this configuration through the smoke runner.The curl scripts define their own endpoint, tenant, token, dataset, and trace ID defaults. Use the shown local values. If adapting JSON fields, use values without quotes, backslashes, or line breaks; the shell substitutions are not a general JSON encoder.
Stop LogDB with Ctrl-C in the service terminal after finishing the workflow. The startup script requests termination, waits up to five seconds, and forcibly stops its owned service if needed before deleting only the temporary data directory it created. Save any results you need before stopping. The source checkout, saved scripts, Collector configuration, and build caches remain. The smoke runner stops its child Collector when it finishes.
Local LogDB requests require both x-logdb-tenant and authorization. Missing tenant headers are rejected; use the OTLP and query reference for exact error details.
Each block below is a complete file. Save shell files and run them with Bash so their exit handling stays inside the script. The Collector YAML contains both receivers, both exporters, and all four service pipelines.
YAML
Collector YAML
otelcol-logdb-smoke.yaml
Complete local Collector configuration, including all four logs/traces pipelines. The smoke runner supplies its environment variables. Save this file as collector/otelcol-logdb-smoke.yaml in the LogDB crate directory.
receivers:
otlp/http_to_http:
protocols:
http:
endpoint: ${env:LOGDB_COLLECTOR_HTTP_INPUT_ENDPOINT}
otlp/http_to_grpc:
protocols:
http:
endpoint: ${env:LOGDB_COLLECTOR_GRPC_INPUT_ENDPOINT}
exporters:
otlphttp/logdb:
endpoint: ${env:LOGDB_COLLECTOR_LOGDB_HTTP_ENDPOINT}
headers:
x-logdb-tenant: local
authorization: Bearer local-dev-token
otlp/logdb:
endpoint: ${env:LOGDB_COLLECTOR_LOGDB_GRPC_ENDPOINT}
tls:
insecure: true
headers:
x-logdb-tenant: local
authorization: Bearer local-dev-token
service:
telemetry:
logs:
level: error
pipelines:
logs/http:
receivers: [otlp/http_to_http]
exporters: [otlphttp/logdb]
traces/http:
receivers: [otlp/http_to_http]
exporters: [otlphttp/logdb]
logs/grpc:
receivers: [otlp/http_to_grpc]
exporters: [otlp/logdb]
traces/grpc:
receivers: [otlp/http_to_grpc]
exporters: [otlp/logdb]
Bash
Start the service
start-logdb.sh
Complete script for the service terminal. Save as start-logdb.sh and run with bash start-logdb.sh. It creates disposable data, waits for its LogDB process, and removes only that directory after stopping the process.
#!/usr/bin/env bash
set -euo pipefail
# Service terminal: keep this script running while using the workflow terminal.
cd "${LOGDB_SOURCE_DIR:?Set LOGDB_SOURCE_DIR to your LogDB source directory.}/LogDB"
cargo build --locked --bin logdb --target-dir "$LOGDB_SOURCE_DIR/LogDB/target"
export LOGDB_BIND_ADDRESS=127.0.0.1:4318
export LOGDB_OTLP_GRPC_BIND_ADDRESS=127.0.0.1:4317
export LOGDB_DATA_DIR
LOGDB_DATA_DIR="$(mktemp -d "${TMPDIR:-/tmp}/logdb-collector.XXXXXX")"
readonly LOGDB_DATA_DIR
# Stop the owned service before deleting this script's temporary data.
service_pid=
cleanup() {
trap '' INT TERM
if [ -n "$service_pid" ]; then
kill -TERM "$service_pid" 2>/dev/null || true
for attempt in 1 2 3 4 5; do
kill -0 "$service_pid" 2>/dev/null || break
sleep 1
done
if kill -0 "$service_pid" 2>/dev/null; then
kill -KILL "$service_pid" 2>/dev/null || true
fi
wait "$service_pid" 2>/dev/null || true
fi
rm -rf -- "$LOGDB_DATA_DIR"
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
printf 'Temporary tutorial data: %s\n' "$LOGDB_DATA_DIR"
"$LOGDB_SOURCE_DIR/LogDB/target/debug/logdb" &
service_pid=$!
wait "$service_pid"
Bash
Run the Collector smoke
run-collector-smoke.sh
Complete script for the separate workflow terminal. Save as run-collector-smoke.sh and run with bash run-collector-smoke.sh after exporting LOGDB_SOURCE_DIR and LOGDB_COLLECTOR_SMOKE_OTELCOL_BIN in that terminal. It checks HTTP readiness, then starts the smoke runner.
#!/usr/bin/env bash
set -euo pipefail
# Workflow terminal: the service must already be running in its own terminal.
cd "${LOGDB_SOURCE_DIR:?Set LOGDB_SOURCE_DIR to your LogDB source directory.}/LogDB"
export LOGDB_COLLECTOR_SMOKE_OTELCOL_BIN="${LOGDB_COLLECTOR_SMOKE_OTELCOL_BIN:?Set this to your otelcol binary path.}"
export LOGDB_COLLECTOR_SMOKE_LOGDB_HTTP_ENDPOINT=http://127.0.0.1:4318
export LOGDB_COLLECTOR_SMOKE_LOGDB_GRPC_ENDPOINT=127.0.0.1:4317
export LOGDB_COLLECTOR_SMOKE_CONFIG=collector/otelcol-logdb-smoke.yaml
curl -fsS "$LOGDB_COLLECTOR_SMOKE_LOGDB_HTTP_ENDPOINT/health"
cargo run --locked --bin logdb-collector-smoke
Bash
Send a JSON log
curl-otlp-json-log.sh
Complete script for the workflow terminal with the local service running. Save and run with Bash. It sends one synthetic log through the JSON compatibility route; it does not use the Collector.
#!/usr/bin/env bash
set -euo pipefail
export LOGDB_ENDPOINT="${LOGDB_ENDPOINT:-http://127.0.0.1:4318}"
export LOGDB_TENANT="${LOGDB_TENANT:-local}"
export LOGDB_TOKEN="${LOGDB_TOKEN:-local-dev-token}"
export LOGDB_DATASET="${LOGDB_DATASET:-checkout}"
curl -fsS -X POST "$LOGDB_ENDPOINT/v1/otlp/logs" \
-H "content-type: application/json" \
-H "x-logdb-tenant: $LOGDB_TENANT" \
-H "authorization: Bearer $LOGDB_TOKEN" \
--data @- <<JSON
{
"resourceLogs": [{
"resource": {
"attributes": [
{"key": "tenant_id", "value": {"stringValue": "$LOGDB_TENANT"}},
{"key": "service.name", "value": {"stringValue": "$LOGDB_DATASET"}}
]
},
"scopeLogs": [{
"logRecords": [{
"timeUnixNano": "1783947600000000000",
"body": {"stringValue": "collector example log"}
}]
}]
}]
}
JSON
Bash
Send and query a JSON trace
curl-otlp-json-trace-query.sh
Complete script for the workflow terminal. Save and run with Bash. It sends one synthetic span and queries the same dataset and trace ID. A fresh tutorial directory contains one matching trace record.
#!/usr/bin/env bash
set -euo pipefail
export LOGDB_ENDPOINT="${LOGDB_ENDPOINT:-http://127.0.0.1:4318}"
export LOGDB_TENANT="${LOGDB_TENANT:-local}"
export LOGDB_TOKEN="${LOGDB_TOKEN:-local-dev-token}"
export LOGDB_DATASET="${LOGDB_DATASET:-checkout}"
export LOGDB_TRACE_ID="${LOGDB_TRACE_ID:-4bf92f3577b34da6a3ce929d0e0e4736}"
curl -fsS -X POST "$LOGDB_ENDPOINT/v1/otlp/traces" \
-H "content-type: application/json" \
-H "x-logdb-tenant: $LOGDB_TENANT" \
-H "authorization: Bearer $LOGDB_TOKEN" \
--data @- <<JSON
{
"resourceSpans": [{
"resource": {
"attributes": [
{"key": "tenant_id", "value": {"stringValue": "$LOGDB_TENANT"}},
{"key": "service.name", "value": {"stringValue": "$LOGDB_DATASET"}}
]
},
"scopeSpans": [{
"spans": [{
"traceId": "$LOGDB_TRACE_ID",
"spanId": "00f067aa0ba902b7",
"name": "collector example span",
"startTimeUnixNano": "1783947600000000000"
}]
}]
}]
}
JSON
curl -fsS -X POST "$LOGDB_ENDPOINT/v1/query" \
-H "content-type: application/json" \
-H "x-logdb-tenant: $LOGDB_TENANT" \
-H "authorization: Bearer $LOGDB_TOKEN" \
--data @- <<JSON
{
"dataset": "$LOGDB_DATASET",
"filter": {
"trace_id": "$LOGDB_TRACE_ID"
},
"page": {
"limit": 10
}
}
JSON
Bash
Check tenant rejection
check-tenant-policy.sh
Complete negative check for the workflow terminal. Save and run with Bash. It deliberately omits tenant and authorization headers and leaves the rejected response visible.
#!/usr/bin/env bash
set -euo pipefail
export LOGDB_ENDPOINT="${LOGDB_ENDPOINT:-http://127.0.0.1:4318}"
# This request deliberately omits tenant and authorization headers.
# Keep the rejected HTTP response body visible for inspection.
curl -sS -X POST "$LOGDB_ENDPOINT/v1/query" \
-H "content-type: application/json" \
--data '{"dataset":"checkout"}'
| Behavior | Surface | Source scope | Maturity |
|---|---|---|---|
| Collector exports logs and traces over OTLP HTTP/protobuf | otlphttp exporter to /v1/logs and /v1/traces | documented source scope and otelcol-logdb-smoke.yaml | Live route behavior; smoke process opt-in |
| Collector exports logs and traces over OTLP/gRPC | otlp exporter to optional gRPC listener | documented source scope and logdb-collector-smoke.rs | Live when LOGDB_OTLP_GRPC_BIND_ADDRESS is configured |
| Send OTLP JSON compatibility logs | POST /v1/otlp/logs | documented source scope, and OtlpHttpEndpointTests | Live |
| Send OTLP JSON compatibility traces | POST /v1/otlp/traces | documented source scope, and OtlpHttpEndpointTests | Live |
| Query retained trace records | POST /v1/query | documented source scope and QueryApiEndpointTests | Live |
| Reject missing tenant header | Tenant admission and query authorization | documented source scope and QueryApiEndpointTests | Local tenant policy |
The live collector smoke emits a unique trace ID. The curl examples use safe synthetic payloads and record IDs.
Text
Expected Output
Representative output from separate Collector and curl workflows. IDs vary; query JSON shows selected fields.
collector smoke passed
trace_id: <unique 32 hex chars>
matched_records: 4
log_bodies: collector smoke grpc log, collector smoke http log
span_names: collector smoke grpc span, collector smoke http span
{
"status": "accepted",
"signal": "log",
"accepted_records": 1,
"record_ids": ["logdb_..."]
}
{
"status": "accepted",
"signal": "trace",
"accepted_records": 1,
"record_ids": ["logdb_..."]
}
{
"status": "ok",
"tenant_id": "local",
"dataset": "checkout",
"matched_records": 1,
"results": [{ "record": { "signal": "trace" } }]
}
{
"status": "rejected",
"retryable": false,
"error": {
"kind": "missing_tenant",
"message": "x-logdb-tenant header is required"
}
}| Command | What it proves | Validation status |
|---|---|---|
cargo test --manifest-path LogDB/Cargo.toml --bin logdb-collector-smoke | Collector endpoint normalization, command environment, payload mutation, response parsing, and evidence evaluation. | passed 6/6 on 2026-08-16 |
cargo test --manifest-path LogDB/Cargo.toml otlp_collector | Collector-shaped OTLP log and trace fixtures encode official export request values. | passed 2/2 on 2026-08-16 |
dotnet test <LogDB automated tests solution> --filter OtlpHttpEndpointTests|QueryApiEndpointTests | OTLP JSON compatibility ingest, native OTLP HTTP/protobuf behavior, query by ID/trace ID, and missing-auth rejection. | passed 10/10 on 2026-08-16 |
LogDB examples stay scoped to logs, traces, local retained-record query, and local tenant policy. Use the compatibility matrix before strengthening S3, gRPC, metrics, profiles, BYOC, replay, support, or production claims.
Available
Run the local quickstartUse the curl first-success path before adapting collector configuration.
Available
Read OTLP and query referenceReview route shapes, content types, tenant headers, query filters, errors, and limits.
Available
Compare OTLP and S3 scopeConfirm live, partial, unsupported, preview, future, and verification-required boundaries before adding more example claims.
Available
Review guide patternsUse the manifest check alongside product tests before changing status or evidence wording.