diff options
Diffstat (limited to 'src/MTS_Logger.cpp')
-rw-r--r-- | src/MTS_Logger.cpp | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/src/MTS_Logger.cpp b/src/MTS_Logger.cpp new file mode 100644 index 0000000..93775fe --- /dev/null +++ b/src/MTS_Logger.cpp @@ -0,0 +1,312 @@ +/* + * 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 <http://www.gnu.org/licenses/>. + * + */ + +#include <mts/MTS_Logger.h> +#include <mts/MTS_Lock.h> +#include <mts/MTS_Text.h> +#include <mts/MTS_System.h> +#include <stdio.h> +#include <errno.h> +#include <stdarg.h> +#include <syslog.h> + +#include <iostream> + +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::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; +} + |