Logger class
Use a Logger to log debug messages. Loggers are named using a hierarchical dot-separated name convention.
class Logger { /** Simple name of this logger. */ final String name; /** The full name of this logger, which includes the parent's full name. */ String get fullName => (parent == null || parent.name == '') ? name : '${parent.fullName}.$name'; /** Parent of this logger in the hierarchy of loggers. */ final Logger parent; /** Logging [Level] used for entries generated on this logger. */ Level _level; final Map<String, Logger> _children; /** Children in the hierarchy of loggers, indexed by their simple names. */ final Map<String, Logger> children; /** Controller used to notify when log entries are added to this logger. */ StreamController<LogRecord> _controller; /** * Singleton constructor. Calling `new Logger(name)` will return the same * actual instance whenever it is called with the same string name. */ factory Logger(String name) { return _loggers.putIfAbsent(name, () => new Logger._named(name)); } factory Logger._named(String name) { if (name.startsWith('.')) { throw new ArgumentError("name shouldn't start with a '.'"); } // Split hierarchical names (separated with '.'). int dot = name.lastIndexOf('.'); Logger parent = null; String thisName; if (dot == -1) { if (name != '') parent = new Logger(''); thisName = name; } else { parent = new Logger(name.substring(0, dot)); thisName = name.substring(dot + 1); } return new Logger._internal(thisName, parent, new Map<String, Logger>()); } Logger._internal(this.name, this.parent, Map<String, Logger> children) : this._children = children, this.children = new UnmodifiableMapView(children) { if (parent != null) parent._children[name] = this; } /** * Effective level considering the levels established in this logger's parents * (when [hierarchicalLoggingEnabled] is true). */ Level get level { if (hierarchicalLoggingEnabled) { if (_level != null) return _level; if (parent != null) return parent.level; } return _rootLevel; } /** Override the level for this particular [Logger] and its children. */ void set level(Level value) { if (hierarchicalLoggingEnabled && parent != null) { _level = value; } else { if (parent != null) { throw new UnsupportedError( 'Please set "hierarchicalLoggingEnabled" to true if you want to ' 'change the level on a non-root logger.'); } _rootLevel = value; } } /** * Returns an stream of messages added to this [Logger]. You can listen for * messages using the standard stream APIs, for instance: * logger.onRecord.listen((record) { ... }); */ Stream<LogRecord> get onRecord => _getStream(); void clearListeners() { if (hierarchicalLoggingEnabled || parent == null) { if (_controller != null) { _controller.close(); _controller = null; } } else { root.clearListeners(); } } /** Whether a message for [value]'s level is loggable in this logger. */ bool isLoggable(Level value) => (value >= level); /** * Adds a log record for a [message] at a particular [logLevel] if * `isLoggable(logLevel)` is true. * * Use this method to create log entries for user-defined levels. To record a * message at a predefined level (e.g. [Level.INFO], [Level.WARNING], etc) you * can use their specialized methods instead (e.g. [info], [warning], etc). */ void log(Level logLevel, String message, [Object error, StackTrace stackTrace]) { if (isLoggable(logLevel)) { var record = new LogRecord(logLevel, message, fullName, error, stackTrace); if (hierarchicalLoggingEnabled) { var target = this; while (target != null) { target._publish(record); target = target.parent; } } else { root._publish(record); } } } /** Log message at level [Level.FINEST]. */ void finest(String message, [Object error, StackTrace stackTrace]) => log(Level.FINEST, message, error, stackTrace); /** Log message at level [Level.FINER]. */ void finer(String message, [Object error, StackTrace stackTrace]) => log(Level.FINER, message, error, stackTrace); /** Log message at level [Level.FINE]. */ void fine(String message, [Object error, StackTrace stackTrace]) => log(Level.FINE, message, error, stackTrace); /** Log message at level [Level.CONFIG]. */ void config(String message, [Object error, StackTrace stackTrace]) => log(Level.CONFIG, message, error, stackTrace); /** Log message at level [Level.INFO]. */ void info(String message, [Object error, StackTrace stackTrace]) => log(Level.INFO, message, error, stackTrace); /** Log message at level [Level.WARNING]. */ void warning(String message, [Object error, StackTrace stackTrace]) => log(Level.WARNING, message, error, stackTrace); /** Log message at level [Level.SEVERE]. */ void severe(String message, [Object error, StackTrace stackTrace]) => log(Level.SEVERE, message, error, stackTrace); /** Log message at level [Level.SHOUT]. */ void shout(String message, [Object error, StackTrace stackTrace]) => log(Level.SHOUT, message, error, stackTrace); Stream<LogRecord> _getStream() { if (hierarchicalLoggingEnabled || parent == null) { if (_controller == null) { _controller = new StreamController<LogRecord>.broadcast(sync: true); } return _controller.stream; } else { return root._getStream(); } } void _publish(LogRecord record) { if (_controller != null) { _controller.add(record); } } /** Top-level root [Logger]. */ static Logger get root => new Logger(''); /** All [Logger]s in the system. */ static final Map<String, Logger> _loggers = <String, Logger>{}; }
Static Properties
Constructors
Properties
final Map<String, Logger> children #
Children in the hierarchy of loggers, indexed by their simple names.
final Map<String, Logger> children
final String fullName #
The full name of this logger, which includes the parent's full name.
String get fullName => (parent == null || parent.name == '') ? name : '${parent.fullName}.$name';
Level get level #
Effective level considering the levels established in this logger's parents (when hierarchicalLoggingEnabled is true).
Level get level { if (hierarchicalLoggingEnabled) { if (_level != null) return _level; if (parent != null) return parent.level; } return _rootLevel; }
void set level(Level value) #
Override the level for this particular Logger and its children.
void set level(Level value) { if (hierarchicalLoggingEnabled && parent != null) { _level = value; } else { if (parent != null) { throw new UnsupportedError( 'Please set "hierarchicalLoggingEnabled" to true if you want to ' 'change the level on a non-root logger.'); } _rootLevel = value; } }
Methods
void clearListeners() #
void clearListeners() { if (hierarchicalLoggingEnabled || parent == null) { if (_controller != null) { _controller.close(); _controller = null; } } else { root.clearListeners(); } }
void config(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.CONFIG.
void config(String message, [Object error, StackTrace stackTrace]) => log(Level.CONFIG, message, error, stackTrace);
void fine(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.FINE.
void fine(String message, [Object error, StackTrace stackTrace]) => log(Level.FINE, message, error, stackTrace);
void finer(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.FINER.
void finer(String message, [Object error, StackTrace stackTrace]) => log(Level.FINER, message, error, stackTrace);
void finest(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.FINEST.
void finest(String message, [Object error, StackTrace stackTrace]) => log(Level.FINEST, message, error, stackTrace);
void info(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.INFO.
void info(String message, [Object error, StackTrace stackTrace]) => log(Level.INFO, message, error, stackTrace);
bool isLoggable(Level value) #
Whether a message for value's level is loggable in this logger.
bool isLoggable(Level value) => (value >= level);
void log(Level logLevel, String message, [Object error, StackTrace stackTrace]) #
Adds a log record for a
message at a particular
logLevel if
isLoggable(logLevel)
is true.
Use this method to create log entries for user-defined levels. To record a message at a predefined level (e.g. Level.INFO, Level.WARNING, etc) you can use their specialized methods instead (e.g. info, warning, etc).
void log(Level logLevel, String message, [Object error, StackTrace stackTrace]) { if (isLoggable(logLevel)) { var record = new LogRecord(logLevel, message, fullName, error, stackTrace); if (hierarchicalLoggingEnabled) { var target = this; while (target != null) { target._publish(record); target = target.parent; } } else { root._publish(record); } } }
void severe(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.SEVERE.
void severe(String message, [Object error, StackTrace stackTrace]) => log(Level.SEVERE, message, error, stackTrace);
void shout(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.SHOUT.
void shout(String message, [Object error, StackTrace stackTrace]) => log(Level.SHOUT, message, error, stackTrace);
void warning(String message, [Object error, StackTrace stackTrace]) #
Log message at level Level.WARNING.
void warning(String message, [Object error, StackTrace stackTrace]) => log(Level.WARNING, message, error, stackTrace);