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();
model.append(MessageLevel::Error, tr("[Log4j Parse Error] Failed to parse log4j log event: %1").arg(err.value().errMessage));
return false;
} else {
if (!items.isEmpty()) {
auto& model = *getLogModel();
for (auto const& item : items) {
if (std::holds_alternative<LogParser::LogEntry>(item)) {
auto entry = std::get<LogParser::LogEntry>(item);
auto msg = QString("[%1] [%2/%3] [%4]: %5")
.arg(entry.timestamp.toString("HH:mm:ss"))
.arg(entry.thread)
.arg(entry.levelText)
.arg(entry.logger)
.arg(entry.message);
msg = censorPrivateInfo(msg);
model.append(entry.level, msg);
} else if (std::holds_alternative<LogParser::PlainText>(item)) {
auto msg = std::get<LogParser::PlainText>(item).message;
level = LogParser::guessLevel(msg, model.previousLevel());
msg = censorPrivateInfo(msg);
model.append(level, msg);
}
}
}
if (items.isEmpty())
return true;
auto model = getLogModel();
for (auto const& item : items) {
if (std::holds_alternative<LogParser::LogEntry>(item)) {
auto entry = std::get<LogParser::LogEntry>(item);
auto msg = QString("[%1] [%2/%3] [%4]: %5")
.arg(entry.timestamp.toString("HH:mm:ss"))
.arg(entry.thread)
.arg(entry.levelText)
.arg(entry.logger)
.arg(entry.message);
msg = censorPrivateInfo(msg);
model->append(entry.level, msg);
} else if (std::holds_alternative<LogParser::PlainText>(item)) {
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;
}
@@ -273,23 +284,10 @@ void LaunchTask::onLogLine(QString line, MessageLevel::Enum level)
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
line = censorPrivateInfo(line);
model.append(level, line);
getLogModel()->append(level, line);
}
void LaunchTask::emitSucceeded()

View File

@@ -169,8 +169,8 @@ bool LogModel::isOverFlow()
MessageLevel::Enum LogModel::previousLevel()
{
if (!m_content.isEmpty()) {
return m_content.last().level;
if (m_numLines > 0) {
return m_content[m_numLines - 1].level;
}
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");
}
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>[^\\]]+)\\]");
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
QString timestamp = match.captured("timestamp");
QString levelStr = match.captured("level");
level = MessageLevel::getLevel(levelStr);
return MessageLevel::getLevel(levelStr);
} else {
// Old style forge logs
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") ||
line.contains("[FINEST]"))
level = MessageLevel::Info;
return MessageLevel::Info;
if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
level = MessageLevel::Error;
return MessageLevel::Error;
if (line.contains("[WARNING]"))
level = MessageLevel::Warning;
return MessageLevel::Warning;
if (line.contains("[DEBUG]"))
level = MessageLevel::Debug;
return MessageLevel::Debug;
}
if (level != MessageLevel::Unknown)
return level;
if (line.contains("overwriting existing"))
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();
/// 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:
std::optional<LogEntry> parseAttributes();

View File

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

View File

@@ -126,7 +126,11 @@ class XmlLogParseTest : public QObject {
last = entry.level;
} else if (std::holds_alternative<LogParser::PlainText>(item)) {
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));
last = level;
}

View File

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

View File

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