|
| 1 | +--- |
| 2 | +title: JSON logging |
| 3 | +sidebar_position: 25 |
| 4 | +--- |
| 5 | + |
| 6 | +# Logging (JSON) |
| 7 | + |
| 8 | +This page documents the structured JSON log format emitted when the `FELDERA_LOG_JSON` environment variable is set (for example, `FELDERA_LOG_JSON=1`). The default pretty text logs are unchanged. Logs come from two sources: |
| 9 | + |
| 10 | +- Control plane components (manager, runner, compiler-server, kubernetes-runner, control-plane): these carry `feldera-service` set to the component name. |
| 11 | +- Pipelines (the dataflow processes): these carry `feldera-service: "pipeline"` and `pipeline-name`/`pipeline-id`. Control plane logs that are about a specific pipeline also include the pipeline identifiers. |
| 12 | + |
| 13 | +## Identity fields |
| 14 | + |
| 15 | +These identity fields are lifted alongside the standard top-level metadata (`timestamp`, `level`, `target`): |
| 16 | + |
| 17 | +| Field | Meaning | |
| 18 | +| ------------------ | -------------------------------------------------------------------------------- | |
| 19 | +| `feldera-service` | Source: `manager` \| `runner` \| `compiler-server` \| `kubernetes-runner` \| `control-plane` \| `pipeline` (auto-tagged by module path). This identifies which Feldera component produced the log. | |
| 20 | +| `pipeline-name` | Human-friendly pipeline name when available; if it is not immediately available it is set to `N/A`. Present for pipeline events. Control plane events tied to a specific pipeline also include this name. | |
| 21 | +| `pipeline-id` | Pipeline UUID when the event relates to a specific pipeline. Present for pipeline events. Control plane events tied to a specific pipeline also include this ID. | |
| 22 | + |
| 23 | +## JSON object members (spec) |
| 24 | + |
| 25 | +Each log entry is a JSON object whose members are: |
| 26 | + |
| 27 | +- `timestamp` (required): string value, UTC with microsecond precision (e.g. `2025-12-06T02:08:14.902292Z`). |
| 28 | +- `level` (required): string value, one of `TRACE` \| `DEBUG` \| `INFO` \| `WARN` \| `ERROR`. |
| 29 | +- `target` (required): string value, Rust module path of the log source. |
| 30 | +- `fields` (required): object value containing the event payload (one of `message` or `line`). |
| 31 | +- `feldera-service` (optional): string value, present for control plane events and for pipelines (as `pipeline`). |
| 32 | +- `pipeline-name` (optional): string value, present when the event is tied to a pipeline. |
| 33 | +- `pipeline-id` (optional): string value, present when the event is tied to a pipeline. |
| 34 | + |
| 35 | +> Practical rule: every log line has `timestamp`, `level`, `target`, and `fields`. Control plane logs add `feldera-service`; pipeline-related logs add `feldera-service: "pipeline"` plus `pipeline-name` and `pipeline-id`. |
| 36 | +
|
| 37 | +## Examples |
| 38 | + |
| 39 | +Manager pipeline lifecycle: |
| 40 | + |
| 41 | +```json |
| 42 | +{ |
| 43 | + "timestamp": "2025-12-05T18:54:07.231095Z", |
| 44 | + "level": "INFO", |
| 45 | + "target": "pipeline_manager::api::endpoints::pipeline_management", |
| 46 | + "feldera-service": "manager", |
| 47 | + "pipeline-name": "MyPipeline", |
| 48 | + "pipeline-id": "019af011-5282-7751-98c2-f61478d0df63", |
| 49 | + "fields": { |
| 50 | + "message": "Created pipeline \"MyPipeline\" (019af011-5282-7751-98c2-f61478d0df63) (tenant: 00000000-0000-0000-0000-000000000000)" |
| 51 | + } |
| 52 | +} |
| 53 | +``` |
| 54 | + |
| 55 | +Runner log stream starting up: |
| 56 | + |
| 57 | +```json |
| 58 | +{ |
| 59 | + "timestamp": "2025-12-06T02:08:14.902292Z", |
| 60 | + "level": "INFO", |
| 61 | + "target": "pipeline_manager::runner::pipeline_logs", |
| 62 | + "feldera-service": "runner", |
| 63 | + "pipeline-name": "N/A", |
| 64 | + "pipeline-id": "019af16a-ba26-7933-a6e5-65d9d717cb7a", |
| 65 | + "fields": { "line": "Fresh start of pipeline logs" } |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +Compiler server log: |
| 70 | + |
| 71 | +```json |
| 72 | +{ |
| 73 | + "timestamp": "2025-12-05T18:01:22.996459Z", |
| 74 | + "level": "INFO", |
| 75 | + "target": "pipeline_manager::compiler::sql_compiler", |
| 76 | + "feldera-service": "compiler-server", |
| 77 | + "pipeline-name": "MyPipeline", |
| 78 | + "pipeline-id": "019aefac-fc78-75b0-9089-0f7496f8ac1f", |
| 79 | + "fields": { "message": "SQL compilation started: pipeline 019aefac-fc78-75b0-9089-0f7496f8ac1f (program version: 1)" } |
| 80 | +} |
| 81 | +``` |
| 82 | + |
| 83 | +Pipeline log: |
| 84 | + |
| 85 | +```json |
| 86 | +{ |
| 87 | + "timestamp": "2025-12-09T21:26:17.362514Z", |
| 88 | + "level": "INFO", |
| 89 | + "target": "dbsp_adapters::server", |
| 90 | + "feldera-service": "pipeline", |
| 91 | + "pipeline-name": "MyPipeline", |
| 92 | + "pipeline-id": "019af16a-ba26-7933-a6e5-65d9d717cb7a", |
| 93 | + "fields": { "message": "Pipeline initialization complete" } |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +## Example: enabling JSON |
| 98 | + |
| 99 | +```bash |
| 100 | +FELDERA_LOG_JSON=1 cargo run --bin=pipeline-manager |
| 101 | +``` |
| 102 | + |
| 103 | +## Notes |
| 104 | + |
| 105 | +- Plain-text logging remains the default; JSON is opt-in via `FELDERA_LOG_JSON`. |
| 106 | +- The event payload lives under `fields` (`message` or `line`); identity fields (`feldera-service`, `pipeline-name`, `pipeline-id`) are at the top level. |
0 commit comments