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 checks 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 IDmktemp for the local service wrapper.Required
LOGDB_SOURCE_DIR points at the LogDB source checkout.LOGDB_BIND_ADDRESS uses an unprivileged loopback port, such as 127.0.0.1:4318.LOGDB_DATA_DIR for every run.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 startup script allocates a fresh temporary data directory for each run and deletes only that directory after stopping the owned process.
Workflow terminal
Point this shell at the LogDB source checkout. The service script uses the same value in its own terminal.
export LOGDB_SOURCE_DIR=/path/to/logdbLOGDB_SOURCE_DIR points at a checkout that contains LogDB/Cargo.toml.Service terminal
Save this complete file as start-logdb.sh, run bash start-logdb.sh, and keep it running while you use the workflow terminal. The script prints the temporary data directory it owns.
#!/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="${LOGDB_BIND_ADDRESS:-127.0.0.1:4318}"
export LOGDB_DATA_DIR
LOGDB_DATA_DIR="$(mktemp -d "${TMPDIR:-/tmp}/logdb-quickstart.XXXXXX")"
readonly LOGDB_DATA_DIR
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 LogDB data: %s\n' "$LOGDB_DATA_DIR"
"$LOGDB_SOURCE_DIR/LogDB/target/debug/logdb" &
service_pid=$!
status=0
wait "$service_pid" || status=$?
service_pid=
exit "$status"
Temporary LogDB data: /tmp/logdb-quickstart.<unique>
The service starts on 127.0.0.1:4318. The script stops the owned process and removes only its printed temporary directory when it exits.Workflow terminal
Open a second terminal and confirm that the local HTTP service is ready before sending telemetry.
export LOGDB_ENDPOINT=http://127.0.0.1:4318
curl -fsS "$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
Return to the service terminal and stop the startup script. It terminates the owned LogDB process before deleting the temporary directory it printed.
# Press Ctrl-C in the service terminal running bash start-logdb.sh.The script exits, the local LogDB process stops, and only the printed /tmp/logdb-quickstart.<unique> directory is removed.| Symptom | How to recognize it | Likely cause | Fix |
|---|---|---|---|
| Service does not start | bash start-logdb.sh reports that the build failed, the address is already in use, or the service cannot bind. | LOGDB_SOURCE_DIR does not point at a buildable checkout, or another local process is using 127.0.0.1:4318. | Confirm LOGDB_SOURCE_DIR, or 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 startup-script 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 | Source scope | 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 product confirmation |
| 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 product-bound |
This quickstart uses OTLP HTTP JSON compatibility routes and the local segment query store under the startup script's temporary 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 limitsUse the limits and compatibility guidance 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
Read OTLP and query referenceOTLP HTTP/protobuf, optional gRPC, JSON compatibility, custom endpoint, tenant header, limit, error, and query filter details.
Available
Compare OTLP and S3 query scopeDistinguish live ingest, optional gRPC, local query, S3 query reads, metrics/profile exclusions, and future publication work.
Available
Use OpenTelemetry Collector examplesExtend the quickstart with collector configuration, curl payloads, retained-record query checks, tenant headers, and local policy warnings.