/* **************************************************************************** * 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 #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); \ } enum class LogLevel { Emergency = 0, Alert, Critical, Error, Warning, Notice, Info, Debug }; enum class LogMask { Mask = 0, Upto, None }; /*! \class Log \brief Basic logging mechanism. */ class Log { public: static void init( const std::string& context, const std::string& logFile = std::string(), LogLevel logDepth = LogLevel::Info ); static void terminate(); static void write( const int &priority, const std::string &message, const std::string &context = std::string() ); static void emergency( const char* file, int line, const std::string& category, const std::string& message ); static void alert ( const char* file, int line, const std::string& category, const std::string& message ); static void critical ( const char* file, int line, const std::string& category, const std::string& message ); static void error ( const char* file, int line, const std::string& category, const std::string& message ); static void warning ( const char* file, int line, const std::string& category, const std::string& message ); static void notice ( const char* file, int line, const std::string& category, const std::string& message ); static void info ( const char* file, int line, const std::string& category, const std::string& message ); 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; } static void setMask ( LogMask logMask ) { s_logMask = logMask; } static void setLogLevel( LogLevel logLevel ) { s_logLevel = logLevel; } static void setContext ( std::string context ) { s_context = context; } protected: static void emergency( const std::string& category, const std::string& message ); static void alert ( const std::string& category, const std::string& message ); static void critical ( const std::string& category, const std::string& message ); static void error ( const std::string& category, const std::string& message ); static void warning ( const std::string& category, const std::string& message ); static void notice ( const std::string& category, const std::string& message ); static void info ( const std::string& category, const std::string& message ); 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; //! Mutex to keep the logger thread-safe static std::mutex m_mutex; }; } // End namespace log } // End namespace components } // End namespace osdev