| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** | 5 /** |
| 6 * Provides APIs for debugging and error logging. This library introduces | 6 * Provides APIs for debugging and error logging. This library introduces |
| 7 * abstractions similar to those used in other languages, such as the Closure JS | 7 * abstractions similar to those used in other languages, such as the Closure JS |
| 8 * Logger and java.util.logging.Logger. | 8 * Logger and java.util.logging.Logger. |
| 9 */ | 9 */ |
| 10 library logging; | 10 library logging; |
| 11 | 11 |
| 12 import 'dart:async'; | 12 import 'dart:async'; |
| 13 | 13 |
| 14 import '../../meta/lib/meta.dart'; | |
| 15 | |
| 16 /** | 14 /** |
| 17 * Whether to allow fine-grain logging and configuration of loggers in a | 15 * Whether to allow fine-grain logging and configuration of loggers in a |
| 18 * hierarchy. When false, all logging is merged in the root logger. | 16 * hierarchy. When false, all logging is merged in the root logger. |
| 19 */ | 17 */ |
| 20 bool hierarchicalLoggingEnabled = false; | 18 bool hierarchicalLoggingEnabled = false; |
| 21 | 19 |
| 22 /** | 20 /** |
| 23 * Level for the root-logger. This will be the level of all loggers if | 21 * Level for the root-logger. This will be the level of all loggers if |
| 24 * [hierarchicalLoggingEnabled] is false. | 22 * [hierarchicalLoggingEnabled] is false. |
| 25 */ | 23 */ |
| (...skipping 17 matching lines...) Expand all Loading... |
| 43 | 41 |
| 44 /** Logging [Level] used for entries generated on this logger. */ | 42 /** Logging [Level] used for entries generated on this logger. */ |
| 45 Level _level; | 43 Level _level; |
| 46 | 44 |
| 47 /** Children in the hierarchy of loggers, indexed by their simple names. */ | 45 /** Children in the hierarchy of loggers, indexed by their simple names. */ |
| 48 Map<String, Logger> children; | 46 Map<String, Logger> children; |
| 49 | 47 |
| 50 /** Controller used to notify when log entries are added to this logger. */ | 48 /** Controller used to notify when log entries are added to this logger. */ |
| 51 StreamController<LogRecord> _controller; | 49 StreamController<LogRecord> _controller; |
| 52 | 50 |
| 53 // TODO(sigmund): remove together with the deprecated [on] API. | |
| 54 Map<LoggerHandler, StreamSubscription> _deprecatedSubscriptions; | |
| 55 | |
| 56 /** | 51 /** |
| 57 * Singleton constructor. Calling `new Logger(name)` will return the same | 52 * Singleton constructor. Calling `new Logger(name)` will return the same |
| 58 * actual instance whenever it is called with the same string name. | 53 * actual instance whenever it is called with the same string name. |
| 59 */ | 54 */ |
| 60 factory Logger(String name) { | 55 factory Logger(String name) { |
| 61 if (name.startsWith('.')) { | 56 if (name.startsWith('.')) { |
| 62 throw new ArgumentError("name shouldn't start with a '.'"); | 57 throw new ArgumentError("name shouldn't start with a '.'"); |
| 63 } | 58 } |
| 64 if (_loggers == null) _loggers = <String, Logger>{}; | 59 if (_loggers == null) _loggers = <String, Logger>{}; |
| 65 if (_loggers.containsKey(name)) return _loggers[name]; | 60 if (_loggers.containsKey(name)) return _loggers[name]; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 if (parent != null) { | 100 if (parent != null) { |
| 106 throw new UnsupportedError( | 101 throw new UnsupportedError( |
| 107 'Please set "hierarchicalLoggingEnabled" to true if you want to ' | 102 'Please set "hierarchicalLoggingEnabled" to true if you want to ' |
| 108 'change the level on a non-root logger.'); | 103 'change the level on a non-root logger.'); |
| 109 } | 104 } |
| 110 _rootLevel = value; | 105 _rootLevel = value; |
| 111 } | 106 } |
| 112 } | 107 } |
| 113 | 108 |
| 114 /** | 109 /** |
| 115 * Returns an event manager for this [Logger]. You can listen for log messages | |
| 116 * by adding a [LoggerHandler] to an event from the event manager, for | |
| 117 * instance: | |
| 118 * logger.on.record.add((record) { ... }); | |
| 119 * | |
| 120 * This API is Deprecated. Use [onRecord] instead. | |
| 121 */ | |
| 122 @deprecated | |
| 123 LoggerEvents get on => new LoggerEvents(this); | |
| 124 | |
| 125 /** | |
| 126 * Returns an stream of messages added to this [Logger]. You can listen for | 110 * Returns an stream of messages added to this [Logger]. You can listen for |
| 127 * messages using the standard stream APIs, for instance: | 111 * messages using the standard stream APIs, for instance: |
| 128 * logger.onRecord.listen((record) { ... }); | 112 * logger.onRecord.listen((record) { ... }); |
| 129 */ | 113 */ |
| 130 Stream<LogRecord> get onRecord => _getStream(); | 114 Stream<LogRecord> get onRecord => _getStream(); |
| 131 | 115 |
| 132 void clearListeners() { | 116 void clearListeners() { |
| 133 if (hierarchicalLoggingEnabled || parent == null) { | 117 if (hierarchicalLoggingEnabled || parent == null) { |
| 134 if (_controller != null) { | 118 if (_controller != null) { |
| 135 _controller.close(); | 119 _controller.close(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 if (hierarchicalLoggingEnabled || parent == null) { | 178 if (hierarchicalLoggingEnabled || parent == null) { |
| 195 if (_controller == null) { | 179 if (_controller == null) { |
| 196 _controller = new StreamController<LogRecord>.broadcast(); | 180 _controller = new StreamController<LogRecord>.broadcast(); |
| 197 } | 181 } |
| 198 return _controller.stream; | 182 return _controller.stream; |
| 199 } else { | 183 } else { |
| 200 return root._getStream(); | 184 return root._getStream(); |
| 201 } | 185 } |
| 202 } | 186 } |
| 203 | 187 |
| 204 /** Adds a handler to listen whenever a log record is added to this logger. */ | |
| 205 void _addHandler(LoggerHandler handler) { | |
| 206 if (_deprecatedSubscriptions == null) { | |
| 207 _deprecatedSubscriptions = new Map<LoggerHandler, StreamSubscription>(); | |
| 208 } | |
| 209 | |
| 210 _deprecatedSubscriptions[handler] = onRecord.listen(handler); | |
| 211 } | |
| 212 | |
| 213 void _removeHandler(LoggerHandler handler) { | |
| 214 if (_deprecatedSubscriptions != null) { | |
| 215 var sub = _deprecatedSubscriptions.remove(handler); | |
| 216 if (sub != null) { | |
| 217 sub.cancel(); | |
| 218 } | |
| 219 if (_deprecatedSubscriptions.isEmpty) { | |
| 220 _deprecatedSubscriptions = null; | |
| 221 } | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 void _publish(LogRecord record) { | 188 void _publish(LogRecord record) { |
| 226 if (_controller != null) { | 189 if (_controller != null) { |
| 227 _controller.add(record); | 190 _controller.add(record); |
| 228 } | 191 } |
| 229 } | 192 } |
| 230 | 193 |
| 231 /** Top-level root [Logger]. */ | 194 /** Top-level root [Logger]. */ |
| 232 static Logger get root => new Logger(''); | 195 static Logger get root => new Logger(''); |
| 233 | 196 |
| 234 /** All [Logger]s in the system. */ | 197 /** All [Logger]s in the system. */ |
| 235 static Map<String, Logger> _loggers; | 198 static Map<String, Logger> _loggers; |
| 236 } | 199 } |
| 237 | 200 |
| 238 | 201 |
| 239 /** Handler callback to process log entries as they are added to a [Logger]. */ | 202 /** Handler callback to process log entries as they are added to a [Logger]. */ |
| 240 typedef void LoggerHandler(LogRecord); | 203 typedef void LoggerHandler(LogRecord); |
| 241 | 204 |
| 242 | |
| 243 /** Event manager for a [Logger] (holds events that a [Logger] can fire). */ | |
| 244 class LoggerEvents { | |
| 245 final Logger _logger; | |
| 246 | |
| 247 LoggerEvents(this._logger); | |
| 248 | |
| 249 /** Event fired when a log record is added to a [Logger]. */ | |
| 250 LoggerHandlerList get record => new LoggerHandlerList(_logger); | |
| 251 } | |
| 252 | |
| 253 | |
| 254 /** List of handlers that will be called on a logger event. */ | |
| 255 class LoggerHandlerList { | |
| 256 Logger _logger; | |
| 257 | |
| 258 LoggerHandlerList(this._logger); | |
| 259 | |
| 260 void add(LoggerHandler handler) => _logger._addHandler(handler); | |
| 261 void remove(LoggerHandler handler) => _logger._removeHandler(handler); | |
| 262 void clear() => _logger.clearListeners(); | |
| 263 } | |
| 264 | |
| 265 | |
| 266 /** | 205 /** |
| 267 * [Level]s to control logging output. Logging can be enabled to include all | 206 * [Level]s to control logging output. Logging can be enabled to include all |
| 268 * levels above certain [Level]. [Level]s are ordered using an integer | 207 * levels above certain [Level]. [Level]s are ordered using an integer |
| 269 * value [Level.value]. The predefined [Level] constants below are sorted as | 208 * value [Level.value]. The predefined [Level] constants below are sorted as |
| 270 * follows (in descending order): [Level.SHOUT], [Level.SEVERE], | 209 * follows (in descending order): [Level.SHOUT], [Level.SEVERE], |
| 271 * [Level.WARNING], [Level.INFO], [Level.CONFIG], [Level.FINE], [Level.FINER], | 210 * [Level.WARNING], [Level.INFO], [Level.CONFIG], [Level.FINE], [Level.FINER], |
| 272 * [Level.FINEST], and [Level.ALL]. | 211 * [Level.FINEST], and [Level.ALL]. |
| 273 * | 212 * |
| 274 * We recommend using one of the predefined logging levels. If you define your | 213 * We recommend using one of the predefined logging levels. If you define your |
| 275 * own level, make sure you use a value between those used in [Level.ALL] and | 214 * own level, make sure you use a value between those used in [Level.ALL] and |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 353 | 292 |
| 354 /** Associated exception message (if any) when recording errors messages. */ | 293 /** Associated exception message (if any) when recording errors messages. */ |
| 355 String exceptionText; | 294 String exceptionText; |
| 356 | 295 |
| 357 LogRecord( | 296 LogRecord( |
| 358 this.level, this.message, this.loggerName, | 297 this.level, this.message, this.loggerName, |
| 359 [time, this.exception, this.exceptionText]) : | 298 [time, this.exception, this.exceptionText]) : |
| 360 this.time = (time == null) ? new DateTime.now() : time, | 299 this.time = (time == null) ? new DateTime.now() : time, |
| 361 this.sequenceNumber = LogRecord._nextNumber++; | 300 this.sequenceNumber = LogRecord._nextNumber++; |
| 362 } | 301 } |
| OLD | NEW |