> Raw Markdown twin (generated at build time from the source Markdown). Rendered page: https://docs.gatellm.io/en/console/logs-viewer · Doc index: https://docs.gatellm.io/en/llms.txt


# Log viewer

The Logs page shows the complete record of each API request: client request, upstream forwarding, response, and error details. It supports real-time streaming push, persisted storage, and log-body viewing.

Entry: Console → **Logs** (visible to admin and monitor).

For the field reference and environment variables of log-body storage, see [Logs and log-body storage](/en/reference/logs-and-body-storage.md).

## Log list

The list shows recent request records, each containing:

| Field | Description |
|------|------|
| Time | Request timestamp |
| Model | The requested model name; a label may be prepended to the model name to indicate the routing origin (see below) |
| Upstream | The name of the upstream that actually handled the request |
| Path | The endpoint path of the client request (e.g. `/v1/chat/completions`) |
| Status code | The upstream response status code |
| Latency | Total elapsed time (milliseconds) |
| User | Access key name (`anonymous` when unauthenticated) |
| Input Token | prompt token count |
| Output Token | completion token count |

Labels on the model column:

| Label | Meaning |
|------|------|
| `MM` | The request's model name was rewritten by an **identity-scoped model mapping** rule (the access key/group's `model_mappings`). The tooltip shows `original name → mapped name`. If it also hits load balancing or script rerouting, `MM` stacks with the corresponding label |
| `LB` | The request was dispatched to an upstream node via **load balancing** virtual routing |
| `SW` | The request's upstream model was rerouted by the script's `context.useModel()` |

Ordinary requests have no label. `MM` can stack with `LB`/`SW` (`MM` comes first); `LB` and `SW` are mutually exclusive (script rerouting takes priority).

## Log detail

Clicking a log entry expands a detail drawer (the title contains the instance ID that handled the request, making it easy to locate in multi-instance deployments), including the full request/response lifecycle. There is a **Download log** button at the top-right of the drawer that exports this log entry (full request/response text) as a downloadable file (large bodies are formatted by a worker thread, without blocking the page):

| Tab | Contents |
|------|------|
| Overview | Request ID, model, upstream URL, status code, latency, token usage, access key name/group; model mapping / load balancing info bar (shown when hit) |
| Client request | Request headers (sensitive values redacted) + request body |
| Upstream request | Converted request headers + request body (the actual content sent to the upstream) |
| Upstream response | Response status code + response headers + response body |
| Error | Error details on 4xx/5xx (truncated to 512 bytes) |

### Notification

The top of the log detail page shows special notifications for this request, for example:
- **script_use_model_swap (`SW`)**: the request's upstream model was switched by the script via `context.useModel`, not the client's originally requested model. This is an **admin-configured internal reroute**; the target does not pass model access control.

Note that `SW` and the `MM` on the model column are two mechanisms: `MM` means **identity mapping** rewrites the model name the client sent according to the access key/group's mapping rules (see [Identity-scoped model mapping configuration](/en/howto/configure-identity-model-mapping.md)); `SW` means script rerouting. Both can appear on the same request.

## Live logs (SSE stream)

There is a **Live logs switch** at the top-right of the console. When turned on, all requests are pushed to the browser in real time:

- Uses SSE (Server-Sent Events) transport
- Includes all requests (401/429 early failures, internal endpoints, console routes)
- Unauthenticated requests show `user: "anonymous"`
- In multi-instance deployments (Redis mode), aggregates request logs from all instances

With Live off, it polls for refresh; with Live on, it pushes in real time.

## Filtering and search

The Logs page supports the following filtering methods:

| Filter | Description |
|---------|------|
| Time range | Pick start and end times |
| Model | Filter by model name |
| Upstream | Filter by upstream name |
| Path | Filter by request endpoint path |
| Status code | Filter by response status code, syntax below |
| Access key | Filter by key name |
| Search | Search by request ID or other keywords |

**Status-code filter syntax**: not just `2xx/4xx/5xx` — it supports five forms: exact value (`200`), status class (`5xx`), comparison (`>=400`, `>200`), range (`200-299`), negation (`!2xx`). Multiple conditions are separated by spaces or commas; the combination semantics are: positive conditions (without `!`) are combined with **OR**, negative conditions (with `!`) are combined with **AND**, and the two groups are then ANDed. Example: `5xx !500` = 5xx but excluding 500; `200 201` = 200 or 201.

## Request ID correlation

Every request has a unique `z-request-id` header (format `<iso8601>-<uuid4>`); this ID:

- is injected into the request headers before the request enters processing
- is mirrored to the response headers returned to the client
- is forwarded to the upstream as an additional header
- is embedded in all structured log entries

Enter the complete request ID in the Logs page search box to locate a specific request. See [Export billing Excel and log troubleshooting](/en/howto/billing-export-and-logs.md) for details.

## FAQ

**Q: Is the log list real-time?**
After turning on Live, it is real-time push (SSE). With Live off, it polls for refresh.

**Q: Why is the body in the log truncated?**
`logging.max_body_size_mb` limits the captured size of each body (default 25 MB). Large bodies (such as long conversations or large embedding requests) are truncated. Raising this value captures more, but increases memory and disk overhead. See [Logs and log-body storage](/en/reference/logs-and-body-storage.md) for details.

**Q: Where can I see the response body of streaming requests?**
The streaming response body is recorded by a background task after the stream ends. If the stream is interrupted abnormally (client disconnect), the body may be incomplete (marked `body_incomplete`).

**Q: Too many logs and the disk is nearly full — what to do?**
Reduce `log_retention_days` (e.g. 3 days) to speed up cleanup; reduce `stream_body_max_disk_mb` to lower streaming body disk usage. See [Logs and log-body storage](/en/reference/logs-and-body-storage.md) for details.

**Q: Who can view logs?**
The Logs page is visible to admin and monitor. `normal_user` cannot log in to the console, so it cannot see logs (it only has API-key usage rights).

**Q: What is the difference between logs and audit logs?**
Logs (this page) record the request/response of each API call; audit logs ([Audit and security configuration](/en/reference/audit-and-security-config.md)) record console configuration changes (create/delete/modify). The two are complementary.

**Next**: [Statistics](/en/console/statistics.md) for usage statistics; [Logs and log-body storage](/en/reference/logs-and-body-storage.md) for fields and configuration reference; [Overview dashboard](/en/console/overview-dashboard.md) for a global view.
