From 051dacaf0e49ec143336ece79ca63ada41510928 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 24 Mar 2017 14:38:57 +0100 Subject: [PATCH] feat(src/app/Logger): use a relative context path and thread safe --- linphone-desktop/CMakeLists.txt | 1 + linphone-desktop/src/app/App.cpp | 7 +- linphone-desktop/src/app/Logger.cpp | 111 +++++++++++++++++----------- linphone-desktop/src/app/Logger.hpp | 23 ++++-- linphone-desktop/src/utils.cpp | 41 ++++++++++ linphone-desktop/src/utils.hpp | 2 + 6 files changed, 133 insertions(+), 52 deletions(-) create mode 100644 linphone-desktop/src/utils.cpp diff --git a/linphone-desktop/CMakeLists.txt b/linphone-desktop/CMakeLists.txt index 32df419ca..afc831eab 100644 --- a/linphone-desktop/CMakeLists.txt +++ b/linphone-desktop/CMakeLists.txt @@ -106,6 +106,7 @@ set(SOURCES src/components/timeline/TimelineModel.cpp src/externals/single-application/SingleApplication.cpp src/main.cpp + src/utils.cpp ) set(HEADERS diff --git a/linphone-desktop/src/app/App.cpp b/linphone-desktop/src/app/App.cpp index 0cf3a086d..2651ef43f 100644 --- a/linphone-desktop/src/app/App.cpp +++ b/linphone-desktop/src/app/App.cpp @@ -176,11 +176,12 @@ void App::parseArgs () { m_parser.process(*this); - // Initialise logger (do not do this before this point because the application has to be created - // for the logs to be put in the correct directory + // Initialize logger. (Do not do this before this point because the + // application has to be created for the logs to be put in the correct + // directory.) Logger::init(); if (m_parser.isSet("verbose")) { - Logger::instance()->setVerbose(true); + Logger::getInstance()->setVerbose(true); } } diff --git a/linphone-desktop/src/app/Logger.cpp b/linphone-desktop/src/app/Logger.cpp index 58a0fd4c0..981267379 100644 --- a/linphone-desktop/src/app/Logger.cpp +++ b/linphone-desktop/src/app/Logger.cpp @@ -24,6 +24,7 @@ #include #include +#include "../utils.hpp" #include "Paths.hpp" #include "Logger.hpp" @@ -48,54 +49,19 @@ #define MAX_LOGS_COLLECTION_SIZE 104857600 /* 100MB. */ +#define SRC_PATTERN "/linphone-desktop/src/" + +using namespace std; + // ============================================================================= +QMutex Logger::m_mutex; + Logger *Logger::m_instance = nullptr; // ----------------------------------------------------------------------------- -static void qtLogger (QtMsgType type, const QMessageLogContext &context, const QString &msg) { - const char *format; - BctbxLogLevel level; - - if (type == QtDebugMsg) { - format = GREEN "[%s][Debug]" PURPLE "%s" RESET "%s\n"; - level = BCTBX_LOG_DEBUG; - } else if (type == QtInfoMsg) { - format = BLUE "[%s][Info]" PURPLE "%s" RESET "%s\n"; - level = BCTBX_LOG_MESSAGE; - } else if (type == QtWarningMsg) { - format = RED "[%s][Warning]" PURPLE "%s" RESET "%s\n"; - level = BCTBX_LOG_WARNING; - } else if (type == QtCriticalMsg) { - format = RED "[%s][Critical]" PURPLE "%s" RESET "%s\n"; - level = BCTBX_LOG_ERROR; - } else if (type == QtFatalMsg) { - format = RED "[%s][Fatal]" PURPLE "%s" RESET "%s\n"; - level = BCTBX_LOG_FATAL; - } else - return; - - const char *context_str = ""; - - #ifdef QT_MESSAGELOGCONTEXT - QByteArray context_arr = QStringLiteral("%1:%2: ").arg(context.file).arg(context.line).toLocal8Bit(); - context_str = context_arr.constData(); - #endif // ifdef QT_MESSAGELOGCONTEXT - - QByteArray local_msg = msg.toLocal8Bit(); - QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit(); - - fprintf(stderr, format, date_time.constData(), context_str, local_msg.constData()); - bctbx_log(QT_DOMAIN, level, "QT: %s%s", context_str, local_msg.constData()); - - if (type == QtFatalMsg) - abort(); -} - -// ----------------------------------------------------------------------------- - -static void linphoneLogger (const char *domain, OrtpLogLevel type, const char *fmt, va_list args) { +static void linphoneLog (const char *domain, OrtpLogLevel type, const char *fmt, va_list args) { const char *format; if (type == ORTP_DEBUG) @@ -126,18 +92,75 @@ static void linphoneLogger (const char *domain, OrtpLogLevel type, const char *f // ----------------------------------------------------------------------------- +void Logger::log (QtMsgType type, const QMessageLogContext &context, const QString &msg) { + const char *format; + BctbxLogLevel level; + + if (type == QtDebugMsg) { + format = GREEN "[%s][Debug]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_DEBUG; + } else if (type == QtInfoMsg) { + format = BLUE "[%s][Info]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_MESSAGE; + } else if (type == QtWarningMsg) { + format = RED "[%s][Warning]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_WARNING; + } else if (type == QtCriticalMsg) { + format = RED "[%s][Critical]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_ERROR; + } else if (type == QtFatalMsg) { + format = RED "[%s][Fatal]" PURPLE "%s" RESET "%s\n"; + level = BCTBX_LOG_FATAL; + } else + return; + + const char *context_str = ""; + + #ifdef QT_MESSAGELOGCONTEXT + + QByteArray context_arr; + + { + const char *file = context.file; + const char *pos = file ? ::Utils::rstrstr(file, SRC_PATTERN) : file; + + context_arr = QStringLiteral("%1:%2: ") + .arg(pos ? pos + sizeof(SRC_PATTERN) - 1 : file) + .arg(context.line) + .toLocal8Bit(); + context_str = context_arr.constData(); + } + + #endif // ifdef QT_MESSAGELOGCONTEXT + + QByteArray local_msg = msg.toLocal8Bit(); + QByteArray date_time = QDateTime::currentDateTime().toString("HH:mm:ss").toLocal8Bit(); + + m_mutex.lock(); + + fprintf(stderr, format, date_time.constData(), context_str, local_msg.constData()); + bctbx_log(QT_DOMAIN, level, "QT: %s%s", context_str, local_msg.constData()); + + m_mutex.unlock(); + + if (type == QtFatalMsg) + abort(); +} + +// ----------------------------------------------------------------------------- + void Logger::init () { if (m_instance) return; m_instance = new Logger(); - qInstallMessageHandler(qtLogger); + qInstallMessageHandler(Logger::log); linphone_core_set_log_level(ORTP_MESSAGE); linphone_core_set_log_handler( [](const char *domain, OrtpLogLevel type, const char *fmt, va_list args) { if (m_instance->isVerbose()) - linphoneLogger(domain, type, fmt, args); + linphoneLog(domain, type, fmt, args); } ); diff --git a/linphone-desktop/src/app/Logger.hpp b/linphone-desktop/src/app/Logger.hpp index e08490be8..bf8acf1f2 100644 --- a/linphone-desktop/src/app/Logger.hpp +++ b/linphone-desktop/src/app/Logger.hpp @@ -23,23 +23,36 @@ #ifndef LOGGER_H_ #define LOGGER_H_ -#include +#include // ============================================================================= class Logger { public: - static void init (); - static Logger *instance () { return m_instance; }; + ~Logger () = default; - bool isVerbose () const { return m_verbose; }; - void setVerbose (bool verbose) { m_verbose = verbose; }; + bool isVerbose () const { + return m_verbose; + } + + void setVerbose (bool verbose) { + m_verbose = verbose; + } + + static void init (); + + static Logger *getInstance () { + return m_instance; + } private: Logger () = default; + static void log (QtMsgType type, const QMessageLogContext &context, const QString &msg); + bool m_verbose = false; + static QMutex m_mutex; static Logger *m_instance; }; diff --git a/linphone-desktop/src/utils.cpp b/linphone-desktop/src/utils.cpp new file mode 100644 index 000000000..a28221c08 --- /dev/null +++ b/linphone-desktop/src/utils.cpp @@ -0,0 +1,41 @@ +/* + * utils.cpp + * Copyright (C) 2017 Belledonne Communications, Grenoble, France + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: March 24, 2017 + * Author: Ronan Abhamon + */ + + #include "utils.hpp" + +// ============================================================================= + +char *Utils::rstrstr (const char *a, const char *b) { + size_t a_len = strlen(a); + size_t b_len = strlen(b); + const char *s; + + if (b_len > a_len) + return NULL; + + for (s = a + a_len - b_len; s >= a; --s) { + if (!strncmp(s, b, b_len)) + return const_cast(s); + } + + return NULL; +} diff --git a/linphone-desktop/src/utils.hpp b/linphone-desktop/src/utils.hpp index 77bb76c9c..98babd87a 100644 --- a/linphone-desktop/src/utils.hpp +++ b/linphone-desktop/src/utils.hpp @@ -49,6 +49,8 @@ namespace Utils { return findParentType(parent); } + + char *rstrstr (const char *a, const char *b); } #endif // UTILS_H_