Ingest And Query Workflow
LiveLocal OTLP JSON compatibility ingest and POST /v1/query search are implemented for this first-success path.
Quickstart
Run a local LogDB process, send OTLP JSON compatibility logs and traces, capture record IDs, query retained records, and see how the local tenant policy gates access.
Current availability
Private Beta. Public beta is scheduled for .
You will have a local LogDB workflow that accepts one log and two trace records, returns logdb_... record IDs, queries a retained log by exact record ID, queries retained trace spans by trace ID with pagination, and confirms that requests without x-logdb-tenant are rejected.
Local OTLP JSON compatibility ingest and POST /v1/query search are implemented for this first-success path.
This tutorial proves local behavior only. S3 publication, BYOC, public replay APIs, external sinks, performance, support, security, availability, scale, and GA claims still need evidence review.
Required
cargo --version for the Rust toolchaincurl --version for HTTP requestssed for extracting the first returned record IDRequired
/path/to/logdb or an equivalent local checkout.LOGDB_BIND_ADDRESS set to an unprivileged loopback port, such as 127.0.0.1:4318.LOGDB_DATA_DIR set to a disposable tutorial directory.Required
x-logdb-tenant: local on OTLP JSON compatibility ingest and query requests.Authorization: Bearer local-dev-token for the local development tenant.Optional
jq can make JSON inspection easier, but the copy/paste workflow uses only shell, curl, and sed.See local prerequisites for the shared tool baseline.
Use one terminal for the LogDB service and a second terminal for the workflow commands. The query route reads segment bundles from the local data directory by default.
Service terminal
cd /path/to/logdb/LogDB
export LOGDB_BIND_ADDRESS=127.0.0.1:4318
export LOGDB_DATA_DIR="${TMPDIR:-/tmp}/logdb-docs-024"
mkdir -p "$LOGDB_DATA_DIR"
cargo runCargo builds the LogDB crate, opens the local data directory, and starts the HTTP service on 127.0.0.1:4318.
Keep this terminal open while you run the workflow commands.Workflow terminal
export LOGDB_ENDPOINT=http://127.0.0.1:4318
curl -s "$LOGDB_ENDPOINT/health""Healthy"Copy/paste
Set one endpoint, the local development tenant credentials, and the trace ID used by the trace query.
export LOGDB_ENDPOINT=http://127.0.0.1:4318
export LOGDB_TENANT=local
export LOGDB_TOKEN=local-dev-token
export LOGDB_DATASET=checkout
export LOGDB_TRACE_ID=4bf92f3577b34da6a3ce929d0e0e4736These values point at the local development policy. The dataset comes from the OTLP resource attribute service.name=checkout.Copy/paste
Post one OpenTelemetry-shaped JSON compatibility log batch and keep the response for record ID extraction.
LOG_RESPONSE="$(curl -s -X POST "$LOGDB_ENDPOINT/v1/otlp/logs" \
-H 'content-type: application/json' \
-H "x-logdb-tenant: $LOGDB_TENANT" \
-H "authorization: Bearer $LOGDB_TOKEN" \
--data '{
"resourceLogs": [{
"resource": {
"attributes": [
{"key": "tenant_id", "value": {"stringValue": "local"}},
{"key": "service.name", "value": {"stringValue": "checkout"}}
]
},
"scopeLogs": [{
"logRecords": [{
"timeUnixNano": "1783947600000000000",
"body": {"stringValue": "payment accepted"}
}]
}]
}]
}')"
printf '%s\n' "$LOG_RESPONSE"{"status":"accepted","signal":"log","accepted_records":1,"record_ids":["logdb_..."]}Copy/paste
Extract the first deterministic logdb_... record ID from the accepted response.
LOG_RECORD_ID="$(printf '%s' "$LOG_RESPONSE" | sed -nE 's/.*"record_ids":\["([^"]+)".*/\1/p')"
printf '%s\n' "$LOG_RECORD_ID"logdb_...Copy/paste
Search the retained local segment bundles by exact record ID using the same tenant header and bearer token.
curl -s -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": {
"record_id": "$LOG_RECORD_ID"
},
"page": {
"limit": 10
}
}
JSON{
"status": "ok",
"api_version": "v1",
"tenant_id": "local",
"dataset": "checkout",
"matched_records": 1,
"results": [{
"record": {
"record_id": "logdb_...",
"source": "v1.otlp_http",
"signal": "log",
"raw_payload": {"record": {"body": {"stringValue": "payment accepted"}}}
}
}],
"used_indexes": ["record_id"]
}Copy/paste
Post two trace spans with the same trace ID so the query route can prove a retained trace selection.
TRACE_RESPONSE="$(curl -s -X POST "$LOGDB_ENDPOINT/v1/otlp/traces" \
-H 'content-type: application/json' \
-H "x-logdb-tenant: $LOGDB_TENANT" \
-H "authorization: Bearer $LOGDB_TOKEN" \
--data '{
"resourceSpans": [{
"resource": {
"attributes": [
{"key": "tenant_id", "value": {"stringValue": "local"}},
{"key": "service.name", "value": {"stringValue": "checkout"}}
]
},
"scopeSpans": [{
"spans": [
{
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"spanId": "00f067aa0ba902b7",
"name": "POST /checkout",
"startTimeUnixNano": "1783947600000000000"
},
{
"traceId": "4bf92f3577b34da6a3ce929d0e0e4736",
"spanId": "00f067aa0ba902b8",
"name": "SELECT inventory",
"startTimeUnixNano": "1783947600000000100"
}
]
}]
}]
}')"
printf '%s\n' "$TRACE_RESPONSE"{"status":"accepted","signal":"trace","accepted_records":2,"record_ids":["logdb_...","logdb_..."]}Copy/paste
Search the same dataset by exact trace ID and request one result so pagination is visible.
TRACE_QUERY_RESPONSE="$(curl -s -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": 1
}
}
JSON
)"
printf '%s\n' "$TRACE_QUERY_RESPONSE"{
"status": "ok",
"tenant_id": "local",
"dataset": "checkout",
"matched_records": 2,
"results": [{"record": {"signal": "trace"}}],
"page": {"limit": 1, "cursor": null, "next_cursor": "1"},
"used_indexes": ["identity.trace_id"]
}Copy/paste
Use the returned cursor to fetch the second retained trace record.
curl -s -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": 1,
"cursor": "1"
}
}
JSON{
"status": "ok",
"matched_records": 2,
"results": [{"record": {"signal": "trace"}}],
"page": {"limit": 1, "cursor": "1", "next_cursor": null}
}Copy/paste
Send a query without the local tenant headers to see the current local policy reject the request.
curl -s -X POST "$LOGDB_ENDPOINT/v1/query" \
-H 'content-type: application/json' \
--data '{"dataset":"checkout"}'{"status":"rejected","retryable":false,"error":{"kind":"missing_tenant","message":"x-logdb-tenant header is required",...}}The quickstart is successful when log ingest returns a logdb_... record ID, the exact-record query returns matched_records:1 with used_indexes:["record_id"], the trace query returns matched_records:2 with next_cursor:"1", the second trace page clears next_cursor, and the missing-header request returns missing_tenant.
Copy/paste
Stop LogDB with Ctrl-C in the service terminal before removing local tutorial data.
# Press Ctrl-C in the terminal running cargo run.The local LogDB process exits.Copy/paste
Remove only the disposable data directory used by this quickstart.
rm -rf "${TMPDIR:-/tmp}/logdb-docs-024"The tutorial data directory is gone. Do not remove a shared LOGDB_DATA_DIR.| Symptom | How to recognize it | Likely cause | Fix |
|---|---|---|---|
| Service does not start | cargo run reports that the address is already in use or cannot bind. | Another local process is using 127.0.0.1:4318. | Choose a different loopback port in LOGDB_BIND_ADDRESS and update LOGDB_ENDPOINT to match. |
| Health check cannot connect | curl reports connection refused or times out against 127.0.0.1:4318. | The service terminal stopped, is still compiling, or is bound to a different address. | Wait for Cargo to finish, confirm the service terminal is still open, and re-check LOGDB_ENDPOINT. |
Ingest returns missing_tenant | The response status is 401 Unauthorized and the JSON error kind is missing_tenant. | x-logdb-tenant was omitted or empty. | Send x-logdb-tenant: local on OTLP JSON compatibility and query requests. |
Ingest returns missing_credentials | The response status is 401 Unauthorized and the JSON error kind is missing_credentials. | The bearer token header was omitted or malformed. | Send authorization: Bearer local-dev-token with the local tenant header. |
Ingest returns tenant_mismatch | The response status is 403 Forbidden and the error mentions tenant claims. | The OTLP resource attribute tenant_id or service.logdb.tenant_id does not match x-logdb-tenant. | Use local in both the header and OTLP resource attributes for this quickstart. |
| Query returns zero matches | The response status is ok, but matched_records is 0 and results is empty. | The record ID, trace ID, dataset, or data directory does not match the ingest request. | Re-run ingest, re-extract LOG_RECORD_ID, and confirm LOGDB_DATASET=checkout. |
Trace page does not return next_cursor | The first trace query does not show page.next_cursor set to 1. | Only one trace span was accepted, or the query used a different trace ID. | Re-run the documented trace ingest command and query with LOGDB_TRACE_ID=4bf92f3577b34da6a3ce929d0e0e4736. |
| Workflow step | Evidence | Status |
|---|---|---|
| Service startup and health | LogDB source repository: README.md, LogDB/src/main.rs, LogDB/src/config.rs, and AutomatedTests/Health/HealthEndpointTests.cs | Source-backed; local run still needs reviewer acceptance |
| OTLP JSON compatibility ingest | LogDB source repository: README.md, LogDB/src/handlers/otlp_http_handler.rs, LogDB/src/ingestion/otlp_http.rs, and AutomatedTests/Otlp/OtlpHttpEndpointTests.cs | Source-backed |
| Tenant admission policy | LogDB source repository: LogDB/src/ingestion/tenant_admission.rs and query/ingest endpoint tests | Source-backed |
| Query by record ID and trace ID | LogDB source repository: docs/query/http-query-api.md, LogDB/src/handlers/query_handler.rs, LogDB/src/query/api.rs, and AutomatedTests/Query/QueryApiEndpointTests.cs | Source-backed |
| Segment publication and local limits | LogDB source repository: docs/ingestion/live-wal-gateway.md, docs/storage/segment-bundle-v1.md, and docs/fact-sheets/logdb.md | Source-backed; claims remain review-bound |
This quickstart uses OTLP HTTP JSON compatibility routes and the local segment query store under LOGDB_DATA_DIR.
The local development policy accepts tenant local with bearer token local-dev-token; the OTLP tenant claim must match the header.
The workflow covers logs, traces, retained segment search, record IDs, trace IDs, and pagination only.
S3 publication, BYOC deployment, public replay APIs, external sinks, scale, availability, support, and performance remain outside this quickstart.
Available now
Review LogDB evidenceUse the evidence index before strengthening ingest, query, S3, replay, BYOC, or GA claims.
Available now
Read tutorial prerequisitesCheck the shared local tool baseline and product-specific setup expectations for first-success tutorials.
Available: DOCS-033
Read OTLP and query referenceOTLP HTTP/protobuf, optional gRPC, JSON compatibility, custom endpoint, tenant header, limit, error, and query filter details.
Available: DOCS-039
Compare OTLP and S3 query scopeDistinguish live ingest, optional gRPC, local query, S3 query reads, metrics/profile exclusions, and future publication work.
Available: DOCS-060
Use OpenTelemetry Collector examplesExtend the quickstart with collector configuration, curl payloads, retained-record query checks, tenant headers, and local policy warnings.