cable

An extensible and simple logging framework.


Keywords
dart, dartlang, flutter, logger, logging, plugins
License
BSD-3-Clause

Documentation

cable

An extensible and simple logging framework.
Build Status Pub Package Version Latest Dartdocs

The cable package provides a re-usable interface for logging and defining custom logging destinations, such as file I/O, remote web services, and more.

Installation

Add cable as under dependencies in your pubspec.yaml file:

dependencies:
  cable: ^0.1.0

And that's it! See usage for details.

Usage

Getting started

Out of the box cable provides two top-level methods, log and logLazy.

For simple string messages, use log:

void main() {
  log('Hello World!');
}

And for more complex messages that will need to be computed, use logLazy:

void main() {
  logLazy(() => 'The 100th digit of PI is ${computePiDigits(100)}');
}

Depending on the severity level, the closure for logLazy may not be invoked.

Both of these methods are intended to be for simpler use cases, with drawbacks:

  • They just print string-like objects to console.
  • The default severity is Severity.debug (all messages).
  • They don't (immediately) support custom formatting, destinations, severity.

HINT: Define a default Severity using Dart declaration variables.

In the VM, set CABLE_DEFAULT_SEVERITY to 4, or Severity.warning.

$ dart bin/app.dart -dCABLE_DEFAULT_SEVERITY=4

Read more about Dart declaration variables.

Creating a logger

A Logger class can be created and used for dependency injection:

void main() {
  final logger = new Logger();
  final service = new Service(logger: logger);
  // ...
}

You can also set the severity threshold:

void main() {
  final logger = new Logger(
    severity: Severity.warning,
  );
}

Or define a simple string formatter:

void main() {
  final logger = new Logger(
    // Writes string logs in the format of {name}: {message}.
    formatter: (record) => '${record.origin}: ${record.payload}',
  );
}

By default, a Logger just prints to the console. You can also configure one:

Custom destination(s)

NOTE: This package intentionally is sparse on opinions or specific destinations in order to reduce your transitive dependencies to an absolute minimum. We encourage you to write and contribute to cable_* packages that provide interesting destinations/endpoints for cable!

void main() {
  final logger = new Logger(
   destinations: [
     // Any class that implements Sink<Record>
   ],
 );
}

Several built-in classes are available cross platform:

void main() {
  final logger = new Logger(
   destinations: [
     // Does nothing.
     LogSink.nullSink,
     
     // Prints to console.
     LogSink.printSink,
     
     // Use any Sink<String> instance, such as a `StreamController`.
     new LogSink.writeToSink(someEventController),
     
     // Use any StringSink instance, such as a `StringBuffer`.
     new LogSink.writeToBuffer(stringBuffer),
   ],
  );
}

It's also easy to create your own plugin packages!

class FileSink implements Sink<Record> {
  @override
  void add(Record data) { /* Write to a file. */ }

  @override
  void close() { /* Close the file stream. */ }
}

void main() {
  final logger = new Logger(
    destinations: [new FileSink(/*...*/)],
  );
}

Override Functions

It's possible to replace log and logLazy to forward to your own configured Logger instance at runtime - use scope:

void runLogged(Logger logger) {
  logger.scope(() => startApplication());
}

Using zones, any calls to log or logLazy inside of context of startApplication() will now use your custom logger class, not the default top-level function behavior.

Contributing

We welcome a diverse set of contributions, including, but not limited to:

For the stability of the API and existing users, consider opening an issue first before implementing a large new feature or breaking an API. For smaller changes (like documentation, minor bug fixes), just send a pull request.

Testing

All pull requests are validated against travis, and must pass. The build_runner package lives in a mono repository with other build packages, and all of the following checks must pass for each package.

Ensure code passes all our analyzer checks:

$ dartanalyzer .

Ensure all code is formatted with the latest dev-channel SDK.

$ dartfmt -w .

Run all of our unit tests:

$ pub run test