File indexing completed on 2024-06-16 05:01:20

0001 /* Copyright (C) 2006 - 2014 Jan Kundrát <jkt@flaska.net>
0002 
0003    This file is part of the Trojita Qt IMAP e-mail client,
0004    http://trojita.flaska.net/
0005 
0006    This program is free software; you can redistribute it and/or
0007    modify it under the terms of the GNU General Public License as
0008    published by the Free Software Foundation; either version 2 of
0009    the License or (at your option) version 3 or any later version
0010    accepted by the membership of KDE e.V. (or its successor approved
0011    by the membership of KDE e.V.), which shall act as a proxy
0012    defined in Section 14 of version 3 of the license.
0013 
0014    This program is distributed in the hope that it will be useful,
0015    but WITHOUT ANY WARRANTY; without even the implied warranty of
0016    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017    GNU General Public License for more details.
0018 
0019    You should have received a copy of the GNU General Public License
0020    along with this program.  If not, see <http://www.gnu.org/licenses/>.
0021 */
0022 
0023 #include <QDateTime>
0024 #include <QDebug>
0025 #include <QFile>
0026 #include <QTextStream>
0027 #include "FileLogger.h"
0028 #include "../Imap/Model/Utils.h"
0029 
0030 namespace Common
0031 {
0032 
0033 FileLogger::FileLogger(QObject *parent) :
0034     QObject(parent), m_fileLog(0), m_consoleLog(false), m_autoFlush(false)
0035 {
0036 }
0037 
0038 void FileLogger::setFileLogging(const bool enabled, const QString &fileName)
0039 {
0040     if (enabled) {
0041         if (m_fileLog)
0042             return;
0043 
0044         QFile *logFile = new QFile(fileName, this);
0045         logFile->open(QIODevice::Truncate | QIODevice::WriteOnly);
0046         m_fileLog = new QTextStream(logFile);
0047     } else {
0048         if (m_fileLog) {
0049             QIODevice *dev = m_fileLog->device();
0050             delete m_fileLog;
0051             delete dev;
0052             m_fileLog = 0;
0053         }
0054     }
0055 }
0056 
0057 FileLogger::~FileLogger()
0058 {
0059     delete m_fileLog;
0060 }
0061 
0062 void FileLogger::escapeCrLf(QString &s)
0063 {
0064     s.replace(QLatin1Char('\r'), 0x240d /* SYMBOL FOR CARRIAGE RETURN */)
0065             .replace(QLatin1Char('\n'), 0x240a /* SYMBOL FOR LINE FEED */);
0066 }
0067 
0068 void FileLogger::log(uint connectionId, Common::LogMessage message)
0069 {
0070     if (!m_fileLog && !m_consoleLog)
0071         return;
0072 
0073     QString formatted = formatMessage(connectionId, message);
0074     escapeCrLf(formatted);
0075 
0076     if (m_fileLog) {
0077         *m_fileLog << formatted << "\n";
0078         if (m_autoFlush)
0079             m_fileLog->flush();
0080     }
0081 
0082     enum {CUTOFF=200};
0083     if (m_consoleLog) {
0084         if (message.message.size() > CUTOFF) {
0085             // Got to reformat the message
0086             message.truncatedBytes = message.message.size() - CUTOFF;
0087             message.message = message.message.left(CUTOFF);
0088             formatted = formatMessage(connectionId, message);
0089             escapeCrLf(formatted);
0090         }
0091         qDebug() << formatted.toUtf8().constData() << "\n";
0092     }
0093 }
0094 
0095 QString FileLogger::formatMessage(uint parser, const Common::LogMessage &message) const
0096 {
0097     using namespace Common;
0098     QString direction;
0099     switch (message.kind) {
0100     case LOG_IO_READ:
0101         direction = QStringLiteral(" <<< ");
0102         break;
0103     case LOG_IO_WRITTEN:
0104         direction = QStringLiteral(" >>> ");
0105         break;
0106     case LOG_PARSE_ERROR:
0107         direction = QStringLiteral(" [err] ");
0108         break;
0109     case LOG_MAILBOX_SYNC:
0110         direction = QStringLiteral(" [sync] ");
0111         break;
0112     case LOG_TASKS:
0113         direction = QStringLiteral(" [task] ");
0114         break;
0115     case LOG_MESSAGES:
0116         direction = QStringLiteral(" [msg] ");
0117         break;
0118     case LOG_SUBMISSION:
0119         direction = QStringLiteral(" [submission] ");
0120         break;
0121     case LOG_OTHER:
0122         direction = QStringLiteral(" ");
0123         break;
0124     }
0125     if (message.truncatedBytes) {
0126         direction += QLatin1String("[truncated] ");
0127     }
0128     return message.timestamp.toString(QStringLiteral("hh:mm:ss.zzz")) + QString::number(parser) + QLatin1Char(' ') +
0129             direction + message.source + QLatin1Char(' ') + message.message.trimmed();
0130 }
0131 
0132 /** @short Enable flushing the on-disk log after each message
0133 
0134 Automatically flushing the log will make sure that all messages are actually stored in the log even in the event of a program
0135 crash, but at the cost of a rather high overhead.
0136 */
0137 void FileLogger::setAutoFlush(const bool autoFlush)
0138 {
0139     m_autoFlush = autoFlush;
0140     if (m_autoFlush && m_fileLog)
0141         m_fileLog->flush();
0142 }
0143 
0144 void FileLogger::setConsoleLogging(const bool enabled)
0145 {
0146     m_consoleLog = enabled;
0147 }
0148 
0149 }