Skip to main content
ONR access logs support an nginx-like format string via logging.access_log_format (or logging.access_log_format_preset).

Formatting rules

  • Variables are referenced as $name (example: $status).
  • If a variable is missing or empty, ONR prints - at that position.
  • $$ renders a literal $.

Configuration

In onr.yaml:
logging:
  access_log: true
  access_log_path: ""            # empty = stdout
  access_log_format: ""          # non-empty overrides preset
  access_log_format_preset: ""   # onr_combined | onr_minimal
  access_log_rotate:
    enabled: false
    max_size_mb: 100
    max_backups: 14
    max_age_days: 14
    compress: false
Rotation notes:
  • Rotation only applies when access_log_path is non-empty (file output).
  • When access_log_rotate.enabled=true, access_log_path is required.
  • Rotation triggers on either day boundary (local time) or size threshold.
  • Archive file pattern: <access_log_path>.YYYYMMDD-HHMMSS.NNNNNNNNN (or .gz when compress=true).
Rotation knobs:
  • max_size_mb: rotate when the next write would exceed this file size.
  • max_backups: keep only the newest N archives.
  • max_age_days: remove archives older than N days; 0 disables age-based cleanup.
  • compress: gzip archive files after rotation.
Daily-first setup example:
logging:
  access_log: true
  access_log_path: "./logs/access.log"
  access_log_rotate:
    enabled: true
    max_size_mb: 102400   # keep very large if you want day-boundary rotation to dominate
    max_backups: 14
    max_age_days: 14
    compress: false
Note:
  • Current behavior is day-boundary OR size-threshold (not an exclusive mode switch).

Field reference

Request line fields
VariableMeaning
$time_localTimestamp formatted as YYYY/MM/DD - HH:MM:SS.
$statusDownstream HTTP status code returned to the client.
$latencyEnd-to-end request latency as a Go duration string (example: 123ms, 1.2s).
$latency_msEnd-to-end request latency in milliseconds. If proxy result latency is available, ONR may use it.
$client_ipClient IP as seen by the server.
$methodDownstream HTTP method (example: GET, POST).
$pathDownstream request path (URL path only, without query string).
Identity and routing
VariableMeaning
$request_idRequest ID used for tracing.
$appnameClient app name for observability. Resolved from appname header or (optional) inferred from User-Agent.
$providerSelected provider name (from DSL selection and routing).
$provider_sourceProvider selection source (for example: forced header vs models routing).
$apiNormalized API category (example: chat.completions).
$streamWhether the request is treated as streaming (true/false) when available.
$modelRequested/selected model.
Usage and cost
VariableMeaning
$usage_stageWhere usage data comes from (for example upstream-provided vs best-effort estimation).
$input_tokensInput tokens.
$output_tokensOutput tokens.
$total_tokensTotal tokens.
$cache_read_tokensCache read tokens (when available).
$cache_write_tokensCache write tokens (when available).
$cost_totalTotal cost.
$cost_inputInput cost.
$cost_outputOutput cost.
$cost_cache_readCache read cost (when available).
$cost_cache_writeCache write cost (when available).
$billable_input_tokensBillable input tokens (after provider-specific adjustments).
$cost_multiplierEffective multiplier applied to pricing (if configured).
$cost_modelPricing model used for cost calculation.
$cost_channelChannel identifier used for cost attribution (if available).
$cost_unitCost unit (implementation-defined; depends on pricing config).
Flat usage extras:
  • When usage_extract custom; uses usage_fact ... with non-legacy detail, ONR also emits flattened usage fields into the access log.
  • These keys are appended directly as normal log variables and follow a snake_case convention derived from dimension + attributes + unit.
  • Legacy scalar usage stays unchanged: input_tokens, output_tokens, total_tokens, cache_read_tokens, cache_write_tokens.
  • Typical examples:
    • $cache_write_ttl_5m_tokens
    • $cache_write_ttl_1h_tokens
    • $server_tool_web_search_calls
    • $image_generate_images
    • $image_edit_images
    • $audio_tts_seconds
    • $audio_stt_seconds
    • $audio_translate_seconds
  • For Anthropic non-stream /v1/messages, cache_write token attr.ttl="5m" and attr.ttl="1h" can therefore appear both as:
    • $cache_write_tokens
    • $cache_write_ttl_5m_tokens
    • $cache_write_ttl_1h_tokens
  • The same flattening applies to canonical image/audio/tool facts extracted by ONR or produced by API-specific OpenAI presets such as openai_responses, openai_images_generations, or openai_audio_speech, for example:
    • image.generate image
    • image.edit image
    • audio.tts second
    • audio.stt second
    • audio.translate second
  • These flattened keys are only present when the corresponding usage_fact matched or was produced with quantity 0 from an upstream response that included the field.
Upstream and streaming performance
VariableMeaning
$upstream_statusUpstream HTTP status code (when an upstream request was made).
$finish_reasonNormalized finish reason when extractable.
$ttft_msTime-to-first-token in milliseconds (streaming).
$tpsTokens per second (streaming), best-effort.