---
title: Logging
description: How Octopus initializes logging — levels, JSON/text format, and the precedence of config vs the --log-level flag.
---

# Logging

Octopus logs through the [`tracing`](https://docs.rs/tracing) crate with a
`tracing_subscriber` formatting layer, writing to the process's standard output.

## How logging is initialized

When you run `octopus serve`, the CLI loads the configuration **first** and then
initializes the subscriber from `observability.logging`, so the configured level
and format take effect. The subscriber installs:

- a **formatting layer** — text (default) or JSON lines (`format: json`); the
  per-event target is suppressed;
- an **`EnvFilter`** seeded from the resolved level, with a built-in directive
  that quiets noisy `mdns_sd` library logs to `warn` and above.

## Level

The effective level is resolved with this precedence:

1. the `serve` command's `--log-level` flag, if given;
2. otherwise `observability.logging.level` from the config;
3. otherwise `info`.

`RUST_LOG` layers on top via `EnvFilter` (per-module directives supported).

```bash
# From config (observability.logging.level)
octopus serve -c gateway.yaml

# Override the level for one run
octopus serve -c gateway.yaml --log-level debug

# RUST_LOG directives (per-module overrides)
RUST_LOG=octopus_proxy=trace,info octopus serve -c gateway.yaml
```

Accepted values are `trace`, `debug`, `info`, `warn`, and `error`; an unrecognized
value falls back to `info`.

## Format

| Field | Type | Default | Effect |
| --- | --- | --- | --- |
| `observability.logging.level` | string | `info` | Sets the base level (the `--log-level` flag overrides it). |
| `observability.logging.format` | string (`json` \| `text`) | `text` | `json` installs the JSON-lines formatter; anything else uses the human-readable text formatter. |

```yaml
observability:
  logging:
    level: info
    format: json # structured JSON lines
```

<Callout type="info">
  `--log-level` overrides only the level, not the format. The format always comes
  from `observability.logging.format`.
</Callout>

## What gets logged

The gateway emits `tracing` events across its components — request handling,
proxying, health checks, discovery syncs, lifecycle transitions, and admin
actions. Raising the level to `debug` or `trace` surfaces per-request path/method
logging in the request handler.

## Related

- [Tracing](/docs/octopus/observability/tracing) — distributed tracing status.
- [Configuration → Observability](/docs/octopus/configuration/observability) — the `logging` block schema.
