> ## Documentation Index
> Fetch the complete documentation index at: https://onr.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Access Log Fields

> All supported variables for logging.access_log_format.

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`:

```yaml theme={null}
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:

```yaml theme={null}
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**

| Variable      | Meaning                                                                                           |
| ------------- | ------------------------------------------------------------------------------------------------- |
| `$time_local` | Timestamp formatted as `YYYY/MM/DD - HH:MM:SS`.                                                   |
| `$status`     | Downstream HTTP status code returned to the client.                                               |
| `$latency`    | End-to-end request latency as a Go duration string (example: `123ms`, `1.2s`).                    |
| `$latency_ms` | End-to-end request latency in milliseconds. If proxy result latency is available, ONR may use it. |
| `$client_ip`  | Client IP as seen by the server.                                                                  |
| `$method`     | Downstream HTTP method (example: `GET`, `POST`).                                                  |
| `$path`       | Downstream request path (URL path only, without query string).                                    |

**Identity and routing**

| Variable           | Meaning                                                                                                     |
| ------------------ | ----------------------------------------------------------------------------------------------------------- |
| `$request_id`      | Request ID used for tracing.                                                                                |
| `$appname`         | Client app name for observability. Resolved from `appname` header or (optional) inferred from `User-Agent`. |
| `$provider`        | Selected provider name (from DSL selection and routing).                                                    |
| `$provider_source` | Provider selection source (for example: forced header vs models routing).                                   |
| `$api`             | Normalized API category (example: `chat.completions`).                                                      |
| `$stream`          | Whether the request is treated as streaming (`true`/`false`) when available.                                |
| `$model`           | Requested/selected model.                                                                                   |

**Usage and cost**

| Variable                 | Meaning                                                                                |
| ------------------------ | -------------------------------------------------------------------------------------- |
| `$usage_stage`           | Where usage data comes from (for example upstream-provided vs best-effort estimation). |
| `$input_tokens`          | Input tokens.                                                                          |
| `$output_tokens`         | Output tokens.                                                                         |
| `$total_tokens`          | Total tokens.                                                                          |
| `$cache_read_tokens`     | Cache read tokens (when available).                                                    |
| `$cache_write_tokens`    | Cache write tokens (when available).                                                   |
| `$cost_total`            | Total cost.                                                                            |
| `$cost_input`            | Input cost.                                                                            |
| `$cost_output`           | Output cost.                                                                           |
| `$cost_cache_read`       | Cache read cost (when available).                                                      |
| `$cost_cache_write`      | Cache write cost (when available).                                                     |
| `$billable_input_tokens` | Billable input tokens (after provider-specific adjustments).                           |
| `$cost_multiplier`       | Effective multiplier applied to pricing (if configured).                               |
| `$cost_model`            | Pricing model used for cost calculation.                                               |
| `$cost_channel`          | Channel identifier used for cost attribution (if available).                           |
| `$cost_unit`             | Cost 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**

| Variable           | Meaning                                                        |
| ------------------ | -------------------------------------------------------------- |
| `$upstream_status` | Upstream HTTP status code (when an upstream request was made). |
| `$finish_reason`   | Normalized finish reason when extractable.                     |
| `$ttft_ms`         | Time-to-first-token in milliseconds (streaming).               |
| `$tps`             | Tokens per second (streaming), best-effort.                    |
