/* * Copyright (C) 2015 by Multi-Tech Systems * * This file is part of libmts. * * libmts is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * libmts is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with libmts. If not, see . * */ #include #include #include #include #include #include #include #include #include using namespace MTS; const char* Logger::PrintLevel::OFF_LABEL = "OFF"; const char* Logger::PrintLevel::FATAL_LABEL = "FATAL"; const char* Logger::PrintLevel::ERROR_LABEL = "ERROR"; const char* Logger::PrintLevel::WARNING_LABEL = "WARNING"; const char* Logger::PrintLevel::INFO_LABEL = "INFO"; const char* Logger::PrintLevel::CONFIG_LABEL = "CONFIG"; const char* Logger::PrintLevel::DEBUG_LABEL = "DEBUG"; const char* Logger::PrintLevel::TRACE_LABEL = "TRACE"; const char* Logger::PrintLevel::MAXIMUM_LABEL = "MAXIMUM"; const int Logger::PrintLevel::OFF_LEVEL = 0; const int Logger::PrintLevel::MINIMUM_LEVEL = 1; const int Logger::PrintLevel::FATAL_LEVEL = 1; const int Logger::PrintLevel::ERROR_LEVEL = 10; const int Logger::PrintLevel::WARNING_LEVEL = 20; const int Logger::PrintLevel::INFO_LEVEL = 30; const int Logger::PrintLevel::CONFIG_LEVEL = 40; const int Logger::PrintLevel::DEBUG_LEVEL = 50; const int Logger::PrintLevel::TRACE_LEVEL = 60; const int Logger::PrintLevel::MAXIMUM_LEVEL = 100; volatile int Logger::m_iPrintLevel = Logger::PrintLevel::MAXIMUM_LEVEL; std::string Logger::m_sPrintLevel = Logger::PrintLevel::MAXIMUM_LABEL; Logger::PrintMode Logger::m_eMode = Logger::PrintMode::STDOUT_ONLY; FILE* Logger::m_pFile = NULL; int Logger::m_iLogFacility = -1; Lock Logger::m_oPrintLock; std::string Logger::m_sIdent; std::string Logger::m_sFileName; int Logger::getPrintLevel() { return m_iPrintLevel; } const std::string& Logger::getPrintLevelString() { if (m_iPrintLevel == PrintLevel::OFF_LEVEL) m_sPrintLevel = std::string(PrintLevel::OFF_LABEL); else if (m_iPrintLevel == PrintLevel::FATAL_LEVEL) m_sPrintLevel = std::string(PrintLevel::FATAL_LABEL); else if (m_iPrintLevel > PrintLevel::FATAL_LEVEL && m_iPrintLevel <= PrintLevel::ERROR_LEVEL) m_sPrintLevel = std::string(PrintLevel::ERROR_LABEL); else if (m_iPrintLevel > PrintLevel::ERROR_LEVEL && m_iPrintLevel <= PrintLevel::WARNING_LEVEL) m_sPrintLevel = std::string(PrintLevel::WARNING_LABEL); else if (m_iPrintLevel > PrintLevel::WARNING_LEVEL && m_iPrintLevel <= PrintLevel::INFO_LEVEL) m_sPrintLevel = std::string(PrintLevel::INFO_LABEL); else if (m_iPrintLevel > PrintLevel::INFO_LEVEL && m_iPrintLevel <= PrintLevel::CONFIG_LEVEL) m_sPrintLevel = std::string(PrintLevel::CONFIG_LABEL); else if (m_iPrintLevel > PrintLevel::CONFIG_LEVEL && m_iPrintLevel <= PrintLevel::DEBUG_LEVEL) m_sPrintLevel = std::string(PrintLevel::DEBUG_LABEL); else if (m_iPrintLevel > PrintLevel::DEBUG_LEVEL && m_iPrintLevel <= PrintLevel::TRACE_LEVEL) m_sPrintLevel = std::string(PrintLevel::TRACE_LABEL); else m_sPrintLevel = std::string(PrintLevel::MAXIMUM_LABEL); return m_sPrintLevel; } void Logger::setPrintLevel(int32_t level, bool silent) { m_iPrintLevel = level; if (!silent) { printf(level, "Logger Level Changed to %d\n", level); } } bool Logger::isPrintable(int32_t level) { int32_t currentLevel = getPrintLevel(); return (level <= currentLevel) && (currentLevel > PrintLevel::OFF_LEVEL); } int32_t Logger::syslogPrintLevelConversion(const int32_t& level) { if (level < 10) { return LOG_EMERG; } else if (level < 20) { return LOG_ERR; } else if (level < 30) { return LOG_WARNING; } else if (level < 50) { return LOG_INFO; } else { return LOG_DEBUG; } } void Logger::printMessage(const int32_t& level, const char* label, const char* format, va_list argptr) { m_oPrintLock.lock(); switch (m_eMode) { case Logger::PrintMode::STDOUT_ONLY: ::printf("%s|%s|", MTS::Text::time(MTS::System::timeMicros()).c_str(), label); vprintf(format, argptr); ::printf("\n"); break; case Logger::PrintMode::STDERR_ONLY: fprintf(stderr, "%s|%s|", MTS::Text::time(MTS::System::timeMicros()).c_str(), label); vfprintf(stderr, format, argptr); fprintf(stderr, "\n"); break; case Logger::PrintMode::FILE_ONLY: fprintf(m_pFile, "%s|%s| ", MTS::Text::time(MTS::System::timeMicros()).c_str(), label); vfprintf(m_pFile, format, argptr); fprintf(m_pFile, "\n"); fflush(m_pFile); break; case Logger::PrintMode::SYSLOG_ONLY: if (level <= Logger::PrintLevel::TRACE_LEVEL) { vsyslog(syslogPrintLevelConversion(level), format, argptr); } break; case Logger::PrintMode::STDOUT_AND_FILE: { const std::string timestr(MTS::Text::time(MTS::System::timeMicros())); va_list argptr2; va_copy(argptr2, argptr); ::printf("%s|%s|", timestr.c_str(), label); vprintf(format, argptr); ::printf("\n"); fprintf(m_pFile, "%s|%s| ", timestr.c_str(), label); vfprintf(m_pFile, format, argptr2); fprintf(m_pFile, "\n"); fflush(m_pFile); va_end(argptr2); } break; case Logger::PrintMode::STDOUT_AND_SYSLOG: { if (level <= Logger::PrintLevel::TRACE_LEVEL) { va_list argptr2; va_copy(argptr2, argptr); vsyslog(syslogPrintLevelConversion(level), format, argptr2); va_end(argptr2); } ::printf("%s|", MTS::Text::time(MTS::System::timeMicros()).c_str()); ::printf("%s|", label); vprintf(format, argptr); ::printf("\n"); } break; case Logger::PrintMode::NO_PRINTING: default: break; } m_oPrintLock.unlock(); } void Logger::printfFatal(const char* format, ...) { if (isPrintable(PrintLevel::FATAL_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::FATAL_LEVEL, PrintLevel::FATAL_LABEL, format, argptr); va_end(argptr); } } void Logger::printfError(const char* format, ...) { if (isPrintable(PrintLevel::ERROR_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::ERROR_LEVEL, PrintLevel::ERROR_LABEL, format, argptr); va_end(argptr); } } void Logger::printfWarning(const char* format, ...) { if (isPrintable(PrintLevel::WARNING_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::WARNING_LEVEL, PrintLevel::WARNING_LABEL, format, argptr); va_end(argptr); } } void Logger::printfInfo(const char* format, ...) { if (isPrintable(PrintLevel::INFO_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::INFO_LEVEL, PrintLevel::INFO_LABEL, format, argptr); va_end(argptr); } } void Logger::printfConfig(const char* format, ...) { if (isPrintable(PrintLevel::CONFIG_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::CONFIG_LEVEL, PrintLevel::CONFIG_LABEL, format, argptr); va_end(argptr); } } void Logger::printfDebug(const char* format, ...) { if (isPrintable(PrintLevel::DEBUG_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::DEBUG_LEVEL, PrintLevel::DEBUG_LABEL, format, argptr); va_end(argptr); } } void Logger::printfTrace(const char* format, ...) { if (isPrintable(PrintLevel::TRACE_LEVEL)) { va_list argptr; va_start(argptr, format); printMessage(PrintLevel::TRACE_LEVEL, PrintLevel::TRACE_LABEL, format, argptr); va_end(argptr); } } void Logger::printfGeneric(int level, const char* label, const char* format, ...) { va_list argptr; va_start(argptr, format); printMessage(level, label, format, argptr); va_end(argptr); } void Logger::printf(int level, const char* format, ...) { if (isPrintable(level)) { va_list argptr; va_start(argptr, format); m_oPrintLock.lock(); vprintf(format, argptr); m_oPrintLock.unlock(); va_end(argptr); } } void Logger::printf(const char* format, ...) { if (isPrintable(PrintLevel::MAXIMUM_LEVEL)) { va_list argptr; va_start(argptr, format); m_oPrintLock.lock(); vprintf(format, argptr); m_oPrintLock.unlock(); va_end(argptr); } } bool Logger::setup(const PrintMode& mode) { m_oPrintLock.lock(); m_eMode = mode; m_oPrintLock.unlock(); return true; } bool Logger::setup(const PrintMode& mode, const std::string& filename) { /* close the handle and reopen it each time setup() is called in case * we are being used with programs like logrotate, etc * * if the file is different, switch to the new file */ m_oPrintLock.lock(); if (m_pFile) { fclose(m_pFile); } if (m_sFileName != filename) { m_sFileName = filename; } m_pFile = fopen(m_sFileName.c_str(), "a"); m_iLogFacility = -1; m_oPrintLock.unlock(); if (!m_pFile) { fprintf(stderr, "Error opening logfile %s\n", m_sFileName.c_str()); return false; } m_eMode = mode; return true; } bool Logger::setup(const PrintMode& mode, const std::string& ident, const int& option, const int& facility) { m_oPrintLock.lock(); m_pFile = NULL; m_sFileName = ""; m_iLogFacility = facility; m_sIdent = ident; m_eMode = mode; m_oPrintLock.unlock(); openlog(m_sIdent.c_str(), option, m_iLogFacility); return true; }