A small, pragmatic Dart logging kit built on top of logging.
Everything is opt-in and stays out of your way in release — file rotation, JSON payloads,
HTTP dumps, and call tracing all sit at FINE and disappear when not needed.
Pure Dart — works in Flutter, server, and CLI projects.
| Module | Purpose |
|---|---|
initLogging() |
Root logger with colored console output + optional daily-rotated file sink (keeps last 5 files). |
LoggerJson |
infoJson() / prettyJson() — log any Map / List / JSON string as indented output. Long strings are automatically truncated. |
LoggerTrace |
trace() / traceAsync() — log a function's arguments and return value at FINE. Zero overhead when FINE is not loggable. |
LoggingClient |
Drop-in http.Client wrapper that logs every request/response. Authorization redacted, bodies truncated. |
prettyResponse() |
Render an http.Response as a readable request+response block for logs. |
dumpValue() |
Human-readable dump of any Dart object, capped at depth 4. |
dependencies:
logger_utils:
git:
url: https://github.com/sunbird89629/logger_utils.git
ref: v0.1.0import 'package:logger_utils/logger_utils.dart';
void main() {
// Console only:
initLogging();
// Or with daily-rotated file output:
initLogging(logsDir: 'logs', filePrefix: 'myapp');
final log = Logger('my.module');
log.info('started');
log.infoJson('payload', {'user': 'alice', 'items': [1, 2, 3]});
}| Level | Content | Debug build | Release build |
|---|---|---|---|
FINE |
HTTP dumps, call traces, full payloads | ✅ visible | ❌ hidden |
INFO |
Key events and milestones | ✅ visible | ✅ visible |
WARNING / SEVERE |
Recoverable and fatal errors | ✅ visible | ✅ visible |
The noisy stuff vanishes automatically in release.
Wrap any function to log its arguments and return value:
final result = log.trace('square', [3], () => 3 * 3);
// FINE square(3)
// FINE square => 9
final title = await log.traceAsync(
'fetchTitle',
[id],
() => api.fetchTitle(id),
);Zero overhead: the wrapper becomes a no-op when FINE is not loggable. The original
function runs directly — no formatting cost, no intermediate allocations.
Wrap your http.Client once and every call is logged:
final client = LoggingClient(); // wraps a fresh http.Client
// or: LoggingClient(inner: myExistingClient, maxBodyLog: 8192);
final api = ApiClient(httpClient: client); // every request/response now loggedSample output (at FINE):
GET https://api.example.com/users/42
accept: application/json
200 OK (123ms, 456 bytes)
content-type: application/json
{
"id": 42,
"name": "alice"
}
Authorizationheader is always redacted before logging.- Bodies past
maxBodyLogchars are truncated (default 4096). - When
FINEis not loggable,send()forwards to the inner client without buffering the response stream — zero overhead.
Prefer to log a response you already have?
log.fine(prettyResponse(response, elapsedMs: 123));log.infoJson('payload', jsonMapOrString);
// or standalone:
final text = prettyJson({'a': 1, 'blob': longBase64}, maxStringLen: 100);- Non-JSON strings are returned as-is.
- Long string values (not keys) are truncated so base64 blobs don't flood the log.
- Non-ASCII (Chinese, emoji) is kept verbatim.
MIT