Skip to content

Commit 1706cf9

Browse files
committed
docs(logging): Improve clarity and consistency in logging guides
1 parent 437c6de commit 1706cf9

3 files changed

Lines changed: 124 additions & 99 deletions

File tree

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,24 @@
1-
# Developer guide: Writing logs
1+
# Developer guide: writing logs
22

33
This guide provides language-specific setup instructions and standards for initializing loggers and
44
emitting diagnostic logs when developing or modifying CLP components.
55

66
:::{note}
7-
Always prefer UTC service timestamps. Time zone conversions should be handled
8-
downstream in log viewers or aggregation systems.
7+
Always prefer UTC service timestamps. Time zone conversions should be handled downstream in log
8+
viewers or aggregation systems.
99
:::
1010

1111
## Python
1212

13-
New Python orchestration services should use `structlog` for structured JSON logging
14-
and bind context variables where appropriate.
13+
New Python orchestration services should use `structlog` for structured JSON logging and bind
14+
context variables where appropriate.
1515

16-
```python
17-
from clp_py_utils.clp_logging import get_structlog_logger
16+
```python
17+
from clp_py_utils.clp_logging import get_structlog_logger
1818

19-
log = get_structlog_logger("service_name")
20-
log.info("hello, %s!", "world")
21-
```
19+
log = get_structlog_logger("service_name")
20+
log.info("hello, %s!", "world")
21+
```
2222

2323
:::{note}
2424
Existing Python services use stdlib loggers whose handlers are configured with structlog's
@@ -28,43 +28,43 @@ Existing Python services use stdlib loggers whose handlers are configured with s
2828
## Rust
2929

3030
New Rust HTTP services should initialize `tracing` at process startup using
31-
[`clp_rust_utils::logging::set_up_logging`][clp-rust-logging] and keep the returned guard alive
32-
for the lifetime of the process:
31+
[`clp_rust_utils::logging::set_up_logging`][clp-rust-logging] and keep the returned guard alive
32+
for the lifetime of the process:
3333

34-
```rust
35-
let _guard = clp_rust_utils::logging::set_up_logging("service_name.log");
34+
```rust
35+
let _guard = clp_rust_utils::logging::set_up_logging("service_name.log");
3636

37-
// Choose structured logging over formatting values directly into the message field.
38-
tracing::info!(server_address = %addr, "Server started.");
39-
```
37+
// Choose structured logging over formatting values directly into the message field.
38+
tracing::info!(server_address = %addr, "Server started.");
39+
```
4040

4141
## WebUI
4242

43-
WebUI server code should use Fastify's Pino logger. Use `request.log` for request-scoped
44-
logs and `app.log` for startup, shutdown, and application-level logs:
43+
WebUI server code should use Fastify's Pino logger. Use `request.log` for request-scoped logs and
44+
`app.log` for startup, shutdown, and application-level logs:
4545

46-
```typescript
47-
// Request-scoped
48-
request.log.info({searchJobId}, "Search submitted");
49-
request.log.error(err, "Failed to submit search");
46+
```typescript
47+
// Request-scoped
48+
request.log.info({searchJobId}, "Search submitted");
49+
request.log.error(err, "Failed to submit search");
5050

51-
// Application-scoped
52-
app.log.info("WebUI server listening on port 3000");
53-
```
51+
// Application-scoped
52+
app.log.info("WebUI server listening on port 3000");
53+
```
5454

5555
WebUI client code should use `console.*` for browser diagnostics:
5656

57-
```typescript
58-
console.error("Failed to submit query:", err);
59-
```
57+
```typescript
58+
console.error("Failed to submit query:", err);
59+
```
6060

6161
## Core and setup tools
6262

6363
* Native core binaries (`clp`, `clp-s`, `glt`, native `reducer_server`) should continue using
6464
[`spdlog`][spdlog] and the `spdlog` initialization already defined in each binary's startup code.
6565
* Package/setup tools (DB initialization scripts, package controllers) should use the
66-
[standard Python logger][stdlogger].
66+
[standard Python logger][std-logger].
6767

6868
[clp-rust-logging]: https://github.com/y-scope/clp/blob/DOCS_VAR_CLP_GIT_REF/components/clp-rust-utils/src/logging.rs
6969
[spdlog]: https://github.com/gabime/spdlog
70-
[stdlogger]: https://docs.python.org/3/library/logging.html
70+
[std-logger]: https://docs.python.org/3/library/logging.html

docs/src/dev-docs/logging-operator-guide.md

Lines changed: 86 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,71 @@
1-
# Operator guide: Consuming CLP logs
2-
3-
This guide details how to configure internal log levels, capture service logs,
4-
and understand the component-specific log structures emitted by a running CLP deployment.
5-
The table below provides a high-level overview of the logging behaviors
6-
across all component families:
7-
8-
| Component family | Components | Logger | Format | Level control |
9-
|-------------------------------|---------------------------------------------------------------------|-----------------------------------------------------------|----------------------------------|----------------------------|
10-
| Python orchestration services | `compression_scheduler`, `query_scheduler`, `compression_worker`, `query_worker`, `reducer`, `garbage_collector`, `mcp_server` | [`structlog` with stdlib logging compatibility][clp-py-logging] | JSON | `CLP_LOGGING_LEVEL` |
11-
| Rust HTTP services | `api_server`, `log_ingestor` | [`clp_rust_utils::logging`][clp-rust-logging] / `tracing` | JSON | `RUST_LOG` |
12-
| WebUI server | Fastify server | [Fastify/Pino][pino] | JSON or pretty text | `LOG_LEVEL` |
13-
| WebUI client | Browser app | Browser console | Browser console output | Browser/devtools dependent |
14-
| Native core binaries | `clp`, `clp-s`, `glt`, native `reducer_server` | `spdlog` | Text | Binary-specific |
15-
| Package/setup tools | Package controller, DB initialization scripts | Python stdlib logging | Text | Script-specific |
1+
# Operator guide: consuming CLP logs
2+
3+
This guide details how to configure internal log levels, capture service logs, and understand the
4+
component-specific log structures emitted by a running CLP deployment. The table below provides a
5+
high-level overview of the logging behaviors across all component families:
6+
7+
| Component family | Components | Logger | Format | Level control |
8+
|-------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|------------------------|----------------------------|
9+
| Python orchestration services | `compression_scheduler`, `query_scheduler`, `compression_worker`, `query_worker`, `reducer`, `garbage_collector`, `mcp_server` | [`structlog` with stdlib logging compatibility][clp-py-logging] | JSON | `CLP_LOGGING_LEVEL` |
10+
| Rust HTTP services | `api_server`, `log_ingestor` | [`clp_rust_utils::logging`][clp-rust-logging] / `tracing` | JSON | `RUST_LOG` |
11+
| WebUI server | Fastify server | [Fastify/Pino][pino] | JSON or pretty text | `LOG_LEVEL` |
12+
| WebUI client | Browser app | Browser console | Browser console output | Browser/devtools dependent |
13+
| Native core binaries | `clp`, `clp-s`, `glt`, native `reducer_server` | `spdlog` | Text | Binary-specific |
14+
| Package/setup tools | Package controller, DB initialization scripts | Python stdlib logging | Text | Script-specific |
1615

1716
## Log level configuration
1817

19-
This section covers how to modify logging verbosity for different components.
20-
Use the following environment variables and settings to filter
21-
logs for each component family:
18+
This section covers how to modify logging verbosity for different components. Use the following
19+
environment variables and settings to filter logs for each component family:
2220

23-
* **Python orchestration services**: `CLP_LOGGING_LEVEL` supports `DEBUG`, `INFO`, `WARN`, `WARNING`, `ERROR`, and `CRITICAL`.
24-
Missing or invalid values default to `INFO`.
21+
* **Python orchestration services**: `CLP_LOGGING_LEVEL` supports `DEBUG`, `INFO`, `WARN`,
22+
`WARNING`, `ERROR`, and `CRITICAL`. Missing or invalid values default to `INFO`.
2523
* **Rust HTTP services**: Configure log filtering with [tracing_subscriber::EnvFilter][EnvFilter].
2624
Filter directives are read from the `RUST_LOG` environment variable to determine which spans and
2725
events are enabled.
28-
* *`log-ingestor`*: Log level is exposed via `CLP_LOG_INGESTOR_LOGGING_LEVEL`
29-
(Docker Compose) or `clpConfig.log_ingestor.logging_level` (Helm), which is
30-
then passed to `RUST_LOG`.
31-
* *`api-server`*: Log level is hardcoded to `INFO` and does not expose a deployment
32-
variable for configuration.
26+
* *`log-ingestor`*: Log level is exposed via `CLP_LOG_INGESTOR_LOGGING_LEVEL` (Docker Compose)
27+
or `clpConfig.log_ingestor.logging_level` (Helm), which is then passed to `RUST_LOG`.
28+
* *`api-server`*: Log level is hardcoded to `INFO` and does not expose a deployment variable
29+
for configuration.
3330
* **WebUI**: `LOG_LEVEL` controls the Pino server log level (defaults to `info`).
34-
:::{warning}
35-
`LOG_LEVEL` is a generic environment variable. Be mindful of environment
36-
variable collisions with other tools or container settings.
37-
:::
31+
32+
:::{warning}
33+
`LOG_LEVEL` is a generic environment variable. Be mindful of environment
34+
variable collisions with other tools or container settings.
35+
:::
3836

3937
## Log routing and collection
4038

41-
Access to CLP package logs is entirely dependent on where the component is executed.
39+
Access to the CLP Package logs is entirely dependent on where the component is executed.
4240

4341
### Containerized services
4442

4543
For continuously running deployed services such as Python orchestration services, Rust HTTP services, and WebUI server, log routing depends on the orchestrator:
4644

4745
* **Docker Compose**: Logs are available using `docker compose logs`. If `CLP_LOGS_DIR` is set,
4846
logs are additionally written to `<CLP_LOGS_DIR>/<component_name>.log`. This directory mounts to the host via `CLP_LOGS_DIR_HOST` (defaults to `./var/log`).
49-
:::{note}
50-
For Rust services, setting `CLP_LOGS_DIR` enables file logging with hourly log rotation and a
51-
non-blocking file writer.
52-
:::
53-
* **Kubernetes/Helm**: Logs are accessible using `kubectl logs` or a cluster log collector (e.g., Fluent Bit).
54-
File logging is only enabled for templates that set `CLP_LOGS_DIR` and mount a log volume.
47+
:::{note}
48+
For Rust services, setting `CLP_LOGS_DIR` enables file logging with hourly log rotation and a
49+
non-blocking file writer.
50+
:::
51+
* **Kubernetes/Helm**: Logs are accessible using `kubectl logs` or a cluster log collector (e.g., Fluent Bit). File
52+
logging is only enabled for templates that set `CLP_LOGS_DIR` and mount a log volume.
5553

5654
### Standalone tools
5755

5856
* **Core binaries**: Running standalone binaries (`clp`, `clp-s`, etc.) emits
59-
unstructured `spdlog` text to `stdout`.
60-
:::{note}
61-
*When deployed*, Python orchestration services invoke these binaries as subprocesses.
62-
Consequently, the core binaries' unstructured log text is captured and written to the
63-
Python logger's output stream as a single multi-line JSON record. These appear alongside
64-
normal container logs in Docker or Kubernetes.
65-
:::
57+
unstructured `spdlog` text to `stdout`.
58+
:::{note}
59+
*When deployed*, Python orchestration services invoke these binaries as subprocesses.
60+
Consequently, the core binaries' unstructured log text is captured and written to the Python
61+
logger's output stream as a single multi-line JSON record. These appear alongside normal container
62+
logs in Docker or Kubernetes.
63+
:::
6664
* **WebUI client**: WebUI client (`console.*`) logs remain local to the user's browser devtools
67-
and are *not* captured by any backend telemetry service. They should be treated
68-
purely as local diagnostics.
69-
* **Package scripts**: Package controller commands and one-shot
70-
setup scripts emit unstructured Python stdlib logs to `stdout`.
65+
and are *not* captured by any backend telemetry service. They should be treated purely as local
66+
diagnostics.
67+
* **Package scripts**: Package controller commands and one-shot setup scripts emit unstructured
68+
Python stdlib logs to `stdout`.
7169

7270
## Component-specific log schemas
7371

@@ -96,39 +94,53 @@ record. Each record includes the following fields:
9694

9795
Example:
9896

99-
<!-- markdownlint-disable MD013 -->
10097
```json
101-
{"timestamp":"2026-06-22T17:03:21.123456Z","event":"Compression job 1 submitted.","logger":"compression_scheduler","level":"info","filename":"compression_scheduler.py","func_name":"main","lineno":616}
98+
{
99+
"timestamp": "2026-06-22T17:03:21.123456Z",
100+
"event": "Compression job 1 submitted.",
101+
"logger": "compression_scheduler",
102+
"level": "info",
103+
"filename": "compression_scheduler.py",
104+
"func_name": "main",
105+
"lineno": 616
106+
}
102107
```
103-
<!-- markdownlint-enable MD013 -->
104108

105109
### Rust HTTP services
106110

107111
These services use [`clp_rust_utils::logging::set_up_logging`][clp-rust-logging], which configures
108112
`tracing_subscriber` to emit one JSON object per log record. Each record includes the following
109113
fields:
110114

111-
| Field | Description |
112-
|---------------|------------------------------------------------------------|
113-
| `timestamp` | Timestamp emitted by `tracing_subscriber`. |
115+
| Field | Description |
116+
|---------------|-------------------------------------------------------------------|
117+
| `timestamp` | Timestamp emitted by `tracing_subscriber`. |
114118
| `level` | Log level, emitted as values such as `INFO`, `WARN`, and `ERROR`. |
115-
| `fields` | Structured `tracing` fields, including the log message. |
116-
| `filename` | Source filename for the log call. |
117-
| `line_number` | Source line number for the log call. |
119+
| `fields` | Structured `tracing` fields, including the log message. |
120+
| `filename` | Source filename for the log call. |
121+
| `line_number` | Source line number for the log call. |
118122

119123
Example:
120124

121-
<!-- markdownlint-disable MD013 -->
122125
```json
123-
{"timestamp":"2026-06-26T13:06:48.621307","level":"INFO","fields":{"message":"Spawned SQS listener task.","job_id":"3","task_id":"0"},"filename":"components/log-ingestor/src/ingestion_job/sqs_listener.rs","line_number":320}
126+
{
127+
"timestamp": "2026-06-26T13:06:48.621307",
128+
"level": "INFO",
129+
"fields": {
130+
"message": "Spawned SQS listener task.",
131+
"job_id": "3",
132+
"task_id": "0"
133+
},
134+
"filename": "components/log-ingestor/src/ingestion_job/sqs_listener.rs",
135+
"line_number": 320
136+
}
124137
```
125-
<!-- markdownlint-enable MD013 -->
126138

127139
### WebUI server
128140

129141
The WebUI server uses Fastify's Pino logger. When the server runs without an interactive terminal,
130-
such as in Docker Compose or Kubernetes, it emits one JSON object per log record. When `stdout` is an
131-
interactive terminal, it uses `pino-pretty` for human-readable output.
142+
such as in Docker Compose or Kubernetes, it emits one JSON object per log record. When `stdout` is
143+
an interactive terminal, it uses `pino-pretty` for human-readable output.
132144

133145
Each JSON record includes the following fields:
134146

@@ -146,18 +158,28 @@ Each JSON record includes the following fields:
146158

147159
Example:
148160

149-
<!-- markdownlint-disable MD013 -->
150161
```json
151-
{"level":30,"time":1782480774533,"pid":1,"hostname":"webui","reqId":"req-1h","res":{"statusCode":200},"responseTime":1.0457000732421875,"msg":"request completed"}
162+
{
163+
"level": 30,
164+
"time": 1782480774533,
165+
"pid": 1,
166+
"hostname": "webui",
167+
"reqId": "req-1h",
168+
"res": {
169+
"statusCode": 200
170+
},
171+
"responseTime": 1.0457000732421875,
172+
"msg": "request completed"
173+
}
152174
```
153-
<!-- markdownlint-enable MD013 -->
154175

155176
### Core and package tools
156177

157178
Native core binaries emit unstructured `spdlog` text logs. Package controller commands and one-shot
158179
setup scripts also emit unstructured Python stdlib logs. These tools do not follow the JSON log
159180
formats described for Python orchestration services, Rust HTTP services, or the WebUI server.
160181

182+
161183
[clp-py-logging]: https://github.com/y-scope/clp/blob/DOCS_VAR_CLP_GIT_REF/components/clp-py-utils/clp_py_utils/clp_logging.py
162184
[clp-rust-logging]: https://github.com/y-scope/clp/blob/DOCS_VAR_CLP_GIT_REF/components/clp-rust-utils/src/logging.rs
163185
[pino]: https://fastify.dev/docs/v2.15.x/Documentation/Logging/

docs/src/dev-docs/logging.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
# CLP package logging
1+
# CLP Package logging
22

3-
The CLP package utilizes a polyglot architecture, meaning each component family manages its own logging stack. There is **no single project-wide JSON schema**.
3+
The CLP Package utilizes a polyglot architecture, meaning each component family manages its own
4+
logging stack. There is **no single project-wide JSON schema**.
45

56
This document is divided into two sections:
67

7-
* [Developer guide](logging-developer-guide.md): How to set up and write logs when modifying CLP components.
8-
* [Operator guide](logging-operator-guide.md): How to configure log levels, capture service logs, and understand the component-specific log structures in deployment.
8+
* [Developer guide](logging-developer-guide.md): How to set up and write logs when modifying CLP
9+
components.
10+
* [Operator guide](logging-operator-guide.md): How to configure log levels, capture service logs,
11+
and understand the component-specific log structures when deploying CLP package services.
912

1013
:::{toctree}
1114
:hidden:

0 commit comments

Comments
 (0)