Skip to main content

Config schema

Complete schema for ~/.hermes/hermes_otel.yaml (or a legacy ~/.hermes/plugins/hermes_otel/config.yaml, or the file named by HERMES_OTEL_CONFIG). See config.yaml for the narrative version.

The field table below is generated from HermesOtelConfig by scripts/gen_config_docs.py; a test fails if it drifts.

Top level

FieldTypeDefaultDescription
enabledbooltrueMaster kill switch; false unloads every hook
sample_ratefloat | nullnullParent-based trace-ID ratio 0.0–1.0; null = AlwaysOn (no sampling)
root_span_ttl_msint600000Orphan-sweep TTL: a turn root older than this with no end hook is closed
flush_interval_msint60000Metrics export cadence (PeriodicExportingMetricReader)
preview_max_charsint1200Cap on preview strings (tool args/results, user message, assistant response)
capture_previewsbooltruefalse suppresses every input/output preview; metadata still recorded
tool_input_preview_max_charsint | nullnullPer-category cap for tool args previews; null = preview_max_chars
tool_output_preview_max_charsint | nullnullPer-category cap for tool result previews; null = preview_max_chars
llm_input_preview_max_charsint | nullnullPer-category cap for LLM input previews; null = preview_max_chars
llm_output_preview_max_charsint | nullnullPer-category cap for LLM output previews; null = preview_max_chars
headersmap(unset)Extra HTTP headers on every OTLP request; per-backend headers: are merged onto these
global_tagsmap(unset)Merged into the OTel Resource; overridden by resource_attributes on key conflict
resource_attributesmap(unset)Merged into the Resource on top of the defaults service.name=hermes-agent, service.instance.id (per-process UUID), service.version, process.pid
project_namestring | null(unset)openinference.project.name on the Resource (Phoenix project); overrides OTEL_PROJECT_NAME
span_batch_max_queue_sizeint2048Max buffered spans per backend before drops
span_batch_schedule_delay_msint1000BatchSpanProcessor worker wake-up cadence
span_batch_max_export_batch_sizeint512Max spans per OTLP POST
span_batch_export_timeout_msint30000Per-export HTTP timeout
force_flush_on_session_endbooltrueSynchronously flush every backend at the end of each turn
capture_conversation_historyboolfalseAttach the full message JSON to llm.* spans
conversation_history_max_charsint20000JSON cap when conversation capture is on
capture_full_promptsboolfalseFull-fidelity prompt capture (llm.input_messages, gen_ai.input.messages); respects capture_previews
capture_full_responsesboolfalseFull-fidelity response capture (llm.output.content, gen_ai.output.messages)
capture_sender_idboolfalseGateway sessions add hermes.sender.id and user.id (platform:sender)
capture_logsboolfalseAttach an OTel LoggingHandler to Python logging; see OTel logs
log_levelstring"INFO"Handler level: DEBUG / INFO / WARNING / ERROR / CRITICAL
log_attach_loggerstring | null(unset)Logger to attach to; null = root, hermes_otel = the plugin only
emit_genai_metricsbooltrueAlso emit the OTel GenAI spec metrics (gen_ai.client.*, gen_ai.agent.*)
skill_spansbooltrueOpen a skill.<name> span on each successful skill load, closed at turn end
discovery_promptboolfalseRegister a system-prompt section advertising hermes_otel:observability (changes what the model sees every turn; opt-in)
dashboard_livebooltrueKeep recent spans/metrics/logs in $HERMES_HOME/hermes_otel_live.db for the dashboard's Live mode
dashboard_live_max_spansint1000Rows kept per kind (spans, metrics, logs) in the live store
host_metricsboolfalseSample CPU/GPU and emit process.* / system.* / hw.* metrics; see Host & GPU metrics
host_metrics_gpustring"auto"auto · amd · nvidia · off — which GPU SDK to probe
host_metrics_interval_msint1000Host sampling cadence (floor 50 ms)
suppress_mcp_ping_spansbooltrueDrop successful MCP keepalive ping spans before export
backendslist(unset)Multi-backend fan-out list; see the backends[] section

When backends: is present and non-empty, single-backend env-var detection is skipped.

backends[] entries

Shared fields (all optional unless noted):

FieldTypeDescription
typestringRequired. One of: phoenix, langfuse, signoz, jaeger, tempo, otlp, lgtm, uptrace, openobserve, parseable, honeycomb, weave. (LangSmith is env-var only — LANGSMITH_TRACING=true; it is not an OTLP backend.)
namestringFriendly name shown in logs (default: type)
endpointstringFull OTLP traces endpoint URL. Required for every type except langfuse (built from base_url), honeycomb (built from region) and weave (built from base_url)
tracesboolOverride trace-export default (true). Set false for dashboard/query-only backends that should not receive span exports. trace is accepted as an alias.
metricsboolOverride metrics-export default for this backend
logsboolOverride logs-export default (on for signoz, otlp, lgtm, uptrace, openobserve, parseable, honeycomb; off elsewhere)
headersmapPer-backend HTTP headers (merged onto top-level headers)

Type-specific fields

phoenix

FieldTypeDescription
endpointstringRequired. e.g. http://localhost:6006/v1/traces. Traces only (Phoenix rejects /v1/metrics)

langfuse

FieldTypeDescription
public_keystringLangfuse public key (inline; discouraged)
public_key_envstringEnv var name holding the public key
secret_keystringLangfuse secret key (inline; discouraged)
secret_key_envstringEnv var name holding the secret key
base_urlstringLangfuse base URL (e.g. https://cloud.langfuse.com); the plugin appends /api/public/otel/v1/traces
endpointstringOverride; skips base_url construction

Basic Auth header is constructed automatically from public + secret keys.

signoz

FieldTypeDescription
endpointstringOTLP endpoint (self-host: http://localhost:4328/v1/traces; cloud: https://ingest.<region>.signoz.cloud:443/v1/traces)
ingestion_keystringSigNoz Cloud ingestion key (inline; discouraged)
ingestion_key_envstringEnv var name holding the ingestion key

When an ingestion key is set, the plugin adds the signoz-ingestion-key header.

jaeger

FieldTypeDescription
endpointstringRequired. e.g. http://localhost:4318/v1/traces. Traces only (metrics/logs off)

tempo

FieldTypeDescription
endpointstringRequired. Traces only (metrics/logs off); use type: lgtm for the all-in-one Grafana container

otlp

FieldTypeDescription
endpointstringRequired. OTLP traces endpoint
metricsboolDefault: true; set false for traces-only collectors
logsboolDefault: true; set false if the collector doesn't accept /v1/logs

Use headers: for auth (${VAR} interpolation supported).

lgtm

Alias over otlp with a dedicated display name and all signals on by default. See Grafana LGTM.

FieldTypeDescription
endpointstringRequired. OTLP traces endpoint — http://localhost:4318/v1/traces for the bundled docker-compose/lgtm.yaml
metricsboolDefault: true
logsboolDefault: true

Use type: lgtm (not type: tempo) when pointing at the grafana/otel-lgtm container — tempo is traces-only and would disable the logs/metrics fan-out.

uptrace

FieldTypeDescription
endpointstringRequired. OTLP traces endpoint (self-host: http://localhost:14318/v1/traces). Also via OTEL_UPTRACE_ENDPOINT
dsnstringUptrace DSN, sent as the uptrace-dsn header on every export (inline; discouraged)
dsn_envstringEnv var name holding the DSN (falls back to OTEL_UPTRACE_DSN / UPTRACE_DSN)

All three signals on by default. See Uptrace.

openobserve

FieldTypeDescription
endpointstringRequired. http://<host>:5080/api/<org>/v1/traces. Also via OTEL_OPENOBSERVE_ENDPOINT
user / user_envstringBasic-auth user (falls back to OTEL_OPENOBSERVE_USER / OPENOBSERVE_USER)
password / password_envstringBasic-auth password (falls back to OTEL_OPENOBSERVE_PASSWORD / OPENOBSERVE_PASSWORD)
stream_namestringOptional stream name (OTEL_OPENOBSERVE_STREAM)

All three signals on by default. See OpenObserve.

parseable

FieldTypeDescription
endpointstringRequired. Parseable ingestor OTLP traces endpoint, ending in /v1/traces
api_keystringParseable API key (inline; discouraged)
api_key_envstringEnv var holding the key (falls back to PARSEABLE_API_KEY / OTEL_PARSEABLE_API_KEY)
traces_datasetstringTraces dataset (default: hermes-traces)
metrics_datasetstringMetrics dataset (default: hermes-metrics)
logs_datasetstringLogs dataset (default: hermes-logs)

The plugin supplies signal-specific X-P-Stream and X-P-Log-Source headers automatically. See Parseable.

honeycomb

FieldTypeDescription
api_keystringHoneycomb ingest key (inline; discouraged)
api_key_envstringEnv var name holding the key (falls back to HONEYCOMB_API_KEY / OTEL_HONEYCOMB_API_KEY)
regionstringus (default) or eu; selects the endpoint when none is given
datasetstringOptional x-honeycomb-dataset header. Only honored by Classic keys — modern Environments keys ignore it
endpointstringOverride; skips the region default. Also via OTEL_HONEYCOMB_ENDPOINT

The plugin sets x-honeycomb-team from the key automatically and enables all three signals. See Honeycomb for dataset routing details.

weave

FieldTypeDescription
api_keystringW&B API key (inline; discouraged)
api_key_envstringEnv var name holding the key (falls back to WANDB_API_KEY)
entitystringW&B entity/team; copied to Resource attribute wandb.entity
entity_envstringEnv var name holding the entity (falls back to WANDB_ENTITY / DEFAULT_WANDB_ENTITY)
projectstringW&B project; copied to Resource attribute wandb.project
project_envstringEnv var name holding the project (falls back to WANDB_PROJECT / DEFAULT_WANDB_PROJECT)
base_urlstringW&B base URL. Cloud default is https://trace.wandb.ai; Dedicated Cloud / Self-Managed hosts such as https://acme.wandb.io get /traces/otel/v1/traces appended
endpointstringOverride; skips base_url construction. Also via OTEL_WEAVE_ENDPOINT / WANDB_OTLP_ENDPOINT

The plugin sets the wandb-api-key header automatically. Weave is traces-only by default; set metrics: true / logs: true only if W&B documents ingest for those signals or you are pointing at a compatible collector. wandb.entity and wandb.project may also be supplied via top-level resource_attributes; conflicting values fail startup.

Env var interpolation in headers:

Inside any headers: value — and any other string field of a backends: entry, such as api_key, dsn, password or endpoint${VAR_NAME} is replaced with the env var's value when the config is loaded:

headers:
Authorization: "Bearer ${OTEL_AUTH_TOKEN}"
x-honeycomb-team: ${HONEYCOMB_API_KEY}

Missing env vars result in a startup warning and the literal ${VAR} being sent (which will fail auth, but visibly so).

Precedence

For every field, precedence (highest → lowest) is:

  1. HERMES_OTEL_* env var (if applicable — see Env var reference)
  2. config.yaml value
  3. Built-in default

Validation

On startup the plugin validates the config and:

  • Logs a warning naming the key and keeps the default for a value that cannot be parsed as the field's type (yaml or HERMES_OTEL_* env var)
  • Logs a single warning and uses an empty config if the YAML fails to parse
  • Logs a warning and ignores the file if it exists but pyyaml is not installed in the Hermes venv
  • Logs a warning and skips a backends: entry it cannot resolve (missing endpoint, unknown type)

The plugin never crashes Hermes because of config — at worst it disables itself with a clear log line.