structured_log_flutter
Headless log-viewer core for structured_log — a bounded
in-memory buffer and a filterable controller for building a live, in-app log
viewer in Flutter. No Material, Cupertino, or any other design-system
dependency: this package renders nothing itself, so any UI skin can be built
on top of it — structured_log_material,
structured_log_fluent, and
structured_log_cupertino all build on it.
Status: published on pub.dev (
0.1.0).structured_log_material,structured_log_fluent, andstructured_log_cupertinoall depend on it as a regular hosted dependency; within this monorepo,melos bootstrapresolves it to a path dependency instead.
Features
Section titled “Features”LogBuffer— a fixed-capacity ring buffer that plugs directly intostructured_logas anOutputFunction/LogSink.output- Live updates —
LogBuffer.entriesis aValueListenable, so a widget can rebuild on every new entry without polling LogViewerController— aChangeNotifierwith level/category/search filtering, pause/resume, and clearing, all applied on top of aLogBufferlogLevelColor(LogLevel level, Brightness brightness)— the canonicalLogLevelindicator color, shared by every skin built on this package so the palette can’t drift between them- Zero design-system dependency — only
dart:ui,package:flutter/foundation.dart, andstructured_log
Installation
Section titled “Installation”dependencies: structured_log_flutter: ^0.1.0Within this monorepo, melos bootstrap resolves it to a path dependency
instead:
dependencies: structured_log_flutter: path: ../structured_log_flutterQuick Start
Section titled “Quick Start”import 'package:structured_log/structured_log.dart';import 'package:structured_log_flutter/structured_log_flutter.dart';
final buffer = LogBuffer(capacity: 500);final controller = LogViewerController(buffer);
StructlogConfiguration.configure(sinks: [ LogSink(name: 'console', output: coloredConsoleOutput), LogSink(name: 'viewer', output: buffer.capture),]);
getLogger().info('user_login', context: {'user_id': 42});
controller.levelFilter = LogLevel.warning; // only warning and abovecontroller.searchQuery = 'login'; // further narrowed by textprint(controller.visibleEntries);API Reference
Section titled “API Reference”LogBuffer
Section titled “LogBuffer”| Member | Description |
|---|---|
LogBuffer({int capacity = 500}) |
Creates an empty buffer; oldest entry evicted once capacity is exceeded |
capture(Map<String, dynamic> entry, LogLevel level) |
Matches OutputFunction’s signature — pass it directly as a sink’s output |
entries |
ValueListenable<List<Map<String, dynamic>>>, oldest first |
clear() |
Empties the buffer and notifies entries’ listeners |
LogViewerController
Section titled “LogViewerController”A ChangeNotifier wrapping a LogBuffer:
| Member | Description |
|---|---|
levelFilter (LogLevel?) |
Minimum level a visible entry must have; null = no restriction |
categoryFilter (String?) |
Exact category context value required; null = no restriction |
searchQuery (String) |
Case-insensitive substring match against event and every other context value (level/timestamp excluded) |
paused (bool) |
While true, visibleEntries stays frozen at the entries visible when paused, even as buffer keeps capturing |
visibleEntries |
The buffer’s entries, filtered by the three properties above |
clear() |
Clears buffer (and any frozen snapshot) and notifies listeners |
dispose() |
Detaches from buffer.entries — call when the controller is no longer needed |
logLevelOf(Map<String, dynamic> entry)
Section titled “logLevelOf(Map<String, dynamic> entry)”Parses an entry’s level context key back into a LogLevel, matching by
name — returns null if missing or unrecognized. Exposed as a standalone
function so a UI skin (like structured_log_material) doesn’t need to
reimplement this parsing.
logLevelColor(LogLevel level, Brightness brightness)
Section titled “logLevelColor(LogLevel level, Brightness brightness)”The single source of truth for LogLevel indicator colors, used by every
skin’s list row, detail view, and badges. Lives here (not in any one skin)
because Color/Brightness aren’t tied to Material, Cupertino, or Fluent
— this table is genuinely design-system-neutral, unlike the widgets built
on top of it.
Building a UI Skin
Section titled “Building a UI Skin”structured_log_flutter intentionally renders nothing — wire a
LogViewerController up to whatever widgets you like, listening to it as
any other ChangeNotifier (AnimatedBuilder, ListenableBuilder, etc.) and
reading visibleEntries for what to display. See
structured_log_material,
structured_log_fluent, and
structured_log_cupertino for complete
reference implementations (list, expanded-entry detail, empty states) on
Material 3, Fluent UI, and Cupertino respectively.
License
Section titled “License”MIT