1// Copyright 2018 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5import 'dart:core'; 6import 'dart:io'; 7 8/// Determines the level of logging. 9/// 10/// Verbosity is increasing from one (none) to five (fine). The sixth level 11/// (all) logs everything. 12enum LoggingLevel { 13 /// Logs no logs. 14 none, 15 16 /// Logs severe messages at the most (severe messages are always logged). 17 /// 18 /// Severe means that the process has encountered a critical level of failure 19 /// in which it cannot recover and will terminate as a result. 20 severe, 21 22 /// Logs warning messages at the most. 23 /// 24 /// Warning implies that an error was encountered, but the process will 25 /// attempt to continue, and may/may not succeed. 26 warning, 27 28 /// Logs info messages at the most. 29 /// 30 /// An info message is for determining information about the state of the 31 /// application as it runs through execution. 32 info, 33 34 /// Logs fine logs at the most. 35 /// 36 /// A fine message is one that is not important for logging outside of 37 /// debugging potential issues in the application. 38 fine, 39 40 /// Logs everything. 41 all, 42} 43 44/// Signature of a function that logs a [LogMessage]. 45typedef LoggingFunction = void Function(LogMessage log); 46 47/// The default logging function. 48/// 49/// Runs the [print] function using the format string: 50/// '[${log.levelName}]::${log.tag}--${log.time}: ${log.message}' 51/// 52/// Exits with status code 1 if the `log` is [LoggingLevel.severe]. 53LoggingFunction defaultLoggingFunction = (LogMessage log) { 54 print('[${log.levelName}]::${log.tag}--${log.time}: ${log.message}'); 55 if (log.level == LoggingLevel.severe) { 56 exit(1); 57 } 58}; 59 60/// Represents a logging message created by the logger. 61/// 62/// Includes a message, the time the message was created, the level of the log 63/// as an enum, the name of the level as a string, and a tag. This class is used 64/// to print from the global logging function defined in 65/// [Logger.loggingFunction] (a function that can be user-defined). 66class LogMessage { 67 /// Creates a log, including the level of the log, the time it was created, 68 /// and the actual log message. 69 /// 70 /// When this message is created, it sets its [time] to [DateTime.now]. 71 LogMessage(this.message, this.tag, this.level) 72 : levelName = level.toString().substring(level.toString().indexOf('.') + 1), 73 time = DateTime.now(); 74 75 /// The actual log message. 76 final String message; 77 78 /// The time the log message was created. 79 final DateTime time; 80 81 /// The level of this log. 82 final LoggingLevel level; 83 84 /// The human readable level of this log. 85 final String levelName; 86 87 /// The tag associated with the message. This is set to [Logger.tag] when 88 /// emitted by a [Logger] object. 89 final String tag; 90} 91 92/// Logs messages using the global [LoggingFunction] and logging level. 93/// 94/// Example of setting log level to [LoggingLevel.warning] and creating a 95/// logging function: 96/// 97/// ```dart 98/// Logger.globalLevel = LoggingLevel.warning; 99/// ``` 100class Logger { 101 /// Creates a logger with the given [tag]. 102 Logger(this.tag); 103 104 /// The tag associated with the log message (usable in the logging function). 105 /// [LogMessage] objects emitted by this class will have [LogMessage.tag] set 106 /// to this value. 107 final String tag; 108 109 /// Determines what to do when the [Logger] creates and attempts to log a 110 /// [LogMessage] object. 111 /// 112 /// This function can be reassigned to whatever functionality of your 113 /// choosing, so long as it has the same signature of [LoggingFunction] (it 114 /// can also be an asynchronous function, if doing file I/O, for 115 /// example). 116 static LoggingFunction loggingFunction = defaultLoggingFunction; 117 118 /// Determines the logging level all [Logger] instances use. 119 static LoggingLevel globalLevel = LoggingLevel.none; 120 121 /// Logs a [LoggingLevel.severe] level `message`. 122 /// 123 /// Severe messages are always logged, regardless of what level is set. 124 void severe(String message) { 125 loggingFunction(LogMessage(message, tag, LoggingLevel.severe)); 126 } 127 128 /// Logs a [LoggingLevel.warning] level `message`. 129 void warning(String message) { 130 if (globalLevel.index >= LoggingLevel.warning.index) { 131 loggingFunction(LogMessage(message, tag, LoggingLevel.warning)); 132 } 133 } 134 135 /// Logs a [LoggingLevel.info] level `message`. 136 void info(String message) { 137 if (globalLevel.index >= LoggingLevel.info.index) { 138 loggingFunction(LogMessage(message, tag, LoggingLevel.info)); 139 } 140 } 141 142 /// Logs a [LoggingLevel.fine] level `message`. 143 void fine(String message) { 144 if (globalLevel.index >= LoggingLevel.fine.index) { 145 loggingFunction(LogMessage(message, tag, LoggingLevel.fine)); 146 } 147 } 148} 149