#ifndef __Log_h__ #define __Log_h__ #include "File.h" #include "LogListener.h" #include #include #include namespace coreutils { class ConsoleServer; static const int LOG_NONE = 0; static const int LOG_INFO = 1; static const int LOG_WARN = 2; static const int LOG_EXCEPT = 4; static const int LOG_DEBUG_1 = 8; static const int LOG_DEBUG_2 = 16; static const int LOG_DEBUG_3 = 32; static const int LOG_DEBUG_4 = 64; /// /// Log /// /// Provides easy to access and use logging features to maintain a /// history of activity and provide information for activity debugging. /// class Log : public std::ostringstream { public: /// /// Constructor method that accepts a pointer to a log listener /// This enables the Log object to send new log /// messages to the connected listener. /// /// @param consoleServer a pointer to the console server that will /// be used to echo log entries. /// Log(LogListener *logListener); /// /// Constructor method accepts a file object that will be used to /// echo all log entries. This provides a permanent disk file record /// of all logged activity. /// Log(File *logFile); /// /// Constructor method that is used to send a message to the log. /// /// @param level the logging level to associate with this message. /// /// To send log message: Log(LOG_INFO) << "This is a log message."; /// Log(int level); /// /// The destructor for the log object. /// ~Log(); bool output = false; /// /// Set the logListener to point to the instantiated LogListener /// object for the application. /// static LogListener *logListener; /// /// Specify a File object where the log entries will be written as /// a permanent record to disk. /// static File *logFile; /// /// A meaningless sequenctial number that starts from 0 at the /// beginning of the logging process. /// static int seq; /// /// Rotation threshold for the static logFile, in bytes - checked /// after every write that reaches it. Default 100MB. Change it /// any time (takes effect on the next log call); 0 disables /// rotation entirely. /// static size_t maxLogSize; /// /// How many rotated-out backups (logFile.1, logFile.2, ...) to /// keep once maxLogSize is hit - the oldest beyond this count is /// deleted outright, not just renamed away. Default 5. /// static int maxLogBackups; private: // Static, not per-instance - every Log(level) call constructs // and destructs its own temporary Log object, so a per-instance // mutex (the original declaration here) provided no actual // mutual exclusion between concurrent threads at all, each // locking a separate mutex of their own. Only became load-bearing // once rotation was added: two threads racing between "check // size" and "close/rename/reopen" on the one shared logFile // could otherwise write to a stale fd mid-rotation or rotate out // from under an in-flight write. static std::mutex mtx; }; } #endif