Last updated:
0 purchases
harmony log
harmony_log #
Harmony Logging Mechanism
Installation #
Add the following lines to your pubspec.yaml file:
dependencies:
harmony_log: ^latest.version
copied to clipboard
import harmony_log.
import 'package:harmony_log/harmony_log.dart';
copied to clipboard
Usage #
Log system contains two main blocks, A logger which is represented using Log class, and an output which is represented
using LogOutput class.
Each log request on Log class is transformed to a LogEvent by adding identification and time information, and is
redirected to the given LogOutput. LogEvents contain message, error, stackTrace and level (which is
represented using LogLevel enum) as well as some extra information like id (which is generated by the given LogId)
, time and extra. extra is a general field with type Object which is reserved for adding extra information to a
log event.
A LogId is needed for Log class to generate an id for each log event. You can use LogId factories like
counter which will simply count from a starting value, constant which will always generate the same given id
and custom which you can provide your custom logic for id generation. You can check out on dart docs.
As well as a generic log method on Log class you have access to helper methods
v, d, i, w, e and wtf which add level according to their acronyms. You have also access to write method
on Log class which is a low level method to directly specify log events. LogLevel enum has 6 different log levels
like LogLevel.verbose with significance of 0 and LogLevel.wtf with significance of 5. LogLevels are comparable
using compareTo method or comparison operators like >=.
Each Log class should be initialized using init and closed using close. After calling init it should be
immediately usable. But after calling close the behaviour is unspecified meaning using log after being closed can
actually log events, don't log events without giving an error or throwing an error. Also closing may be finished
asynchronously. you must call logging methods after calling init and before calling close. init and close
commands are redirected to LogOutput.
Log class is created by providing a LogOutput, LogId and a tag to its constructor. tag is by default null. it is
recommended that you create one Log class with null tag for your app log, then create tagged loggers from your logger
using tagged method. This has the advantage to using the same output and id generation systems, So by initializing one
them all of them are initialized and the same for closing.
LogOutputs are created using its factories. Some of the outputs are responsible to redirect events to other outputs,
like filtered to filter events and redirect to other output, multi to output to multiple other outputs, redirect
to redirect output to other output conditionally and redirectOnDebug to redirect output to other output only on debug.
Some of them are terminal outputs like noop which does not do anything. And there is a special custom output which
can be used to create custom outputs by providing functions for init, write and close operations. And a
special plain factory which is used to output plain String data. There is also developerLog log output which can
be used to log to dart:developer.
Filtering events is done by using special filtered LogOutput factory. You should provide and output for filtered
events to go to and a LogFilter to filter events. LogFilters are created using its factories, for example level
which will allow levels equal or greater than the specified level, all which will allow all events, none which won't
allow any events, debug which will allow events only on debug, and several other factories which you can check out on
dart docs. And there is a custom factory which is used to create custom filtering logic. All LogFilters support
standard set operations like |, &, - and !.
Plain output is where you will output logs to for example console and file. Outputting plain data is done by using
special plain LogOutput factory. You should provide a LogPlainFilter and a LogPlainOutput.
LogPlainFilter is responsible for transforming a log event to a list of string lines. It can be created using its
factories like simple which will format a simple single-line output, pretty which will format events in a box like
view, json which will format events in json. json formatter is specially good when outputting to a
file. LogPlainFilter will also add start and end sequences to log output, for example in json we need [and ] at
start and end of file to be meaningful. There is a custom factory which you can use to implement your custom
formatting mechanism.
LogPlainOutput is responsible to output a list of string lines. Some of the plain outputs are responsible to redirect
events to other plain outputs, like multi to output to multiple other outputs, redirect
to redirect output to other output conditionally. Some of them are terminal outputs like noop which does not do
anything, console which is used to output data using print statements and file which is used to output data to
file in the given directory path. File name is based on creating time with a prefix, postfix and extension which can be
changed of needed. File output can not be used on flutter web.
As a note filtering will always pass init and close operations. It is better to use redirect and its dialects for
enabling/disabling logging completely on different situations.
A basic example, which only logs on debug and outputs to cosnole using simple formatting:
import 'package:harmony_log/harmony_log.dart';
void main() {
final log = Log(
id: LogId.counter(),
child: LogOutput.redirectOnDebug(
child: LogOutput.plain(
format: LogPlainFormat.simple(),
child: LogPlainOutput.console(),
),
),
);
log.init();
log.i('hello, there!');
log.e('bad code!', error: AssertionError());
log.close();
}
copied to clipboard
A basic example, which only logs on debug and outputs to cosnole using pretty formatting, and also filtering logs to
have at least info level and using counter id generation:
final log = Log(
id: LogId.counter(),
child: LogOutput.redirectOnDebug(
child: LogOutput.filtered(
filter: LogFilter.level(LogLevel.info),
child: LogOutput.plain(
format: LogPlainFormat.pretty(),
child: LogPlainOutput.console(),
),
),
),
);
copied to clipboard
An example, which shows logs with level at least debug on cosole only in debug with pretty formatting, saves all logs
to a file with json formatting, on release sends logs with level of at least error to a server:
final log = Log(
id: LogId.counter(),
child: LogOutput.multi(
children: [
LogOutput.redirectOnDebug(
child: LogOutput.filtered(
filter: LogFilter.level(LogLevel.debug),
child: LogOutput.plain(
format: LogPlainFormat.simple(),
child: LogPlainOutput.console(),
),
),
),
LogOutput.plan(
format: LogPlainFormat.json(),
child: LogPlainOutput.file(
path: 'path/to/directory',
),
),
LogOutput.redirectOnRelease(
child: LogOutput.filtered(
filter: LogFilter.level(LogLevel.error),
child: LogOutput.custom(
write: (e) {
// send event to server
},
),
),
),
],
),
);
copied to clipboard
creating a tagged logger:
final log = Log(/* ... */);
final otherLog = log.tagged('OTHER');
copied to clipboard
Examples #
see example:
Simple Example
Complex Example
For personal and professional use. You cannot resell or redistribute these repositories in their original state.
There are no reviews.