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"