mirror of
https://github.com/PrismLauncher/PrismLauncher.git
synced 2025-04-30 22:54:38 +02:00
feat(xml-logs): Case insisitive xml parseing + cleaner switch
Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
parent
11015a22d2
commit
1bd1245d86
@ -29,11 +29,9 @@ void LogParser::appendLine(QAnyStringView data)
|
|||||||
if (!m_partialData.isEmpty()) {
|
if (!m_partialData.isEmpty()) {
|
||||||
m_buffer = QString(m_partialData);
|
m_buffer = QString(m_partialData);
|
||||||
m_buffer.append("\n");
|
m_buffer.append("\n");
|
||||||
m_buffer.append(data.toString());
|
|
||||||
m_partialData.clear();
|
m_partialData.clear();
|
||||||
} else {
|
|
||||||
m_buffer.append(data.toString());
|
|
||||||
}
|
}
|
||||||
|
m_buffer.append(data.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<LogParser::Error> LogParser::getError()
|
std::optional<LogParser::Error> LogParser::getError()
|
||||||
@ -41,26 +39,6 @@ std::optional<LogParser::Error> LogParser::getError()
|
|||||||
return m_error;
|
return m_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageLevel::Enum LogParser::parseLogLevel(const QString& level)
|
|
||||||
{
|
|
||||||
auto test = level.trimmed().toUpper();
|
|
||||||
if (test == "TRACE") {
|
|
||||||
return MessageLevel::Trace;
|
|
||||||
} else if (test == "DEBUG") {
|
|
||||||
return MessageLevel::Debug;
|
|
||||||
} else if (test == "INFO") {
|
|
||||||
return MessageLevel::Info;
|
|
||||||
} else if (test == "WARN") {
|
|
||||||
return MessageLevel::Warning;
|
|
||||||
} else if (test == "ERROR") {
|
|
||||||
return MessageLevel::Error;
|
|
||||||
} else if (test == "FATAL") {
|
|
||||||
return MessageLevel::Fatal;
|
|
||||||
} else {
|
|
||||||
return MessageLevel::Unknown;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<LogParser::LogEntry> LogParser::parseAttributes()
|
std::optional<LogParser::LogEntry> LogParser::parseAttributes()
|
||||||
{
|
{
|
||||||
LogParser::LogEntry entry{
|
LogParser::LogEntry entry{
|
||||||
@ -82,7 +60,7 @@ std::optional<LogParser::LogEntry> LogParser::parseAttributes()
|
|||||||
entry.timestamp = QDateTime::fromSecsSinceEpoch(value.trimmed().toLongLong());
|
entry.timestamp = QDateTime::fromSecsSinceEpoch(value.trimmed().toLongLong());
|
||||||
} else if (name == "level"_L1) {
|
} else if (name == "level"_L1) {
|
||||||
entry.levelText = value.trimmed().toString();
|
entry.levelText = value.trimmed().toString();
|
||||||
entry.level = parseLogLevel(entry.levelText);
|
entry.level = MessageLevel::getLevel(entry.levelText);
|
||||||
} else if (name == "thread"_L1) {
|
} else if (name == "thread"_L1) {
|
||||||
entry.thread = value.trimmed().toString();
|
entry.thread = value.trimmed().toString();
|
||||||
}
|
}
|
||||||
@ -137,7 +115,7 @@ std::optional<LogParser::ParsedItem> LogParser::parseNext()
|
|||||||
m_parser.setNamespaceProcessing(false);
|
m_parser.setNamespaceProcessing(false);
|
||||||
m_parser.addData(m_buffer);
|
m_parser.addData(m_buffer);
|
||||||
if (m_parser.readNextStartElement()) {
|
if (m_parser.readNextStartElement()) {
|
||||||
if (m_parser.qualifiedName() == "log4j:Event"_L1) {
|
if (m_parser.qualifiedName().compare("log4j:Event"_L1, Qt::CaseInsensitive) == 0) {
|
||||||
int depth = 1;
|
int depth = 1;
|
||||||
bool eod = false;
|
bool eod = false;
|
||||||
while (depth > 0 && !eod) {
|
while (depth > 0 && !eod) {
|
||||||
@ -237,7 +215,7 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
m_parser.addData(m_buffer);
|
m_parser.addData(m_buffer);
|
||||||
|
|
||||||
m_parser.readNextStartElement();
|
m_parser.readNextStartElement();
|
||||||
if (m_parser.qualifiedName() == "log4j:Event"_L1) {
|
if (m_parser.qualifiedName().compare("log4j:Event"_L1, Qt::CaseInsensitive) == 0) {
|
||||||
auto entry_ = parseAttributes();
|
auto entry_ = parseAttributes();
|
||||||
if (!entry_.has_value()) {
|
if (!entry_.has_value()) {
|
||||||
setError();
|
setError();
|
||||||
@ -248,12 +226,11 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
bool foundMessage = false;
|
bool foundMessage = false;
|
||||||
int depth = 1;
|
int depth = 1;
|
||||||
|
|
||||||
while (!m_parser.atEnd()) {
|
enum parseOp { noOp, entryReady, parseError };
|
||||||
auto tok = m_parser.readNext();
|
|
||||||
switch (tok) {
|
auto foundStart = [&]() -> parseOp {
|
||||||
case QXmlStreamReader::TokenType::StartElement: {
|
|
||||||
depth += 1;
|
depth += 1;
|
||||||
if (m_parser.qualifiedName() == "log4j:Message"_L1) {
|
if (m_parser.qualifiedName().compare("log4j:Message"_L1, Qt::CaseInsensitive) == 0) {
|
||||||
QString message;
|
QString message;
|
||||||
bool messageComplete = false;
|
bool messageComplete = false;
|
||||||
|
|
||||||
@ -265,12 +242,12 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
message.append(m_parser.text());
|
message.append(m_parser.text());
|
||||||
} break;
|
} break;
|
||||||
case QXmlStreamReader::TokenType::EndElement: {
|
case QXmlStreamReader::TokenType::EndElement: {
|
||||||
if (m_parser.qualifiedName() == "log4j:Message"_L1) {
|
if (m_parser.qualifiedName().compare("log4j:Message"_L1, Qt::CaseInsensitive) == 0) {
|
||||||
messageComplete = true;
|
messageComplete = true;
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
case QXmlStreamReader::TokenType::EndDocument: {
|
case QXmlStreamReader::TokenType::EndDocument: {
|
||||||
return {}; // parse fail
|
return parseError; // parse fail
|
||||||
} break;
|
} break;
|
||||||
default: {
|
default: {
|
||||||
// no op
|
// no op
|
||||||
@ -278,7 +255,7 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (m_parser.hasError()) {
|
if (m_parser.hasError()) {
|
||||||
return {};
|
return parseError;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,10 +263,12 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
foundMessage = true;
|
foundMessage = true;
|
||||||
depth -= 1;
|
depth -= 1;
|
||||||
}
|
}
|
||||||
break;
|
return noOp;
|
||||||
case QXmlStreamReader::TokenType::EndElement: {
|
};
|
||||||
|
|
||||||
|
auto foundEnd = [&]() -> parseOp {
|
||||||
depth -= 1;
|
depth -= 1;
|
||||||
if (depth == 0 && m_parser.qualifiedName() == "log4j:Event"_L1) {
|
if (depth == 0 && m_parser.qualifiedName().compare("log4j:Event"_L1, Qt::CaseInsensitive) == 0) {
|
||||||
if (foundMessage) {
|
if (foundMessage) {
|
||||||
auto consumed = m_parser.characterOffset();
|
auto consumed = m_parser.characterOffset();
|
||||||
if (consumed > 0 && consumed <= m_buffer.length()) {
|
if (consumed > 0 && consumed <= m_buffer.length()) {
|
||||||
@ -301,12 +280,24 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
clearError();
|
clearError();
|
||||||
return entry;
|
return entryReady;
|
||||||
}
|
}
|
||||||
m_parser.raiseError("log4j:Event Missing required attribute: message");
|
m_parser.raiseError("log4j:Event Missing required attribute: message");
|
||||||
setError();
|
setError();
|
||||||
return {};
|
return parseError;
|
||||||
}
|
}
|
||||||
|
return noOp;
|
||||||
|
};
|
||||||
|
|
||||||
|
while (!m_parser.atEnd()) {
|
||||||
|
auto tok = m_parser.readNext();
|
||||||
|
parseOp op = noOp;
|
||||||
|
switch (tok) {
|
||||||
|
case QXmlStreamReader::TokenType::StartElement: {
|
||||||
|
op = foundStart();
|
||||||
|
} break;
|
||||||
|
case QXmlStreamReader::TokenType::EndElement: {
|
||||||
|
op = foundEnd();
|
||||||
} break;
|
} break;
|
||||||
case QXmlStreamReader::TokenType::EndDocument: {
|
case QXmlStreamReader::TokenType::EndDocument: {
|
||||||
return {};
|
return {};
|
||||||
@ -315,6 +306,16 @@ std::optional<LogParser::ParsedItem> LogParser::parseLog4J()
|
|||||||
// no op
|
// no op
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case parseError:
|
||||||
|
return {}; // parse fail or error
|
||||||
|
case entryReady:
|
||||||
|
return entry;
|
||||||
|
case noOp:
|
||||||
|
default: {
|
||||||
|
// no op
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_parser.hasError()) {
|
if (m_parser.hasError()) {
|
||||||
@ -334,16 +335,7 @@ 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");
|
||||||
if (levelStr == "INFO")
|
level = MessageLevel::getLevel(levelStr);
|
||||||
level = MessageLevel::Info;
|
|
||||||
if (levelStr == "WARN")
|
|
||||||
level = MessageLevel::Warning;
|
|
||||||
if (levelStr == "ERROR")
|
|
||||||
level = MessageLevel::Error;
|
|
||||||
if (levelStr == "FATAL")
|
|
||||||
level = MessageLevel::Fatal;
|
|
||||||
if (levelStr == "TRACE" || levelStr == "DEBUG")
|
|
||||||
level = MessageLevel::Debug;
|
|
||||||
} 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]") ||
|
||||||
|
@ -62,7 +62,6 @@ class LogParser {
|
|||||||
static MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level);
|
static MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
MessageLevel::Enum parseLogLevel(const QString& level);
|
|
||||||
std::optional<LogEntry> parseAttributes();
|
std::optional<LogEntry> parseAttributes();
|
||||||
void setError();
|
void setError();
|
||||||
void clearError();
|
void clearError();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user