File indexing completed on 2024-05-12 05:48:37

0001 /*
0002     SPDX-FileCopyrightText: 2007 Nicolas Ternisien <nicolas.ternisien@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "syslogAnalyzer.h"
0008 
0009 #include <QDateTime>
0010 #include <QStringList>
0011 
0012 #include <KLocalizedString>
0013 
0014 #include "globals.h"
0015 #include "ksystemlog_debug.h"
0016 
0017 #include "localLogFileReader.h"
0018 #include "logLevel.h"
0019 #include "logLine.h"
0020 #include "logMode.h"
0021 #include "logViewWidget.h"
0022 
0023 #include "logViewModel.h"
0024 
0025 #include "parsingHelper.h"
0026 
0027 #include "ksystemlogConfig.h"
0028 
0029 SyslogAnalyzer::SyslogAnalyzer(LogMode *logMode)
0030     : FileAnalyzer(logMode)
0031 {
0032 }
0033 
0034 SyslogAnalyzer::~SyslogAnalyzer()
0035 {
0036 }
0037 
0038 LogViewColumns SyslogAnalyzer::initColumns()
0039 {
0040     LogViewColumns columns;
0041     columns.addColumn(LogViewColumn(i18n("Date"), true, false));
0042     columns.addColumn(LogViewColumn(i18n("Host"), true, true));
0043     columns.addColumn(LogViewColumn(i18n("Process"), true, true));
0044     columns.addColumn(LogViewColumn(i18n("Message"), true, false));
0045 
0046     return columns;
0047 }
0048 
0049 LogFileReader *SyslogAnalyzer::createLogFileReader(const LogFile &logFile)
0050 {
0051     return new LocalLogFileReader(logFile);
0052 }
0053 
0054 Analyzer::LogFileSortMode SyslogAnalyzer::logFileSortMode()
0055 {
0056     return Analyzer::AscendingSortedLogFile;
0057 }
0058 
0059 /**
0060  * TODO Improve speed of this method (with KRegExp class for example)
0061  */
0062 LogLine *SyslogAnalyzer::parseMessage(const QString &logLine, const LogFile &originalFile)
0063 {
0064     // qCDebug(KSYSTEMLOG) << QTime::currentTime() << " : Reading line : " << logLine << " from " <<
0065     // originalFile.url.path();
0066 
0067     // 15 is the default date size format
0068     if (logLine.length() < 15) {
0069         qCDebug(KSYSTEMLOG) << "Too short line";
0070         return undefinedLogLine(logLine, originalFile);
0071     }
0072 
0073     const int year = QDate::currentDate().year();
0074 
0075     // Month number
0076     QString const month(logLine.left(3));
0077 
0078     QString line(logLine);
0079 
0080     line.remove(0, 4);
0081     const int monthNum = ParsingHelper::instance()->parseSyslogMonth(month);
0082 
0083     // Day number
0084     QString const day(line.left(2));
0085     const int dayNum = day.toInt();
0086 
0087     line.remove(0, 3);
0088 
0089     // Time
0090     QString stringTime(line.left(8));
0091     const int h = QStringView(stringTime).left(2).toInt();
0092     stringTime.remove(0, 3);
0093     const int m = QStringView(stringTime).left(2).toInt();
0094     stringTime.remove(0, 3);
0095     const int s = QStringView(stringTime).left(2).toInt();
0096     const QDateTime dateTime(QDate(year, monthNum, dayNum), QTime(h, m, s));
0097     if (!dateTime.isValid()) {
0098         qCDebug(KSYSTEMLOG) << "Malformed date and time";
0099         return undefinedLogLine(logLine, originalFile);
0100     }
0101 
0102     line.remove(0, 9);
0103 
0104     QString hostname;
0105 
0106     const int nextSpace = line.indexOf(QLatin1Char(' '));
0107     int nextDoubleDot = line.indexOf(QLatin1Char(':'));
0108 
0109     // Normal case or no process name
0110     if (nextSpace < nextDoubleDot || nextDoubleDot == -1) {
0111         // Host name
0112         hostname = line.left(nextSpace);
0113         line.remove(0, nextSpace + 1);
0114     }
0115     // No host name case (very rare)
0116     else {
0117         // Host name
0118         hostname = undefinedHostName();
0119     }
0120 
0121     // Refresh double dot once the line has been substr'ed
0122     nextDoubleDot = line.indexOf(QLatin1Char(':'));
0123 
0124     QString process;
0125     QString message;
0126 
0127     // Process name
0128     if (nextDoubleDot != -1) {
0129         process = line.left(nextDoubleDot);
0130 
0131         // If the delete process identifier option is enabled
0132         if (KSystemLogConfig::deleteProcessIdentifier()) {
0133             const int squareBracket = process.indexOf(QLatin1Char('['));
0134 
0135             // If we find a bracket, we remove the useless part
0136             if (squareBracket != -1) {
0137                 process.truncate(squareBracket);
0138             }
0139         }
0140         line.remove(0, nextDoubleDot + 1);
0141 
0142         message = line.remove(0, 1);
0143     }
0144     // If we can't find any ':' character, it means that this line is a
0145     // internal message of syslogd
0146     else {
0147         if (line.contains(QLatin1String("last message repeated")) || line.contains(QLatin1String("-- MARK --"))) {
0148             process = QStringLiteral("syslog");
0149         } else {
0150             process = undefinedProcess();
0151         }
0152 
0153         message = line;
0154     }
0155 
0156     QStringList list;
0157     list.append(hostname);
0158     list.append(process);
0159     list.append(message);
0160 
0161     return new LogLine(mLogLineInternalIdGenerator++, dateTime, list, originalFile.url().toLocalFile(), originalFile.defaultLogLevel(), mLogMode);
0162 }
0163 
0164 inline LogLine *SyslogAnalyzer::undefinedLogLine(const QString &message, const LogFile &originalFile)
0165 {
0166     QStringList items;
0167     items << undefinedHostName() << undefinedProcess() << message;
0168     return new LogLine(mLogLineInternalIdGenerator++,
0169                        QDateTime::currentDateTime(),
0170                        items,
0171                        originalFile.url().toLocalFile(),
0172                        originalFile.defaultLogLevel(),
0173                        mLogMode);
0174 }
0175 
0176 inline QString SyslogAnalyzer::undefinedHostName()
0177 {
0178     // i18nc("Undefined host name", "undefined");
0179     return QLatin1String("");
0180 }
0181 
0182 inline QString SyslogAnalyzer::undefinedProcess()
0183 {
0184     // i18nc("Undefined process", "undefined");
0185     return QLatin1String("");
0186 }
0187 
0188 #include "moc_syslogAnalyzer.cpp"