juice_observability 0.5.1
juice_observability: ^0.5.1 copied to clipboard
Crash reporting and breadcrumbs as a Juice bloc, with global error-handler capture behind a fan-out reporter seam.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.5.1 - 2026-09-29 #
Requires juice ^1.10.0 (LevelAwareJuiceLogger).
Changed — DevtoolsJuiceLogger: the cost follows the listener #
- Payloads are built and posted only while the VM's Extension stream has a
listener (
dart:developerextensionStreamHasListener).postEventalready dropped events nobody would receive; the logger built each payload first — including the state'stoString()on every emission. Now it builds nothing for nobody. The inner logger still receives every call, errors included. - It declares its level to the framework (
LevelAwareJuiceLogger):Level.allwhile a listener is attached, otherwise what the inner logger declares. With the default inner logger, a release build or an app launched without tooling builds no per-event telemetry at all; attaching DevTools mid-run turns it on live. Underflutter runthe tooling daemon is a listener, so nothing changes there. - New test seam
hasListener:besidepost:. Injectingpostalone keeps the listener present, so existing captures are unaffected.
0.5.0 - 2026-09-16 #
Changed — every builder now declares its EventConcurrency mode #
- 0.2.0 made
RecordError/AddBreadcrumbsequentialand left four builders bare. Now explicit:InitializeObservabilityEvent→droppable;SetUserEvent,SetContextEvent,SetEnabledEvent→sequential(the two that fan out to reporters await them; they now complete in the order the calls were made — the analytics precedent). - DevTools extension
config.yamlversionaligned to the package (the panel header read "v0.1.0" on 0.4.0).
Tests #
- Gated-reporter coverage: a second
setUserdoes not start its fan-out until the first completes.
0.4.0 - 2026-08-21 #
New Features #
DevTools extension — Juice telemetry, visualized
Ships a DevTools extension (extension/devtools/) that consumes the
juice:<type> events DevtoolsJuiceLogger posts and renders four views:
Timeline (every transition, newest last), Spans (use-case
executions paired by executionId — honest durations even under
concurrent overlap, running/failed/elapsed), Blocs (per-bloc
emission count with the rebuild GROUPS each emission targeted — the
rebuild inspector groups make explainable), and Problems (errors,
unhandled events, leak detection). Loads automatically when a Juice app
using DevtoolsJuiceLogger connects to DevTools; a live-filter box and
clear across all four.
Source: packages/juice_observability_devtools_extension (publish_to: none). The model is a pure TelemetryModel (7 unit tests, no VM); the
live TelemetryStore adds the VM wiring, split because
devtools_extensions is web-only.
0.3.1 - 2026-08-21 #
- Docs: README now actually introduces
DevtoolsJuiceLogger(0.3.0's headline was missing from the pub.flutter-io.cn page) and the install snippet is current. Requiresjuice ^1.7.0so the span pairing documented here is structural, not aspirational. - Example: demonstrates the mirror IN FULL — a Juice-pure
TelemetryFeedBlocfed through the injectablepostseam (teeing to the real VM post and an in-app panel), so every tap shows itsuse_case_execution → use_case_completedpair withexecutionIdand elapsed time, no DevTools required. Teaches the self-loop guard (isSelfTelemetry): a bloc that consumes telemetry must filter out its own. Example tests cover the formatter, the guard, and a real start/end pair.
0.3.0 - 2026-08-21 #
New Features #
DevtoolsJuiceLogger — the framework's telemetry, live in DevTools
A JuiceLogger decorator that mirrors Juice's existing structured log
entries (use-case executions, state emissions, bloc lifecycle, event
subscriptions, unhandled events, leak detection, and all error types) to the
VM's extension-event stream via dart:developer postEvent, as
juice:<type> events — consumable live by DevTools and any VM-service
listener. A mirror on the existing logger seam, not new instrumentation:
- Typed entries (
context['type']) post asjuice:<type>; untyped chatter stays console-only; errors without a type always post asjuice:error. - Wire-safe payloads: primitives pass through; live objects (states, blocs,
group sets) cross as
toStringcapped at 512 chars. - Decorates any inner logger (default
DefaultJuiceLogger) — console logging keeps working; thepostfunction is an injectable seam for tests. - Phase 1 is instant events by design; duration spans await a
use_case_completedentry in core (ROADMAP: BlocSignal tee-up, item 1).
One line to adopt: JuiceLoggerConfig.configureLogger(DevtoolsJuiceLogger()).
0.2.0 - 2026-06-09 #
Changed #
- Requires
juice ^1.5.0. - Adopt
EventConcurrency.sequentialforRecordErrorEventandAddBreadcrumbEvent. The breadcrumb ring and error counter now live in state with a natural read-modify-write; the bloc-side accumulator workaround (_breadcrumbs/_errorCount+ helpers) is removed. Behavior unchanged — rapid breadcrumbs/errors stay race-free, now via the framework mode.
0.1.0 - 2026-05-28 #
Added #
- Initial release.
ObservabilityBloc— crash reporting + breadcrumbs, fanned out to one or more reporters.- Global capture — installs
FlutterError.onError+PlatformDispatcher.onError(chaining any existing handlers; restored onclose) so uncaught errors are reported automatically. CrashReporter— vendor seam (recordError/addBreadcrumb/setUser/setContext). Ship a Sentry/Crashlytics adapter;ConsoleCrashReporterandNoopCrashReporterincluded.- Breadcrumb ring — bounded trail (
maxBreadcrumbs) attached to each report. - Fan-out with isolation — a throwing reporter can't break the others.
- API —
recordError,breadcrumb,setUser,setContext,setEnabled. - Rebuild group —
observability:status.