LogCabin
|
00001 /* Copyright (c) 2010-2012 Stanford University 00002 * Copyright (c) 2014-2015 Diego Ongaro 00003 * 00004 * Permission to use, copy, modify, and distribute this software for any 00005 * purpose with or without fee is hereby granted, provided that the above 00006 * copyright notice and this permission notice appear in all copies. 00007 * 00008 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES 00009 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 00010 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR 00011 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 00012 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 00013 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 00014 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 00015 */ 00016 00017 /** 00018 * \file 00019 * This file is used to control how LogCabin's debug log (event log) messages 00020 * are handled. When used by client applications, this should be accessed as 00021 * LogCabin::Client::Debug (the LogCabin::Core namespace is used internally in 00022 * LogCabin). 00023 */ 00024 00025 #include <cstdio> 00026 #include <initializer_list> 00027 #include <functional> 00028 #include <ostream> 00029 #include <string> 00030 #include <utility> 00031 #include <vector> 00032 00033 #ifndef LOGCABIN_INCLUDE_LOGCABIN_DEBUG_H 00034 #define LOGCABIN_INCLUDE_LOGCABIN_DEBUG_H 00035 00036 namespace LogCabin { 00037 namespace Core { 00038 namespace Debug { 00039 00040 /** 00041 * The levels of verbosity for log messages. Higher values are noisier. 00042 * 00043 * \since LogCabin v1.1.0. New levels may be added in future minor releases 00044 * (adding a new level is considered backwards-compatible), so use 'default' 00045 * values in switch statements. 00046 */ 00047 enum class LogLevel { 00048 // If you change this enum, you should also update logLevelToString() and 00049 // logLevelFromString() in Core/Debug.cc. 00050 /** 00051 * This log level is just used for disabling all log messages, which is 00052 * really only useful in unit tests. 00053 */ 00054 SILENT = 0, 00055 /** 00056 * Bad stuff that shouldn't happen. The system broke its contract to users 00057 * in some way or some major assumption was violated. 00058 */ 00059 ERROR = 10, 00060 /** 00061 * Messages at the WARNING level indicate that, although something went 00062 * wrong or something unexpected happened, it was transient and 00063 * recoverable. 00064 */ 00065 WARNING = 20, 00066 /** 00067 * A system message that might be useful for administrators and developers. 00068 */ 00069 NOTICE = 30, 00070 /** 00071 * Messages at the VERBOSE level don't necessarily indicate that anything 00072 * went wrong, but they could be useful in diagnosing problems. 00073 */ 00074 VERBOSE = 40, 00075 }; 00076 00077 /** 00078 * When LogCabin wants to print a log message, this is the information that 00079 * gets included. 00080 */ 00081 struct DebugMessage { 00082 /// Default constructor. 00083 DebugMessage(); 00084 /// Copy constructor. 00085 DebugMessage(const DebugMessage& other); 00086 /// Move constructor. 00087 DebugMessage(DebugMessage&& other); 00088 /// Destructor. 00089 ~DebugMessage(); 00090 /// Copy assignment. 00091 DebugMessage& operator=(const DebugMessage& other); 00092 /// Move assignment. 00093 DebugMessage& operator=(DebugMessage&& other); 00094 00095 /// The output of __FILE__. 00096 const char* filename; 00097 /// The output of __LINE__. 00098 int linenum; 00099 /// The output of __FUNCTION__. 00100 const char* function; 00101 /// The level of importance of the message as an integer. This should have 00102 /// been of type LogLevel but int was exposed originally; int is used for 00103 /// backwards compatibility. 00104 int logLevel; 00105 /// The level of importance of the message as a static string. 00106 const char* logLevelString; 00107 /// The name of the current process (its PID or server ID). 00108 std::string processName; 00109 /// The name of the current thread (by its function or its thread ID). 00110 std::string threadName; 00111 /// The contents of the message. 00112 std::string message; 00113 }; 00114 00115 /** 00116 * Return the filename given to the last successful call to setLogFilename(), 00117 * or the empty string if none. 00118 * \since LogCabin v1.1.0. 00119 */ 00120 std::string getLogFilename(); 00121 00122 /** 00123 * Open the given file by name and append future debug log messages to it. 00124 * Note that if a handler is set with setLogHandler, this file will not be 00125 * used. 00126 * \param filename 00127 * Name of file. If it already exists, new messages will be appended at 00128 * the end. If the file is already open, this will re-open it (useful for 00129 * rotating logs). 00130 * \return 00131 * Error message if errors were encountered opening the file, otherwise an 00132 * empty string indicates success. 00133 * \since LogCabin v1.1.0. 00134 */ 00135 std::string setLogFilename(const std::string& filename); 00136 00137 /** 00138 * Called to rotate the log file. 00139 * If there was a previous call to setLogFilename(), this will reopen that file 00140 * by name, returning any errors. Otherwise, it will do nothing. 00141 * \return 00142 * Error message if errors were encountered in reopening the file, 00143 * otherwise an empty string indicates success. 00144 * \since LogCabin v1.1.0. 00145 */ 00146 std::string reopenLogFromFilename(); 00147 00148 /** 00149 * Change the file on which debug log messages are written. 00150 * 00151 * Note that if a handler is set with setLogHandler, this file will not be 00152 * used. If a filename has been set with setLogFilename(), this will clear it. 00153 * 00154 * \param newFile 00155 * Handle to open file where log messages will be written. 00156 * \return 00157 * Handle to previous log file (initialized to stderr on process start). 00158 */ 00159 FILE* 00160 setLogFile(FILE* newFile); 00161 00162 00163 /** 00164 * Accept log messages on the given callback instead of writing them to a file. 00165 * Call this again with an empty std::function() to clear it. 00166 * \param newHandler 00167 * Callback invoked once per log message, possibly concurrently. 00168 * \return 00169 * Previous callback (initialized to empty std::function on process start). 00170 */ 00171 std::function<void(DebugMessage)> 00172 setLogHandler(std::function<void(DebugMessage)> newHandler); 00173 00174 /** 00175 * Return the current log policy (as set by a previous call to setLogPolicy). 00176 * Note that this may be empty, indicating that the default level of NOTICE is 00177 * in use. 00178 * \since LogCabin v1.1.0. 00179 */ 00180 std::vector<std::pair<std::string, std::string>> 00181 getLogPolicy(); 00182 00183 /** 00184 * Specify the log messages that should be displayed for each filename. 00185 * This first component is a pattern; the second is a log level. 00186 * A filename is matched against each pattern in order: if the filename starts 00187 * with or ends with the pattern, the corresponding log level defines the most 00188 * verbose messages that are to be displayed for the file. If a filename 00189 * matches no pattern, its log level will default to NOTICE. 00190 */ 00191 void 00192 setLogPolicy(const std::vector< 00193 std::pair<std::string, std::string>>& newPolicy); 00194 /** 00195 * See setLogPolicy. 00196 */ 00197 void 00198 setLogPolicy(const std::initializer_list< 00199 std::pair<std::string, std::string>>& newPolicy); 00200 00201 /** 00202 * Build a log policy from its string representation. 00203 * \param in 00204 * A string of the form "pattern@level,pattern@level,level". 00205 * The pattern is separated from the level by an at symbol. Multiple rules 00206 * are separated by comma. A rule with an empty pattern (match all) does 00207 * not need an at symbol. 00208 * \return 00209 * Logging policy based on string description. 00210 * \since LogCabin v1.1.0. 00211 */ 00212 std::vector<std::pair<std::string, std::string>> 00213 logPolicyFromString(const std::string& in); 00214 00215 /** 00216 * Serialize a log policy into a string representation. 00217 * \param policy 00218 * Logging policy in the format required by setLogPolicy. 00219 * \return 00220 * String representation as accepted by logPolicyFromString. 00221 * \since LogCabin v1.1.0. 00222 */ 00223 std::string 00224 logPolicyToString(const std::vector< 00225 std::pair<std::string, std::string>>& policy); 00226 00227 } // namespace LogCabin::Core::Debug 00228 } // namespace LogCabin::Core 00229 } // namespace LogCabin 00230 00231 #endif /* LOGCABIN_INCLUDE_LOGCABIN_DEBUG_H */