#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; namespace logging = boost::log; namespace keywords = boost::log::keywords; namespace expr = boost::log::expressions; namespace attr = boost::log::attributes; namespace src = boost::log::sources; #define LFC1_LOG(logger, level) BOOST_LOG_SEV(logger, level) << "(" << __FILE__ << ", " << __LINE__ << ") " #define LFC1_LOG_TRACE(logger) LFC1_LOG(logger, trace) #define LFC1_LOG_DEBUG(logger) LFC1_LOG(logger, debug) #define LFC1_LOG_INFO(logger) LFC1_LOG(logger, info) #define LFC1_LOG_WARNING(logger) LFC1_LOG(logger, warning) #define LFC1_LOG_ERROR(logger) LFC1_LOG(logger, error) static const auto RET_SUCCESS = 0; static const auto RET_FAIL = 1; static const auto LOGGING_ENVIRONMENT_NAME = "LOGGING_CONFIG_FILE_NAME"; static const auto DEFAULT_LOGGING_CONFIG_FILE_NAME = "config/LogSettings.txt"; enum ESeverityLevel { trace, debug, info, warning, error }; BOOST_LOG_ATTRIBUTE_KEYWORD(severity, "Severity", ESeverityLevel) ostream& operator<<(ostream& arStream, ESeverityLevel avLevel) { static const char* pStrings[] = { "trace", "debug", "info", "warning", "error" }; if (static_cast(avLevel) < sizeof(pStrings) / sizeof(*pStrings)) { arStream << pStrings[avLevel]; } else { arStream << static_cast(avLevel); } return arStream; } logging::formatting_ostream& operator<< ( logging::formatting_ostream& arStream, logging::to_log_manip const& arManip ) { static const char* pStrings[] = { "TRACE", "DEBUG", "INFO", "WARNING", "ERROR" }; ESeverityLevel vLevel = arManip.get(); if (static_cast(vLevel) < sizeof(pStrings) / sizeof(*pStrings)) { arStream << pStrings[vLevel]; } else { arStream << static_cast(vLevel); } return arStream; } BOOST_LOG_INLINE_GLOBAL_LOGGER_DEFAULT(SLogger, src::severity_logger) static void gvLoggingInit(const char* apConfigFileName = nullptr) { // Obtain the name of the logging configuration file. if (apConfigFileName == nullptr || apConfigFileName[0] == 0) { if ((apConfigFileName = getenv(LOGGING_ENVIRONMENT_NAME)) == 0 || apConfigFileName[0] == 0) { apConfigFileName = DEFAULT_LOGGING_CONFIG_FILE_NAME; } } // Open the logging configuration file. ifstream vConfigFile(apConfigFileName); if (!vConfigFile.is_open()) { // TODO: throw an exception } // Read the contents of the logging configuration file. logging::init_from_stream(vConfigFile); // Add the logging attributes that we require. auto pCore = logging::core::get(); pCore->add_global_attribute("TimeStamp", attr::local_clock()); pCore->add_global_attribute("Process", attr::current_process_name()); pCore->add_global_attribute("ProcessID", attr::current_process_id()); pCore->add_global_attribute("ThreadID", attr::current_thread_id()); pCore->set_filter(severity >= info); } int main() { auto vRetVal = RET_SUCCESS; try { gvLoggingInit(); auto& vLogger = SLogger::get(); LFC1_LOG_TRACE(vLogger) << "A trace severity message"; LFC1_LOG_DEBUG(vLogger) << "A debug severity message"; LFC1_LOG_INFO(vLogger) << "An informational severity message"; LFC1_LOG_WARNING(vLogger) << "A warning severity message"; LFC1_LOG_ERROR(vLogger) << "An error severity message"; } catch (exception& crException) { cerr << crException.what() << endl; vRetVal = RET_FAIL; } catch (...) { cerr << "Unknown exception" << endl; vRetVal = RET_FAIL; } return vRetVal; }