Documentation menu
Getting started
New in v2.0
Feature deep dives
Reference
Observability & log history
Forwarder Observability & Log History
Every delivery is attributable: the central logger stores queryable history with service, owner and correlation id, and dead letters can be replayed.
Verified against the checkout built for v2.2.4 · updated 20 Oct 2026
On this page
OperationsNew in v2.0
Outcome is never guessed: UNKNOWN/OUTCOME_UNCONFIRMED is a first-class state between success and failure.
A logger that owns its own history
- The central logger is a separate microservice with its own storage, so a busy forwarding run cannot slow down log queries.
- Every entry is attributable: service, owner, severity, timestamp and a correlation id that ties a pipeline stage back to the message it belongs to.
- Structured [PIPELINE:*] stages — RECEIVED, VALIDATING, AUTHORIZED, ACCEPTED, IN_PROGRESS, RETRY_WAIT, SUCCEEDED, FAILED, CANCELLED, OUTCOME_UNCONFIRMED.
- Raw message bodies are deliberately not persisted. Content is represented by ids, hashes and type metadata — minimum necessary by design.
- Retention is bounded and purge is tenant-scoped, so one tenant can never delete another tenant's history.
The explorer, in every client
The same query surface backs the bot submenu, the dashboard log explorer and the mobile app, and the CLI exposes it as atf logs query / search / stats / tail / export / purge.
| Parameter | Effect |
|---|---|
| service | Narrow to one emitter: core, api, web or logger. |
| level | DEBUG, INFO, WARNING or ERROR. |
| search | Substring match across the message field. |
| since | Only entries newer than this timestamp. |
| limit | Page size, bounded on the server before it is narrowed to an int32 offset. |
Honest outcomes, including the awkward one
Telegram cannot promise exactly-once delivery, so this system does not pretend otherwise. A request that times out without confirmation becomes OUTCOME_UNCONFIRMED — visible, queryable and replayable — rather than a silent success or a phantom failure.
After the configured retries, a job that still cannot be delivered moves to the dead-letter queue with its full attempt history. DLQ entries can be inspected, replayed or purged, always inside the owning tenant's scope.
atf logs query --level ERROR --since 1h
atf logs stats
atf data queue # depth, in-flight leases, retry waits
atf data dlq # what failed, and why
atf data dlq --replay # push them back through the pipelineTopology and health
- Four services are probed independently: core, logger, api and web, each with reachability, latency and version.
- GET /api/health/services returns the same data the dashboard tile renders, for your own monitoring stack.
- atf system services prints a colourised table with fix hints and exits non-zero if something is down, ready for a cron check.
Frequently asked
Can I see logs for another user's task?
No. Queries are scoped to the authenticated tenant before any filter is applied, and purge is scoped the same way.
Are message bodies stored in the logs?
No. Logs carry ids, hashes, lengths and type metadata. Message content is not persisted by the logger, and secrets are redacted before a line is emitted.
What is OUTCOME_UNCONFIRMED?
It is the state for a delivery whose result Telegram never confirmed, typically a timeout. It is queryable and replayable, and it prevents a timeout from being reported as a success or as a definitive failure.