Skip to main content

Elastic Backend

Uses Elasticsearch DSL for log queries, aggregations for metrics, and Elastic APM for distributed tracing.

TINKR_BACKEND=elastic

Authentication

Tinkr authenticates to Elasticsearch using an API key. Create one in Kibana:

Stack Management → Security → API Keys → Create API Key

Grant the key:

  • read on indices logs-*, filebeat-*, traces-*, apm-*
  • monitor on cluster

Or use a username/password for simpler setups.


Environment variables

VariableRequiredDescription
ELASTIC_URLYesElasticsearch base URL (e.g. https://elastic.acme.internal:9200)
ELASTIC_API_KEYYes (or user/pass)Base64-encoded API key from Kibana
ELASTIC_USERNAMEAlt to API keyElasticsearch username
ELASTIC_PASSWORDAlt to API keyElasticsearch password
ELASTIC_INDEX_PATTERNNoLog index pattern (default: logs-*,filebeat-*)

Profile configuration

~/.tinkr/config.toml
[profiles.elastic-prod]
backend = "elastic"
url = "env:ELASTIC_URL"
index_pattern = "logs-*,filebeat-*"
~/.tinkr/.env
ELASTIC_URL=https://elastic.acme.internal:9200
ELASTIC_API_KEY=VnVhQ2ZHY0JDZGJrZXctATxxxxxxxxxxxxxxxx==

Log query (Elasticsearch DSL)

Tinkr queries using the Elasticsearch DSL:

{
"query": {
"bool": {
"must": [
{ "match": { "service.name": "payments-api" } },
{ "match": { "log.level": "ERROR" } },
{ "range": { "@timestamp": { "gte": "now-1h", "lte": "now" } } }
]
}
},
"sort": [{ "@timestamp": { "order": "desc" } }],
"size": 100
}

Field mapping (ECS-aligned):

Tinkr fieldElasticsearch field
serviceservice.name
levellog.level
timestamp@timestamp
messagemessage

If your indices use a different field layout, set ELASTIC_INDEX_PATTERN to target the right indices.


Metrics (aggregations)

Tinkr uses Elasticsearch date-histogram aggregations to compute metric time series:

{
"query": { "term": { "service.name": "payments-api" } },
"aggs": {
"over_time": {
"date_histogram": { "field": "@timestamp", "fixed_interval": "5m" },
"aggs": { "error_count": { "filter": { "term": { "log.level": "ERROR" } } } }
}
}
}

Distributed tracing (Elastic APM)

Tinkr queries the traces-* and apm-* indices for root spans (spans with no parent.id):

{
"query": {
"bool": {
"must": [
{ "term": { "service.name": "payments-api" } },
{ "range": { "@timestamp": { "gte": "now-1h" } } }
],
"must_not": [{ "exists": { "field": "parent.id" } }]
}
},
"sort": [{ "transaction.duration.us": { "order": "desc" } }],
"size": 20
}

To send traces from your application, use the Elastic APM agent:

# Python
import elasticapm
client = elasticapm.Client(service_name="payments-api", server_url="http://apm-server:8200")

Or use the OpenTelemetry SDK with the OTLP exporter pointing to the Elastic APM server (which accepts OTLP natively since 7.16).


Elastic Cloud (hosted)

For Elastic Cloud, use the Cloud ID + API key:

ELASTIC_URL=https://xxxxxxxxxxxx.es.us-east-1.aws.elastic-cloud.com:9243
ELASTIC_API_KEY=VnVhQ2ZHY0JDZGJrZXctATxxxxxxxxxxxxxxxx==

Local development

# Run Elasticsearch + Kibana locally
docker run -p 9200:9200 -e "discovery.type=single-node" elasticsearch:8.x

export TINKR_BACKEND=elastic
export ELASTIC_URL=http://localhost:9200
export ELASTIC_USERNAME=elastic
export ELASTIC_PASSWORD=changeme
uv run tinkr-server