/* **************************************************************************** * Copyright 2019 Open Systems Development BV * * * * Permission is hereby granted, free of charge, to any person obtaining a * * copy of this software and associated documentation files (the "Software"), * * to deal in the Software without restriction, including without limitation * * the rights to use, copy, modify, merge, publish, distribute, sublicense, * * and/or sell copies of the Software, and to permit persons to whom the * * Software is furnished to do so, subject to the following conditions: * * * * The above copyright notice and this permission notice shall be included in * * all copies or substantial portions of the Software. * * * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * * DEALINGS IN THE SOFTWARE. * * ***************************************************************************/ #pragma once #include #include namespace osdev { namespace components { namespace log { #define LogEmergency(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Emergency)\ { \ osdev::components::log::Log::emergency(__FILE__, __LINE__, context, text); \ } #define LogAlert(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Alert) \ { \ osdev::components::log::Log::alert(__FILE__, __LINE__, context, text); \ } #define LogCritical(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Critical) \ { \ osdev::components::log::Log::critical(__FILE__, __LINE__, context, text); \ } #define LogError(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Error) \ { \ osdev::components::log::Log::error(__FILE__, __LINE__, context, text); \ } #define LogWarning(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Warning) \ { \ osdev::components::log::Log::warning(__FILE__, __LINE__, context, text); \ } #define LogNotice(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Notice) \ { \ osdev::components::log::Log::notice(__FILE__, __LINE__, context, text); \ } #define LogInfo(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Info) \ { \ osdev::components::log::Log::info(__FILE__, __LINE__, context, text); \ } #define LogDebug(context, text) \ if (osdev::components::log::Log::level() >= osdev::components::log::LogLevel::Debug) \ { \ osdev::components::log::Log::debug(__FILE__, __LINE__, context, text); \ } /*! * \brief The LogLevel enum * Enumeration class dealing with LogLevels. * Used to convert to syslog macro's. */ enum class LogLevel { Emergency = 0, Alert, Critical, Error, Warning, Notice, Info, Debug }; /*! * \brief The LogMask enum * Enumeration class dealing with LogMask. * Used to convert to syslog macro's. */ enum class LogMask { Mask = 0, Upto, None }; /*! \class Log \brief Basic logging mechanism. */ class Log { public: /** * @brief Initialize the logging mechanism * @param context - The main context * @param logFile - Logfile if available * @param logDepth - Initial log-depth */ static void init( const std::string& context, const std::string& logFile = std::string(), LogLevel logDepth = LogLevel::Info ); //! Shutdown the logging mechanism static void terminate(); /*! * \brief Write to syslog * \param priority - priority level [from debug up to emergency] * \param message - The string to print * \param context - The context name. default name is the name of the executable. */ static void write( const int &priority, const std::string &message, const std::string &context = std::string() ); /** * @brief Log an emergency message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void emergency( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log an alert message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void alert ( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log a critical message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void critical ( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log an error message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void error ( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log a warning message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void warning ( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log a notice message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void notice ( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log an info message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void info ( const char* file, int line, const std::string& category, const std::string& message ); /** * @brief Log a debug message in a category. * @param file - Name of the source-file * @param line - The line number in the source-file * @param category - The category of the message. * @param message - The string to print */ static void debug ( const char* file, int line, const std::string& category, const std::string& message ); /** * @return The current log level. */ static LogLevel level() { if( s_logMask == LogMask::None ) { return LogLevel::Debug; } return s_logLevel; } /*! * \brief setMask update the current logMask * \param logMask - Enum defining the logmask used. */ static void setMask ( LogMask logMask ) { s_logMask = logMask; } /*! * \brief setLogLevel update the current logLevel * \param logLevel - Enum defining the logLevel used, in combination with Mask. */ static void setLogLevel( LogLevel logLevel ) { s_logLevel = logLevel; } /*! * \brief setContext update the current context * \param context - String containing the new context name. */ static void setContext ( std::string context ) { s_context = context; } protected: /** * @brief Log an emergency message in a category. * @param category The category of the message. * @param message The string to print. */ static void emergency( const std::string& category, const std::string& message ); /** * @brief Log an alert message in a category. * @param category The category of the message. * @param message The string to print. */ static void alert ( const std::string& category, const std::string& message ); /** * @brief Log a critical message in a category. * @param category The category of the message. * @param message The string to print. */ static void critical ( const std::string& category, const std::string& message ); /** * @brief Log an error message in a category. * @param category The category of the message. * @param message The string to print. */ static void error ( const std::string& category, const std::string& message ); /** * @brief Log a warning message in a category. * @param category The category of the message. * @param message The string to print. */ static void warning ( const std::string& category, const std::string& message ); /** * @brief Log a notice message in a category. * @param category The category of the message. * @param message The string to print. */ static void notice ( const std::string& category, const std::string& message ); /** * @brief Log an info message in a category. * @param category The category of the message. * @param message The string to print. */ static void info ( const std::string& category, const std::string& message ); /** * @brief Log an debug message in a category. * @param category The category of the message. * @param message The string to print. */ static void debug ( const std::string& category, const std::string& message ); /** * @brief Log an error message in a category. * @param category The category of the message. * @param message The string to print. * @param level Selected log level */ static void log( const std::string &category, const std::string &message, LogLevel level ); private: /** * @brief Replace the characters in a std::string with other characters. * @param strToReplace The string we want to replace characters in * @param from_chars The characters we want to replace * @param to_chars The characters we want to replace with. * @return strToReplace This is the original string with the replaced characters. */ static void ReplaceAll( std::string &strToReplace, const std::string& from_chars, const std::string& to_chars ); /** * @brief Put filename, line-number and message in one string * @param file Source-file * @param line Line in source-file * @param message The string to print * @return Formatted string with file, line and message */ static std::string fileinfoMessage(const char* file, int line, const std::string& message); //! The main context. static std::string s_context; //! The name of the LogFile. static std::string s_fileName; //! The amount of logging static LogLevel s_logLevel; //! The mask static LogMask s_logMask; }; } // End namespace log } // End namespace components } // End namespace osdev