Skip to main content
Every call in an iii system passes through the engine. Because every worker communicates through the engine, it can trace work as it moves from one worker to the next, giving you observability across the whole system without each worker instrumenting itself. The automatically supplied iii-observability worker turns that information into OpenTelemetry traces, metrics, and logs. Do not declare it in either config.yaml or worker-compose.yaml.
This page is a quick tour. For the complete configuration and the full list of query functions, see the iii-observability worker docs.

Logging

Logger from the observability SDK sends each log line of your worker to the engine, so the line carries the trace and span of the call that logged it. Each level takes a message and optional structured data. The examples on this page use a link store: links::process appends one link to a store file, and retries the write.

Where the lines go

The engine prints each line in its own output, labeled with the worker’s OpenTelemetry service name (set it with OTEL_SERVICE_NAME), unless the observability worker sets logs_console_output: false. It also stores each line: iii call engine::logs::list returns it, and the console shows it next to the trace it was logged in. Under iii compose --up, the engine’s output goes to engine.log in the compose state directory, .iii/compose/<namespace>/ by default (see Compose logs). Before the worker’s OpenTelemetry export starts, or when it is off (OTEL_ENABLED=false), Logger falls back to the language’s own logger, and the line stays in the worker’s process. You can also emit one log line and find it in the stored logs, without a worker:
Logger does not write to your worker’s own output. To print a line in the worker’s terminal, use the print function of the language.

Traces

A trace captures the spans of a call as it moves across workers, the headline view for debugging a request end to end. Traces come from worker function invocations: a worker records a span each time it handles a call. Built-in engine::* functions are not traced by default (set III_OTEL_TRACE_BUILTINS=true to include them), so call a worker function to produce a trace. The Logging examples register links::process, a worker function:
Traces export on a short delay. If engine::traces::list reports 0, wait a few seconds and call links::process again.
To run a function when a log record or a span is recorded, observe observability::on-log or observability::on-span: see Observers.

Health and stored data

Health

Clear stored data

Logs populate quickly. engine::logs::clear followed immediately by engine::logs::list can still return new logs generated in between the two calls.