dajno_logging (1.1.0)
Installation
dart pub add dajno_logging:1.1.0 --hosted-url=About this package
Dart.Package.Logging
Logger with levels (info/debug/warning/error/assertion/fatal), caller file/line
resolution via package:stack_trace, and pluggable sinks. Works on every Dart target,
including Flutter web.
Quick start
import 'package:dajno_logging/dajno_logging.dart';
void main() {
Log.info('Service started');
Log.warning('Cache miss');
Log.assertion(1 + 1 == 2, 'math is broken');
Log.error('Something went wrong'); // throws by default
Log.error('Log only', throwException: false);
}
Sinks
Log does not write anywhere itself: it builds a LogRecord and hands it to every configured
LogSink. The console is the default, so the snippet above behaves as it always has.
// Keep the console and add a file. No call site changes.
final file = FileLogSink('/path/to/app.log');
Log.addSink(file);
Log.info('this line is on the console and on disk');
await Log.flush(); // force the batch out, e.g. before exiting
print(await file.readAll()); // current file, previous generation first
Log.addSink/Log.removeSink/Log.useSinks/Log.clearSinksconfigure destinations.- The sink list is read on every call, so a sink added after the first line still receives everything logged after it.
- A sink that throws never reaches the caller and never costs the other sinks their line.
FileLogSinkbatches writes behind a one-second timer, flusheserror/assertion/fatalimmediately, rotates at 5 MB (maxBytes) and keeps one previous generation (app.log.1).
Writing a sink is the whole extension point: implement LogSink.write(LogRecord) for a remote
endpoint, an in-app console, a test recorder.
Platforms
dart:io is reached only through conditional imports, so the package compiles for the web:
| native | web | |
|---|---|---|
ConsoleLogSink |
stdout |
browser console |
FileLogSink |
the file at path, rotated |
the most recent 2000 lines, in memory |
Log.fatal(quit: true) |
flushes, then exits | flushes, then returns |
CI compiles example/example.dart to JavaScript on every push, so a direct dart:io import
fails the build here rather than in a consumer's web build.
Note from the migration
The old platform published this package as logging — the same name as the
well-known logging package on pub.dev. That's a hard conflict, not just a
version-range one: package:test pulls in the real pub.dev logging package
transitively (via webkit_inspection_protocol), and Dart's pub solver treats
"package logging from pub.dev" and "package logging from a private hosted
feed" as fundamentally different, unresolvable identities — no version
constraint fixes it, dart pub get fails version solving outright. Renamed
to dajno_logging (matching the dajno_* naming already used for the Python
side of this migration, e.g. dajno-ml) to remove the collision entirely.
Every dependent (Dart.Package.Observables, Dart.Package.Network) was
updated to depend on dajno_logging instead.
Project structure
pubspec.yaml
Version.txt the version to publish
lib/
├── dajno_logging.dart public API - exports
└── src/
├── log.dart Log - the static facade, fans out to sinks
├── log_level.dart LogLevel enum, and which levels count as an error
├── log_record.dart one line: level, message, caller, formatting
├── log_sink.dart LogSink - the extension point
├── sinks/
│ ├── console_log_sink.dart stdout, or the browser console
│ └── file_log_sink.dart batched, rotating file
└── platform/
├── console.dart conditional export: console_io / console_web
└── log_file.dart conditional export: log_file_io / log_file_web
test/
├── dajno_logging_test.dart
└── sinks_test.dart
example/
└── example.dart also CI's web build check
Versioning and publishing
Version.txt is the exact version that gets published — a push to main publishes it
only when that version isn't on the feed yet. Pushes to any other branch only resolve
and test.
CI
.forgejo/workflows/build.yml installs the Dart SDK, resolves dependencies, and runs
dart test on every push. On main, it also publishes via dart pub publish, tags the
commit v<version>, and creates a matching Release — via the shared
Platform/Forgejo.Package.Actions/dart-publish
composite action. .forgejo/workflows/cleanup.yml removes prerelease Pub versions when
their branch is deleted.