Skip to content

structured_log

Structured logging for Dart and Flutter — from a line in your app's console to a searchable, shared log store for your whole team.

A log line like "User 42 logged in from 127.0.0.1" is easy to write and hard to use: you can’t filter it by user, count it by IP, or follow one request through it without regular expressions. structured_log records events with data instead — user_login {user_id: 42, ip: 127.0.0.1} — so the same entry reads well in a terminal, parses as JSON, and can be searched by any field. Inspired by Python’s structlog.

The project covers the whole path such an entry travels:

  1. Write it — a small, dependency-free core library for Dart and Flutter.
  2. Get it for free — adapters that log what bloc, riverpod, dio, http, go_router, auto_route and cherrypick already do in your app, the queries of a drift database, every request a shelf server answers, and a bridge for every library that logs through package:logging.
  3. See it on the device — a drop-in log viewer screen in Material, Fluent or Cupertino style.
  4. Collect it — a self-hosted server that receives logs from every install of your app, stores them, and lets your team search and tail them live in a web admin.

Steps 1–3 work entirely inside your app, with no server at all. Step 4 is optional, and adding it doesn’t change a single logging call.

  1. Add structured_log.

    dependencies:
    structured_log: ^0.3.0
  2. Log.

    import 'package:structured_log/structured_log.dart';
    void main() {
    getLogger().info('user_login', context: {'user_id': 42});
    }
  3. Optionally, watch it live inside your own Flutter app — a headless core plus a ready-made Material/Fluent/Cupertino skin, entirely local, no network involved (full walkthrough: Embedding Guide).

  • Events with context — log.info('user_login', context: {...}); bind() attaches fields to a logger (immutably), withCorrelation() adds typed session/request/operation ids.
  • Processors — enrich, transform or drop entries before output.
  • Secret redaction — passwords, tokens and keys masked by field name, JWTs and card numbers by value.
  • Many outputs at once — pretty JSON, JSON lines, logfmt, colored console, file, rotating file, async file, or your own function; each sink with its own level and category filter, switchable at runtime.
  • Safe by design — a log call never throws, and an unencodable value (DateTime, an exception) costs one field, not the entry.
  • Everywhere Dart runs — VM, Flutter, and the web; no runtime dependencies beyond meta.
  • A ready-made screen or embeddable widget: live list, search, level and category filters, pause, clear, entry details with copy.
  • Three design systems — Material 3, Fluent UI (WinUI-style) and Cupertino (iOS-style) — each adaptive: bottom sheet or pushed screen on phones, master-detail on tablets and desktop.
  • A headless core (LogBuffer, LogViewerController) to build your own UI.
Library What gets logged Category
bloc / flutter_bloc creation, events, transitions, errors, closing of every bloc and cubit bloc
riverpod / flutter_riverpod creation, updates, failures, removal of every provider; a failure is logged once riverpod
dio every request and its outcome, level by status code http
package:http the same, as a wrapping http.Client, without buffering bodies http
go_router navigation with route pattern, redirects, routing errors navigation
auto_route navigation with route name and pattern, tab switches; tokens redacted navigation
cherrypick DI scopes, modules, cycles, resolve errors — never an instance di
drift every query with its SQL, duration and rows, slow ones flagged, failures with their stack — argument values off db
package:logging every record of every library that logs through it, with its level, error and stack trace logging
shelf (server) every request a server answers, level by status code; handlers get a logger bound to the request_id, returned in X-Request-Id http

HTTP and navigation adapters redact auth headers, cookies, and token-like query parameters by default; bodies are off unless enabled, and masked by field name when they are — except on the server, where structured_log_shelf never writes them at all.

  • Shipping — RemoteSyncLogOutput batches entries, retries with backoff, caps its buffer, and never blocks the code that logged.
  • Ingest, search, live tail — a full-text and per-field query API, and a Server-Sent Events stream with catch-up after reconnects.
  • Multi-tenancy — groups own projects; each project has its own secret keys, quotas and retention window.
  • Access control — users, teams, and per-scope roles (admin/owner/user); JWT sessions with an HttpOnly refresh cookie in the browser; rate limiting on the auth endpoints; an audit log of who changed what.
  • Simple to run — one Dart process with an embedded SQLite file by default, PostgreSQL when you need it; docker-compose and Kubernetes manifests included.
  • Web admin — a Fluent UI app (English/Russian) for managing groups, projects, keys, users and teams, and for searching and live-tailing logs.
flowchart LR
subgraph app["Your Dart / Flutter app"]
  A["Adapters<br/>bloc · riverpod · dio · http · go_router · auto_route · cherrypick · drift · logging · shelf"] --> C["structured_log"]
  Y["Your code"] --> C
  C --> O["Console / file"]
  C --> V["In-app log viewer"]
  C --> R["RemoteSyncLogOutput"]
end
R -- "HTTP, batched" --> S["structured_log_server<br/>SQLite or PostgreSQL"]
S -- "query API · SSE" --> W["Admin client (web)"]

Everything inside the box works on its own; the server side is added only when you want logs collected centrally.

Standalone — these never touch a network

Section titled “Standalone — these never touch a network”

structured_log

Structured JSON logging for Dart — context binding, correlation fields, processors, multi-sink routing. Zero dependencies beyond meta. Usage & API · pub.dev.

structured_log_flutter

A headless in-app log-viewer core for Flutter — a LogBuffer sink and a filterable LogViewerController, no design-system lock-in. Usage & API · pub.dev.

structured_log_material, structured_log_fluent, structured_log_cupertino

Three ready-to-use in-app log viewers on top of it — Material 3, Fluent UI, and Cupertino — each with search and filtering built in. Published on pub.dev.

structured_log_bloc

A BlocObserver that logs every bloc’s and cubit’s events, state changes and errors — one line, works with flutter_bloc as is. Usage & API. Pre-release on pub.dev.

structured_log_riverpod

A ProviderObserver that logs every Riverpod provider’s creation, updates, failures and removal — one line, works with flutter_riverpod as is. Usage & API. Pre-release on pub.dev.

structured_log_dio, structured_log_http_client

Log every HTTP call and its outcome, levelled by status code, with auth headers and tokens redacted — for dio or package:http. Pre-release on pub.dev.

structured_log_go_router

Logs every go_router navigation, redirect and routing error — which screen the user was on, and where they came from. Usage & API. Pre-release on pub.dev.

structured_log_auto_route

Logs every auto_route screen opened, closed or switched to — name, pattern and location, with tokens redacted. Usage & API. Pre-release on pub.dev.

structured_log_cherrypick

Logs what the cherrypick DI container does — scopes, modules, cycles, resolve errors — without ever printing an instance. Usage & API. Pre-release on pub.dev.

structured_log_drift

Logs every query of a drift database — SQL, duration, rows — flags the slow ones and keeps argument values out. Usage & API. Pre-release on pub.dev.

structured_log_logging

Brings every record a library writes through package:logging into the same sinks, viewer and server as your own entries. Usage & API. Pre-release on pub.dev.

structured_log_shelf

For a Dart server on shelf: logs every request it answers and gives each handler a logger bound to the request’s id, returned in X-Request-Id. Usage & API. Pre-release on pub.dev.

The self-hosted service — opt in when you need it

Section titled “The self-hosted service — opt in when you need it”

structured_log_remote_sync

Ships log entries to structured_log_server over HTTP — batching, retry with backoff, a bounded buffer. Used in the quick start above. Usage & API. Published on pub.dev.

structured_log_server

The self-hosted, multi-tenant server — ingests and stores your apps’ logs, lets you search and tail them live. SQLite or PostgreSQL.

structured_log_admin_client

The web app operators use day to day — dashboard, resource management, live log search, user management, audit log.

Details: Embedding Guide · User Guide · Administrator Guide · Developer Guide · Packages · Architecture