loq_flutter 0.1.1
loq_flutter: ^0.1.1 copied to clipboard
Flutter integration for loq structured logging. Ships a Navigator observer with ambient screen-name context, a lifecycle observer that flushes handlers on pause and detach, and an init helper that wir [...]
0.1.1 #
- No functional changes vs 0.1.0; the shipped
lib/is unchanged. Cuts a release from a fully CI-verified commit (a test-suite lint fix and the CI Flutter-SDK migration landed after 0.1.0 was uploaded) and exercises the new tag-triggered publish workflow.
0.1.0 #
- Initial release.
LoqNavigatorObserver: aNavigatorObserverthat emits a structured log record on everydidPush/didPop/didReplace/didRemoveand tracks the current screen as instance state. Keeps toPageRouteby default so dialogs and modals stay out of the log stream; passincludeNonPageRoutes: trueto track every route.LoqNavigatorObserver.screenFieldsProcessor: aProcessorthat addsapp.screen.nameandloq.app.screen.previous_nameto every record emitted by any logger, sourced from the observer's tracked state. Wire it intoLogConfig.global.processorsto make screen context follow every log.LoqLifecycleObserver: aWidgetsBindingObserverwrapper that emits lifecycle events and flushes registered handlers onpausedanddetached(opt-inhidden).flushHandlersdefaults toLogConfig.global.handlersread at flush time, so changes throughLogConfig.configureare picked up.initLoq(): one-call setup that runs the user'srunAppinsiderunZonedGuardedand wiresFlutterError.onErrorandPlatformDispatcher.instance.onErrorwith chain-and-restore semantics so it lives alongside other packages that touch those slots (Crashlytics, Sentry, etc.). InstallsLoqLifecycleObserverby default; passinstallLifecycleObserver: falseto skip.- Bounded LRU hash queue dedupes the same exception across
capture paths (
PlatformDispatcher.onErrorplusrunZonedGuarded), so it logs once even when both fire. reportSilentFlutterErrors: falseby default. DropsFlutterErrorDetails.silentso framework-handled errors don't add noise. Override per call site.- Default fields follow the OpenTelemetry semantic conventions where
OTel defines them; everything else lives under the
loq.*namespace so it can't collide with future OTel additions.- OTel-verbatim:
exception.type,exception.message,exception.stacktrace(Stable);app.screen.name(Development). - Loq-namespaced:
loq.app.screen.previous_name,loq.navigation.kind,loq.navigation.route_type,loq.navigation.is_first_route,loq.app.lifecycle.state,loq.app.lifecycle.previous_state,loq.error.source,loq.error.handled,loq.flutter.library,loq.flutter.context,loq.flutter.silent.
- OTel-verbatim:
- Sealed event hierarchies for hooks:
NavigationEvent(NavigationPushEvent/NavigationPopEvent/NavigationReplaceEvent/NavigationRemoveEvent),LifecycleEvent(AppResumedEvent/AppInactiveEvent/AppHiddenEvent/AppPausedEvent/AppDetachedEvent),ErrorEvent(FlutterFrameworkErrorEvent/PlatformDispatcherErrorEvent/ZoneGuardErrorEvent). One typedfields:hook covers every event variant; pattern-match withswitchto branch. - Public default helpers:
defaultNavigationFields,defaultLifecycleFields,defaultErrorFields,defaultScreenNameResolver. Build on them through...defaultsin thefields:hook. - Resolver-suffix hooks:
nameResolver(screen-name extraction; override for go_router or auto_route),levelResolver(per-event level override).skipLogpredicate (onLoqNavigatorObserver) drops the log for noisy events while still updating internal screen state; named afterloq_drift'sskipLogto flag the narrower scope vs.loq_shelf'sskip.messageoverride for every event. - Works with raw
Navigator,go_router(observers:), andauto_route(navigatorObservers:). README has setup recipes for each. ansiForegroundFromColor(Color)andansiLevelColors(Map<Level, Color>): turn FlutterColorvalues into 24-bit ANSI true-color escapes forConsoleHandler'slevelColors:map. Lets users on Flutter stay inColors.deepOrangeidioms instead of hand-coding'\x1B[31m'.- Hot-reload safety:
LoqErrorStatekeeps a process-wide reference to the instance that ownsFlutterError.onErrorandPlatformDispatcher.onError. A secondinitLoqcall (typical on hot reload) disposes the prior owner first so the handler chain stays flat instead of growing one level per reload. FlutterErrorDetails.informationCollectoris now captured asloq.flutter.information: aList<String>of widget-tree diagnostic notes (e.g. "The relevant error-causing widget was: Foo"). Left out when empty.MemoryPressureEvent:LoqLifecycleObservernow overridesdidHaveMemoryPressure. Emits atLevel.warnby default (memoryPressureLevel:to override) and flushes registered handlers (flushOnMemoryPressure: falseto turn off). Field:loq.memory.pressure.LocaleChangeEvent:LoqLifecycleObserveroverridesdidChangeLocales. Emits atLevel.debugcarrying the new and previous locale lists. Fields:loq.app.locales,loq.app.previous_locales. No flush.- App-in-background duration: when
AppResumedEventfollowsAppPausedEvent, the resumed event's defaults includeloq.app.background_duration_ms: wall-clock time the app spent paused. Useful for stale-session checks. LifecycleEventhierarchy refactor: the fiveAppLifecycleStatevariants now live under a new intermediateAppLifecycleStateEventsealed class.MemoryPressureEventandLocaleChangeEventextendLifecycleEventdirectly. Switch onAppLifecycleStateEventto treat all five app-state events the same way.captureSourceLocationflag oninitLoq(): top-level setting that flows intoLogConfig.captureSourceLocation, turning on source-location capture for dev builds without a separateLogConfig.configurecall.debugPrintredirect oninitLoq(): optionalredirectFlutterDebugPrint: trueflag captures Flutter framework output (layout warnings, asset chatter,FlutterError.dumpErrorToConsole, and so on) into a configurable logger. Only touchesdebugPrint, not plainprint(), soConsoleHandlerstays loop-free. Hot-reload-safe via the same static-owner pattern as the error slots. Off by default since debug builds are noisy. Configurable viaflutterDebugLogger:andflutterDebugLevel:.