LogCabin
include/LogCabin/Debug.h
Go to the documentation of this file.
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 */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines