Skip to content

Observability

FrogDB provides comprehensive observability through Prometheus metrics, OpenTelemetry (OTLP) export, distributed tracing, DTrace/USDT probes, and structured logging.

FrogDB exports metrics in Prometheus format on the HTTP endpoint (default port 9090):

GET http://<host>:9090/metrics
[http]
enabled = true
bind = "127.0.0.1"
port = 9090

See Metrics Reference for the complete list of all exported metrics.

Metrics can be exported to any OpenTelemetry-compatible collector via OTLP/gRPC:

[metrics]
otlp-enabled = true
otlp-endpoint = "http://otel-collector:4317"
otlp-interval-secs = 15
SettingTypeDefaultDescription
otlp-enabledbooleanfalseEnable OTLP metrics export
otlp-endpointstringhttp://localhost:4317gRPC endpoint of the OTLP collector
otlp-interval-secsinteger15Export interval in seconds

FrogDB supports OpenTelemetry distributed tracing with configurable span granularity.

[tracing]
enabled = true
otlp-endpoint = "http://jaeger:4317"
sampling-rate = 0.1 # Sample 10% of requests
service-name = "frogdb"
scatter-gather-spans = false # Child spans per shard for MGET/MSET
shard-spans = false # Spans inside shard workers
persistence-spans = false # WAL/snapshot spans

When tracing is enabled, FrogDB emits spans at three levels:

  1. Request span — created at connection handler, covers the full command lifecycle
  2. Shard execution span — created in the shard worker, covers command processing
  3. Store operation span — individual data structure operations

FrogDB uses OpenTelemetry database semantic conventions:

AttributeExample
db.systemfrogdb
db.operationGET, SET, MGET
db.statementSET mykey myvalue
frogdb.shard_id3
frogdb.connection_id42
frogdb.key_count1

FrogDB keeps the last 100 traces in memory for debugging (configurable via tracing.recent-traces-max). These are available through the Debug UI.

FrogDB includes USDT (User Statically Defined Tracing) probes for low-overhead, production-safe tracing on macOS and Linux. Enable at build time with --features usdt-probes.

ProbeArgumentsDescription
command__startcommand, key, conn_idFired when a command begins execution
command__donecommand, latency_us, statusFired when a command completes
shard__message__sentfrom_shard, to_shard, msg_typeInter-shard message dispatched
shard__message__receivedshard, msg_type, queue_depthShard received a message
key__expiredkey, shard_idKey expired via TTL
key__evictedkey, shard_id, policyKey evicted due to memory pressure
memory__pressureused, max, actionMemory pressure event
wal__writeshard_id, key, bytesWAL write for a key
scatter__startcommand, shard_count, txidScatter-gather operation started
scatter__donecommand, latency_us, shard_countScatter-gather operation completed
pubsub__publishchannel, subscribersMessage published to a channel
connection__acceptconn_id, addrNew client connection accepted
Terminal window
# List all FrogDB probes (macOS)
sudo dtrace -l -n 'frogdb*:::'
# Trace all commands
sudo dtrace -n 'frogdb*:::command-start { printf("%s %s\n", copyinstr(arg0), copyinstr(arg1)); }'
# Measure command latency
sudo dtrace -n 'frogdb*:::command-done { printf("%s %d us\n", copyinstr(arg0), arg1); }'
# Watch memory pressure events
sudo dtrace -n 'frogdb*:::memory-pressure { printf("used=%d max=%d action=%s\n", arg0, arg1, copyinstr(arg2)); }'
# With bpftrace (Linux)
sudo bpftrace -e 'usdt:./frogdb-server:frogdb:command__start { printf("%s %s\n", str(arg0), str(arg1)); }'

FrogDB uses structured logging with configurable output format and level.

[logging]
level = "info" # trace, debug, info, warn, error
format = "json" # "json" or "pretty"
output = "stdout" # "stdout", "stderr", or "none"
per-request-spans = false # Per-request tracing spans (~13% CPU overhead)
file-path = "/var/log/frogdb/frogdb.log"
[logging.rotation]
max-size-mb = 100
frequency = "daily" # "daily", "hourly", or "never"
max-files = 5

The log level can be changed at runtime without restart:

Terminal window
redis-cli CONFIG SET loglevel debug