flutter_devlog
A small, colored console logger for Dart and Flutter.
It has no dependencies, only prints in debug mode by default, and keeps a simple
API: one class, DevLog, with a method for each log level. When your app grows,
you can add tags, scopes, custom levels, and filtering without changing how you
call it.
If this package helps you, please star the repo to support it.
Resources
Installation
Add it to your pubspec.yaml:
dependencies:
flutter_devlog: ^0.1.0
Then run flutter pub get, and import it where you need it:
import 'package:flutter_devlog/flutter_devlog.dart';
A quick example
You don't need to create anything or call a setup function. Just log:
DevLog.info('App started');
DevLog.success('User logged in');
DevLog.warn('Cache is old');
DevLog.error('Could not load profile');
Each line prints to the console in its own color, with a label showing which
kind of log it was (INFO, SUCCESS, WARN, ERROR).
You can pass any object, not just text:
DevLog.info(user); // an object
DevLog.info([1, 2, 3]); // a list
DevLog.info({'id': 1}); // a map
That is all you need for everyday use. The sections below explain the extra features for when you want them.
The log levels
There are seven built-in levels. Use whichever fits what you are logging:
DevLog.ui('Home screen built'); // screen / widget events
DevLog.storage('Saved token'); // local storage, cache, database
DevLog.info('App started'); // general messages
DevLog.success('Payment complete'); // something worked
DevLog.api('GET /users returned 200');// network calls
DevLog.warn('Token expires soon'); // needs attention, not an error
DevLog.error('Request failed'); // something went wrong
The names you pick are only for your own clarity. Internally they also have a
priority order (ui is lowest, error is highest), which the filter below uses.
Logging errors with details
When you catch an exception, pass the error and stack trace. They show up in the console and in Flutter DevTools, which makes debugging much easier:
try {
await loadProfile();
} catch (e, stackTrace) {
DevLog.error('Failed to load profile', error: e, stackTrace: stackTrace);
}
Pretty-printing JSON
If you log an API response, DevLog.json formats it with indentation so it is
actually readable:
DevLog.json(response, title: 'User response');
This prints the title first, then the JSON neatly indented. If the object can't be turned into JSON, it tells you instead of crashing.
Turning logging on and off
By default, logs only appear in debug builds and are silent in release builds, so you don't have to remove your log lines before shipping.
You can change this and a few other things once, usually at the start of main:
void main() {
DevLog.enabled = true; // force on/off yourself
DevLog.useColors = true; // set false if you see raw codes like \x1B[31m
DevLog.includeSource = true; // add the file and line, e.g. [main.dart:42]
runApp(const MyApp());
}
includeSource is handy while debugging because every log tells you exactly
which line printed it.
Showing only the important logs
In a busy app you may want to hide the low-level noise and keep only warnings and errors. Set a minimum level once:
DevLog.minPriority = LogPriority.warn;
After this, ui, storage, info, success, and api logs are skipped, and
only warn and error get through. Set it back to LogPriority.ui to see
everything again.
Tagging logs by feature
In a larger app it helps to know which part of the code a log came from. Add a
tag:
DevLog.info('Charge started', tag: 'Payment');
This prints under the label INFO/Payment, so you can scan the console and find
all payment-related logs quickly.
A logger for one feature (scopes)
If a whole file or feature should always use the same tag, create a scoped logger once and reuse it. Every call is tagged automatically:
final log = DevLog.scoped('Auth');
log.info('Checking credentials'); // prints as INFO/Auth
log.success('Logged in'); // prints as SUCCESS/Auth
log.error('Token expired', error: e);
This keeps your code clean because you don't repeat the tag every time.
Adding your own log level
The built-in levels may not cover everything. You can define your own by giving it a name, a color, and a priority. No need to edit the package:
const network = LogLevel('NETWORK', LogColor.blue, LogPriority.api);
DevLog.log('Opening socket', level: network);
It then behaves like any built-in level, including color and filtering.
Avoiding expensive log messages
Sometimes building the log text is costly (for example, dumping a large object).
Normally that work happens even if the log is later filtered out. To avoid that,
use lazy and pass a function. The function only runs if the log will actually
be shown:
DevLog.lazy(() => 'Big dump: ${buildExpensiveString()}', level: LogLevel.info);
If minPriority is set above info, the function is never called.
Sending logs somewhere other than the console
By default logs go to the console. If you want to write them to a file, send
them to a crash reporter, or capture them in a test, set onLog. It receives
the final message and its label:
DevLog.onLog = (message, label) {
myLogFile.writeln('[$label] $message');
};
Set it back to null to return to normal console output.
A note on colors
Colors use ANSI escape codes. Most terminals and IDE consoles understand them,
but a few do not and will print raw codes like \x1B[31m instead. If you see
that, turn colors off:
DevLog.useColors = false;
Author
Made by Bayajit Islam — Portfolio · GitHub
Found a bug or have an idea? Open an issue or a pull request on the repository.
License
MIT. See the LICENSE file.
Libraries
- flutter_devlog
- A lightweight, zero-dependency, extensible colored console logger for Dart and Flutter.