structured_log
Structured JSON logging for Dart — context binding, correlation
fields, processors, multi-sink routing. Zero dependencies beyond
meta. Usage & API ·
pub.dev.
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:
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.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.
Add structured_log.
dependencies: structured_log: ^0.3.0Log.
import 'package:structured_log/structured_log.dart';
void main() { getLogger().info('user_login', context: {'user_id': 42});}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).
Run the server. Starts structured_log_server and the admin
client behind one nginx — nothing else to install.
cd deploy && cp .env.example .env && ./deploy.shOpen http://localhost:8080 and sign in with the temporary password
printed to the server’s startup log (details:
Administrator Guide).
Create a project and a secret key. In the admin client: a group, a project inside it, then a secret key for that project — shown once, on creation (walkthrough with screenshots: User Guide).
Ship logs from your app.
import 'package:structured_log/structured_log.dart';import 'package:structured_log_remote_sync/structured_log_remote_sync.dart';
void main() { StructlogConfiguration.configure(sinks: [ LogSink(name: 'server', output: RemoteSyncLogOutput( serverUrl: 'https://logs.example.com', projectSecretKey: 'slk_...', // from step 2 )), ]);
getLogger().info('user_login', context: {'user_id': 42});}Entries show up live in the admin client’s log browser as they’re sent — no restart, no polling (details: Developer Guide).
log.info('user_login', context: {...});
bind() attaches fields to a logger (immutably), withCorrelation()
adds typed session/request/operation ids.DateTime, an exception) costs one field, not the entry.meta.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.
RemoteSyncLogOutput batches entries, retries with
backoff, caps its buffer, and never blocks the code that logged.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.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.
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.
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