File indexing completed on 2024-05-12 05:09:25
0001 /*************************************************************************** 0002 Copyright (C) 2023 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "logger.h" 0026 0027 #include <QTextCodec> 0028 0029 namespace { 0030 const int MAX_LINES_BEFORE_FLUSH = 1000; 0031 } 0032 using Tellico::Logger; 0033 0034 Logger* Logger::self() { 0035 static Logger logger; 0036 return &logger; 0037 } 0038 0039 Logger::Logger(QObject* parent_) : QObject(parent_) { 0040 m_oldHandler = qInstallMessageHandler([](QtMsgType type, const QMessageLogContext& ctx, const QString& msg) { 0041 Logger::self()->log(type, ctx, msg); 0042 }); 0043 qSetMessagePattern(QStringLiteral("[%{time hh:mm:ss}] %{if-debug}[ %{file}:%{line} " 0044 " %{function} ] %{endif}%{if-warning}WARNING %{endif}%{message}")); 0045 } 0046 0047 Logger::~Logger() { 0048 if(m_logStream) { 0049 m_logStream->flush(); 0050 } 0051 qInstallMessageHandler(m_oldHandler); 0052 } 0053 0054 void Logger::log(const QString& msg_) { 0055 static int lineCounter = 0; 0056 if(!m_logStream) return; 0057 0058 QMutexLocker lock(&m_mutex); 0059 ++lineCounter; 0060 if(lineCounter > MAX_LINES_BEFORE_FLUSH) { 0061 lineCounter = 1; 0062 m_logStream->flush(); 0063 } 0064 0065 (*m_logStream) << msg_ << "\n"; 0066 } 0067 0068 void Logger::log(QtMsgType type_, const QMessageLogContext& ctx_, const QString& msg_) { 0069 if(!m_logStream) { 0070 // if there's no logging output defined, revert to previous behavior 0071 // but swallow info messages if they're in Tellico's category 0072 if(type_ != QtInfoMsg || strcmp(ctx_.category, "tellico") != 0) { 0073 m_oldHandler(type_, ctx_, msg_); 0074 } 0075 return; 0076 } 0077 0078 const auto& logMsg = qFormatLogMessage(type_, ctx_, msg_); 0079 log(logMsg); 0080 // also include default handling of warning and critical messages 0081 if(type_ != QtInfoMsg && type_ != QtDebugMsg) { 0082 m_oldHandler(type_, ctx_, msg_); 0083 } 0084 } 0085 0086 void Logger::setLogFile(const QString& logFile_) { 0087 QMutexLocker lock(&m_mutex); 0088 if(m_logStream) { 0089 m_logStream.reset(nullptr); 0090 m_logFile.close(); 0091 } 0092 0093 if(logFile_.isEmpty()) { 0094 return; 0095 } 0096 0097 if(logFile_ == QLatin1String("-")) { 0098 m_logFile.open(stdout, QIODevice::WriteOnly); 0099 } else { 0100 m_logFile.setFileName(logFile_); 0101 m_logFile.open(QIODevice::WriteOnly); 0102 } 0103 0104 m_logStream.reset(new QTextStream(&m_logFile)); 0105 m_logStream->setCodec(QTextCodec::codecForName("UTF-8")); 0106 } 0107 0108 QString Logger::logFile() const { 0109 return m_logFile.fileName(); 0110 } 0111 0112 void Logger::flush() { 0113 if(m_logStream) m_logStream->flush(); 0114 }