Fix issues with log level handling (#4254)

This commit is contained in:
Alexandru Ionut Tripon
2025-11-16 18:13:12 +02:00
committed by GitHub
8 changed files with 70 additions and 72 deletions

View File

@@ -234,29 +234,40 @@ bool LaunchTask::parseXmlLogs(QString const& line, MessageLevel::Enum level)
auto& model = *getLogModel(); auto& model = *getLogModel();
model.append(MessageLevel::Error, tr("[Log4j Parse Error] Failed to parse log4j log event: %1").arg(err.value().errMessage)); model.append(MessageLevel::Error, tr("[Log4j Parse Error] Failed to parse log4j log event: %1").arg(err.value().errMessage));
return false; return false;
} else { }
if (!items.isEmpty()) {
auto& model = *getLogModel(); if (items.isEmpty())
for (auto const& item : items) { return true;
if (std::holds_alternative<LogParser::LogEntry>(item)) {
auto entry = std::get<LogParser::LogEntry>(item); auto model = getLogModel();
auto msg = QString("[%1] [%2/%3] [%4]: %5") for (auto const& item : items) {
.arg(entry.timestamp.toString("HH:mm:ss")) if (std::holds_alternative<LogParser::LogEntry>(item)) {
.arg(entry.thread) auto entry = std::get<LogParser::LogEntry>(item);
.arg(entry.levelText) auto msg = QString("[%1] [%2/%3] [%4]: %5")
.arg(entry.logger) .arg(entry.timestamp.toString("HH:mm:ss"))
.arg(entry.message); .arg(entry.thread)
msg = censorPrivateInfo(msg); .arg(entry.levelText)
model.append(entry.level, msg); .arg(entry.logger)
} else if (std::holds_alternative<LogParser::PlainText>(item)) { .arg(entry.message);
auto msg = std::get<LogParser::PlainText>(item).message; msg = censorPrivateInfo(msg);
level = LogParser::guessLevel(msg, model.previousLevel()); model->append(entry.level, msg);
msg = censorPrivateInfo(msg); } else if (std::holds_alternative<LogParser::PlainText>(item)) {
model.append(level, msg); auto msg = std::get<LogParser::PlainText>(item).message;
}
} MessageLevel::Enum newLevel = MessageLevel::fromLine(msg);
if (newLevel == MessageLevel::Unknown)
newLevel = LogParser::guessLevel(line);
if (newLevel == MessageLevel::Unknown)
newLevel = model->previousLevel();
msg = censorPrivateInfo(msg);
model->append(newLevel, msg);
} }
} }
return true; return true;
} }
@@ -273,23 +284,10 @@ void LaunchTask::onLogLine(QString line, MessageLevel::Enum level)
return; return;
} }
// if the launcher part set a log level, use it
auto innerLevel = MessageLevel::fromLine(line);
if (innerLevel != MessageLevel::Unknown) {
level = innerLevel;
}
auto& model = *getLogModel();
// If the level is still undetermined, guess level
if (level == MessageLevel::Unknown) {
level = LogParser::guessLevel(line, model.previousLevel());
}
// censor private user info // censor private user info
line = censorPrivateInfo(line); line = censorPrivateInfo(line);
model.append(level, line); getLogModel()->append(level, line);
} }
void LaunchTask::emitSucceeded() void LaunchTask::emitSucceeded()

View File

@@ -169,8 +169,8 @@ bool LogModel::isOverFlow()
MessageLevel::Enum LogModel::previousLevel() MessageLevel::Enum LogModel::previousLevel()
{ {
if (!m_content.isEmpty()) { if (m_numLines > 0) {
return m_content.last().level; return m_content[m_numLines - 1].level;
} }
return MessageLevel::Unknown; return MessageLevel::Unknown;
} }

View File

@@ -320,7 +320,7 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
throw std::runtime_error("unreachable: already verified this was a complete log4j:Event"); throw std::runtime_error("unreachable: already verified this was a complete log4j:Event");
} }
MessageLevel::Enum LogParser::guessLevel(const QString& line, MessageLevel::Enum level) MessageLevel::Enum LogParser::guessLevel(const QString& line)
{ {
static const QRegularExpression LINE_WITH_LEVEL("^\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]"); static const QRegularExpression LINE_WITH_LEVEL("^\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
auto match = LINE_WITH_LEVEL.match(line); auto match = LINE_WITH_LEVEL.match(line);
@@ -328,24 +328,26 @@ MessageLevel::Enum LogParser::guessLevel(const QString& line, MessageLevel::Enum
// New style logs from log4j // New style logs from log4j
QString timestamp = match.captured("timestamp"); QString timestamp = match.captured("timestamp");
QString levelStr = match.captured("level"); QString levelStr = match.captured("level");
level = MessageLevel::getLevel(levelStr);
return MessageLevel::getLevel(levelStr);
} else { } else {
// Old style forge logs // Old style forge logs
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") || if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") ||
line.contains("[FINEST]")) line.contains("[FINEST]"))
level = MessageLevel::Info; return MessageLevel::Info;
if (line.contains("[SEVERE]") || line.contains("[STDERR]")) if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
level = MessageLevel::Error; return MessageLevel::Error;
if (line.contains("[WARNING]")) if (line.contains("[WARNING]"))
level = MessageLevel::Warning; return MessageLevel::Warning;
if (line.contains("[DEBUG]")) if (line.contains("[DEBUG]"))
level = MessageLevel::Debug; return MessageLevel::Debug;
} }
if (level != MessageLevel::Unknown)
return level;
if (line.contains("overwriting existing")) if (line.contains("overwriting existing"))
return MessageLevel::Fatal; return MessageLevel::Fatal;
return MessageLevel::Info; if (line == "---- Minecraft Crash Report ----")
return MessageLevel::Error;
return MessageLevel::Unknown;
} }

View File

@@ -59,7 +59,7 @@ class LogParser {
std::optional<Error> getError(); std::optional<Error> getError();
/// guess log level from a line of game log /// guess log level from a line of game log
static MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level); static MessageLevel::Enum guessLevel(const QString& line);
protected: protected:
std::optional<LogEntry> parseAttributes(); std::optional<LogEntry> parseAttributes();

View File

@@ -287,16 +287,10 @@ void OtherLogsPage::reload()
if (!m_instance) { if (!m_instance) {
level = MessageLevel::fromLauncherLine(lineTemp); level = MessageLevel::fromLauncherLine(lineTemp);
} else { } else {
// if the launcher part set a log level, use it level = LogParser::guessLevel(line);
auto innerLevel = MessageLevel::fromLine(lineTemp);
if (innerLevel != MessageLevel::Unknown) {
level = innerLevel;
}
// If the level is still undetermined, guess level if (level == MessageLevel::Unknown)
if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) { level = last;
level = LogParser::guessLevel(line, last);
}
} }
last = level; last = level;

View File

@@ -126,7 +126,11 @@ class XmlLogParseTest : public QObject {
last = entry.level; last = entry.level;
} else if (std::holds_alternative<LogParser::PlainText>(item)) { } else if (std::holds_alternative<LogParser::PlainText>(item)) {
auto msg = std::get<LogParser::PlainText>(item).message; auto msg = std::get<LogParser::PlainText>(item).message;
auto level = LogParser::guessLevel(msg, last); auto level = LogParser::guessLevel(msg);
if (level == MessageLevel::Unknown)
level = last;
out.append(std::make_pair(level, msg)); out.append(std::make_pair(level, msg));
last = level; last = level;
} }

View File

@@ -1,11 +1,11 @@
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO INFO
INFO INFO
INFO INFO

View File

@@ -1,10 +1,10 @@
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO UNKNOWN
INFO INFO
INFO INFO
INFO INFO