summaryrefslogtreecommitdiff
path: root/src/MTS_Logger.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MTS_Logger.cpp')
-rw-r--r--src/MTS_Logger.cpp312
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;
+}
+