feat(xml-logs): finish tests

Signed-off-by: Rachel Powers <508861+Ryex@users.noreply.github.com>
This commit is contained in:
Rachel Powers 2025-04-18 15:22:39 -07:00
parent bfdc77665d
commit 21570a03fb
No known key found for this signature in database
GPG Key ID: E10E321EB160949B
15 changed files with 2006 additions and 91 deletions

View File

@ -151,9 +151,6 @@ class BaseInstance : public QObject, public std::enable_shared_from_this<BaseIns
void setManagedPack(const QString& type, const QString& id, const QString& name, const QString& versionId, const QString& version); void setManagedPack(const QString& type, const QString& id, const QString& name, const QString& versionId, const QString& version);
void copyManagedPack(BaseInstance& other); void copyManagedPack(BaseInstance& other);
/// guess log level from a line of game log
virtual MessageLevel::Enum guessLevel([[maybe_unused]] const QString& line, MessageLevel::Enum level) { return level; }
virtual QStringList extraArguments(); virtual QStringList extraArguments();
/// Traits. Normally inside the version, depends on instance implementation. /// Traits. Normally inside the version, depends on instance implementation.

View File

@ -2,21 +2,22 @@
MessageLevel::Enum MessageLevel::getLevel(const QString& levelName) MessageLevel::Enum MessageLevel::getLevel(const QString& levelName)
{ {
if (levelName == "Launcher") QString name = levelName.toUpper();
if (name == "LAUNCHER")
return MessageLevel::Launcher; return MessageLevel::Launcher;
else if (levelName == "Trace") else if (name == "TRACE")
return MessageLevel::Trace; return MessageLevel::Trace;
else if (levelName == "Debug") else if (name == "DEBUG")
return MessageLevel::Debug; return MessageLevel::Debug;
else if (levelName == "Info") else if (name == "INFO")
return MessageLevel::Info; return MessageLevel::Info;
else if (levelName == "Message") else if (name == "MESSAGE")
return MessageLevel::Message; return MessageLevel::Message;
else if (levelName == "Warning") else if (name == "WARNING" || name == "WARN")
return MessageLevel::Warning; return MessageLevel::Warning;
else if (levelName == "Error") else if (name == "ERROR")
return MessageLevel::Error; return MessageLevel::Error;
else if (levelName == "Fatal") else if (name == "FATAL")
return MessageLevel::Fatal; return MessageLevel::Fatal;
// Skip PrePost, it's not exposed to !![]! // Skip PrePost, it's not exposed to !![]!
// Also skip StdErr and StdOut // Also skip StdErr and StdOut

View File

@ -37,7 +37,6 @@
#include "launch/LaunchTask.h" #include "launch/LaunchTask.h"
#include <assert.h> #include <assert.h>
#include <qlogging.h>
#include <QAnyStringView> #include <QAnyStringView>
#include <QCoreApplication> #include <QCoreApplication>
#include <QDebug> #include <QDebug>
@ -237,9 +236,9 @@ bool LaunchTask::parseXmlLogs(QString const& line, MessageLevel::Enum level)
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 { } else {
if (items.has_value()) { if (!items.isEmpty()) {
auto& model = *getLogModel(); auto& model = *getLogModel();
for (auto const& item : items.value()) { for (auto const& item : items) {
if (std::holds_alternative<LogParser::LogEntry>(item)) { if (std::holds_alternative<LogParser::LogEntry>(item)) {
auto entry = std::get<LogParser::LogEntry>(item); auto entry = std::get<LogParser::LogEntry>(item);
auto msg = QString("[%1] [%2/%3] [%4]: %5") auto msg = QString("[%1] [%2/%3] [%4]: %5")
@ -252,7 +251,7 @@ bool LaunchTask::parseXmlLogs(QString const& line, MessageLevel::Enum level)
model.append(entry.level, msg); model.append(entry.level, msg);
} 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;
level = m_instance->guessLevel(msg, level); level = LogParser::guessLevel(msg, model.previousLevel());
msg = censorPrivateInfo(msg); msg = censorPrivateInfo(msg);
model.append(level, msg); model.append(level, msg);
} }
@ -281,15 +280,16 @@ void LaunchTask::onLogLine(QString line, MessageLevel::Enum level)
level = innerLevel; level = innerLevel;
} }
auto& model = *getLogModel();
// If the level is still undetermined, guess level // If the level is still undetermined, guess level
if (level == MessageLevel::Unknown) { if (level == MessageLevel::Unknown) {
level = m_instance->guessLevel(line, level); level = LogParser::guessLevel(line, model.previousLevel());
} }
// censor private user info // censor private user info
line = censorPrivateInfo(line); line = censorPrivateInfo(line);
auto& model = *getLogModel();
model.append(level, line); model.append(level, line);
} }

View File

@ -166,3 +166,11 @@ bool LogModel::isOverFlow()
{ {
return m_numLines >= m_maxLines && m_stopOnOverflow; return m_numLines >= m_maxLines && m_stopOnOverflow;
} }
MessageLevel::Enum LogModel::previousLevel() {
if (!m_content.isEmpty()) {
return m_content.last().level;
}
return MessageLevel::Unknown;
}

View File

@ -31,6 +31,8 @@ class LogModel : public QAbstractListModel {
void setColorLines(bool state); void setColorLines(bool state);
bool colorLines() const; bool colorLines() const;
MessageLevel::Enum previousLevel();
enum Roles { LevelRole = Qt::UserRole }; enum Roles { LevelRole = Qt::UserRole };
private /* types */: private /* types */:

View File

@ -19,6 +19,9 @@
#include "LogParser.h" #include "LogParser.h"
#include <QRegularExpression>
#include "MessageLevel.h"
void LogParser::appendLine(QAnyStringView data) void LogParser::appendLine(QAnyStringView data)
{ {
if (!m_partialData.isEmpty()) { if (!m_partialData.isEmpty()) {
@ -202,7 +205,7 @@ std::optional<LogParser::ParsedItem> LogParser::parseNext()
} }
} }
std::optional<QList<LogParser::ParsedItem>> LogParser::parseAvailable() QList<LogParser::ParsedItem> LogParser::parseAvailable()
{ {
QList<LogParser::ParsedItem> items; QList<LogParser::ParsedItem> items;
bool doNext = true; bool doNext = true;
@ -320,3 +323,48 @@ 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)
{
static const QRegularExpression LINE_WITH_LEVEL("^\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
auto match = LINE_WITH_LEVEL.match(line);
if (match.hasMatch()) {
// New style logs from log4j
QString timestamp = match.captured("timestamp");
QString levelStr = match.captured("level");
if (levelStr == "INFO")
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 {
// Old style forge logs
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") ||
line.contains("[FINEST]"))
level = MessageLevel::Info;
if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
level = MessageLevel::Error;
if (line.contains("[WARNING]"))
level = MessageLevel::Warning;
if (line.contains("[DEBUG]"))
level = MessageLevel::Debug;
}
if (level != MessageLevel::Unknown)
return level;
if (line.contains("overwriting existing"))
return MessageLevel::Fatal;
// NOTE: this diverges from the real regexp. no unicode, the first section is + instead of *
// static const QRegularExpression JAVA_EXCEPTION(
// R"(Exception in thread|...\d more$|(\s+at |Caused by: )([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*)|([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*(Exception|Error|Throwable)");
//
// if (line.contains(JAVA_EXCEPTION))
// return MessageLevel::Error;
return MessageLevel::Info;
}

View File

@ -55,9 +55,12 @@ class LogParser {
void appendLine(QAnyStringView data); void appendLine(QAnyStringView data);
std::optional<ParsedItem> parseNext(); std::optional<ParsedItem> parseNext();
std::optional<QList<ParsedItem>> parseAvailable(); QList<ParsedItem> parseAvailable();
std::optional<Error> getError(); std::optional<Error> getError();
/// guess log level from a line of game log
static MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level);
protected: protected:
MessageLevel::Enum parseLogLevel(const QString& level); MessageLevel::Enum parseLogLevel(const QString& level);
std::optional<LogEntry> parseAttributes(); std::optional<LogEntry> parseAttributes();

View File

@ -1004,49 +1004,6 @@ QMap<QString, QString> MinecraftInstance::createCensorFilterFromSession(AuthSess
return filter; return filter;
} }
MessageLevel::Enum MinecraftInstance::guessLevel(const QString& line, MessageLevel::Enum level)
{
if (line.contains("overwriting existing"))
return MessageLevel::Fatal;
// NOTE: this diverges from the real regexp. no unicode, the first section is + instead of *
static const QRegularExpression JAVA_EXCEPTION(
R"(Exception in thread|...\d more$|(\s+at |Caused by: )([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*)|([a-zA-Z_$][a-zA-Z\d_$]*\.)+[a-zA-Z_$][a-zA-Z\d_$]*(Exception|Error|Throwable)");
if (line.contains(JAVA_EXCEPTION))
return MessageLevel::Error;
static const QRegularExpression LINE_WITH_LEVEL("\\[(?<timestamp>[0-9:]+)\\] \\[[^/]+/(?<level>[^\\]]+)\\]");
auto match = LINE_WITH_LEVEL.match(line);
if (match.hasMatch()) {
// New style logs from log4j
QString timestamp = match.captured("timestamp");
QString levelStr = match.captured("level");
if (levelStr == "INFO")
level = MessageLevel::Message;
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 {
// Old style forge logs
if (line.contains("[INFO]") || line.contains("[CONFIG]") || line.contains("[FINE]") || line.contains("[FINER]") ||
line.contains("[FINEST]"))
level = MessageLevel::Message;
if (line.contains("[SEVERE]") || line.contains("[STDERR]"))
level = MessageLevel::Error;
if (line.contains("[WARNING]"))
level = MessageLevel::Warning;
if (line.contains("[DEBUG]"))
level = MessageLevel::Debug;
}
return level;
}
IPathMatcher::Ptr MinecraftInstance::getLogFileMatcher() IPathMatcher::Ptr MinecraftInstance::getLogFileMatcher()
{ {
auto combined = std::make_shared<MultiMatcher>(); auto combined = std::make_shared<MultiMatcher>();

View File

@ -139,9 +139,6 @@ class MinecraftInstance : public BaseInstance {
QProcessEnvironment createEnvironment() override; QProcessEnvironment createEnvironment() override;
QProcessEnvironment createLaunchEnvironment() override; QProcessEnvironment createLaunchEnvironment() override;
/// guess log level from a line of minecraft log
MessageLevel::Enum guessLevel(const QString& line, MessageLevel::Enum level) override;
IPathMatcher::Ptr getLogFileMatcher() override; IPathMatcher::Ptr getLogFileMatcher() override;
QString getLogFileRoot() override; QString getLogFileRoot() override;

View File

@ -179,7 +179,9 @@ void OtherLogsPage::on_btnReload_clicked()
showTooBig(); showTooBig();
return; return;
} }
auto handleLine = [this](QString line) { MessageLevel::Enum last = MessageLevel::Unknown;
auto handleLine = [this, &last](QString line) {
if (line.isEmpty()) if (line.isEmpty())
return false; return false;
if (line.back() == '\n') if (line.back() == '\n')
@ -194,9 +196,10 @@ void OtherLogsPage::on_btnReload_clicked()
// If the level is still undetermined, guess level // If the level is still undetermined, guess level
if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) { if (level == MessageLevel::StdErr || level == MessageLevel::StdOut || level == MessageLevel::Unknown) {
level = m_instance->guessLevel(line, level); level = LogParser::guessLevel(line, last);
} }
last = level;
m_model->append(level, line); m_model->append(level, line);
return m_model->isOverFlow(); return m_model->isOverFlow();
}; };

View File

@ -62,3 +62,7 @@ ecm_add_test(MetaComponentParse_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VE
ecm_add_test(CatPack_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test ecm_add_test(CatPack_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
TEST_NAME CatPack) TEST_NAME CatPack)
ecm_add_test(XmlLogs_test.cpp LINK_LIBRARIES Launcher_logic Qt${QT_VERSION_MAJOR}::Test
TEST_NAME XmlLogs)

View File

@ -23,9 +23,11 @@
#include <QList> #include <QList>
#include <QObject> #include <QObject>
#include <QRegularExpression>
#include <QString> #include <QString>
#include <optional> #include <algorithm>
#include <iterator>
#include <FileSystem.h> #include <FileSystem.h>
#include <MessageLevel.h> #include <MessageLevel.h>
@ -42,16 +44,62 @@ class XmlLogParseTest : public QObject {
QString shortXml = QString::fromUtf8(FS::read(FS::PathCombine(source, "vanilla-1.21.5.xml.log"))); QString shortXml = QString::fromUtf8(FS::read(FS::PathCombine(source, "vanilla-1.21.5.xml.log")));
QString shortText = QString::fromUtf8(FS::read(FS::PathCombine(source, "vanilla-1.21.5.text.log"))); QString shortText = QString::fromUtf8(FS::read(FS::PathCombine(source, "vanilla-1.21.5.text.log")));
QStringList shortTextLevels_s = QString::fromUtf8(FS::read(FS::PathCombine(source, "vanilla-1.21.5-levels.txt")))
.split(QRegularExpression("\n|\r\n|\r"), Qt::SkipEmptyParts);
QList<MessageLevel::Enum> shortTextLevels;
shortTextLevels.reserve(24);
std::transform(shortTextLevels_s.cbegin(), shortTextLevels_s.cend(), std::back_inserter(shortTextLevels),
[](const QString& line) { return MessageLevel::getLevel(line.trimmed()); });
QString longXml = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-forge.xml.log"))); QString longXml = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-forge.xml.log")));
QString longText = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-forge.text.log"))); QString longText = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-forge.text.log")));
QTest::addColumn<QString>("text"); QStringList longTextLevels_s = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-levels.txt")))
QTest::addColumn<QString>("xml"); .split(QRegularExpression("\n|\r\n|\r"), Qt::SkipEmptyParts);
QTest::newRow("short-vanilla") << shortText << shortXml; QStringList longTextLevelsXml_s = QString::fromUtf8(FS::read(FS::PathCombine(source, "TerraFirmaGreg-Modern-xml-levels.txt")))
QTest::newRow("long-forge") << longText << longXml; .split(QRegularExpression("\n|\r\n|\r"), Qt::SkipEmptyParts);
QList<MessageLevel::Enum> longTextLevelsPlain;
longTextLevelsPlain.reserve(974);
std::transform(longTextLevels_s.cbegin(), longTextLevels_s.cend(), std::back_inserter(longTextLevelsPlain),
[](const QString& line) { return MessageLevel::getLevel(line.trimmed()); });
QList<MessageLevel::Enum> longTextLevelsXml;
longTextLevelsXml.reserve(896);
std::transform(longTextLevelsXml_s.cbegin(), longTextLevelsXml_s.cend(), std::back_inserter(longTextLevelsXml),
[](const QString& line) { return MessageLevel::getLevel(line.trimmed()); });
QTest::addColumn<QString>("log");
QTest::addColumn<int>("num_entries");
QTest::addColumn<QList<MessageLevel::Enum>>("entry_levels");
QTest::newRow("short-vanilla-plain") << shortText << 25 << shortTextLevels;
QTest::newRow("short-vanilla-xml") << shortXml << 25 << shortTextLevels;
QTest::newRow("long-forge-plain") << longText << 945 << longTextLevelsPlain;
QTest::newRow("long-forge-xml") << longXml << 869 << longTextLevelsXml;
} }
void parseXml() { QFETCH(QString, ) } void parseXml()
{
QFETCH(QString, log);
QFETCH(int, num_entries);
QFETCH(QList<MessageLevel::Enum>, entry_levels);
QList<std::pair<MessageLevel::Enum, QString>> entries = {};
QBENCHMARK
{
entries = parseLines(log.split(QRegularExpression("\n|\r\n|\r")));
}
QCOMPARE(entries.length(), num_entries);
QList<MessageLevel::Enum> levels = {};
std::transform(entries.cbegin(), entries.cend(), std::back_inserter(levels),
[](std::pair<MessageLevel::Enum, QString> entry) { return entry.first; });
QCOMPARE(levels, entry_levels);
}
private: private:
LogParser m_parser; LogParser m_parser;
@ -59,27 +107,35 @@ class XmlLogParseTest : public QObject {
QList<std::pair<MessageLevel::Enum, QString>> parseLines(const QStringList& lines) QList<std::pair<MessageLevel::Enum, QString>> parseLines(const QStringList& lines)
{ {
QList<std::pair<MessageLevel::Enum, QString>> out; QList<std::pair<MessageLevel::Enum, QString>> out;
for (const auto& line : lines) MessageLevel::Enum last = MessageLevel::Unknown;
for (const auto& line : lines) {
m_parser.appendLine(line); m_parser.appendLine(line);
auto items = m_parser.parseAvailable();
for (const auto& item : items) { auto items = m_parser.parseAvailable();
if (std::holds_alternative<LogParser::LogEntry>(item)) { for (const auto& item : items) {
auto entry = std::get<LogParser::LogEntry>(item); if (std::holds_alternative<LogParser::LogEntry>(item)) {
auto msg = QString("[%1] [%2/%3] [%4]: %5") auto entry = std::get<LogParser::LogEntry>(item);
.arg(entry.timestamp.toString("HH:mm:ss")) auto msg = QString("[%1] [%2/%3] [%4]: %5")
.arg(entry.thread) .arg(entry.timestamp.toString("HH:mm:ss"))
.arg(entry.levelText) .arg(entry.thread)
.arg(entry.logger) .arg(entry.levelText)
.arg(entry.message); .arg(entry.logger)
msg = censorPrivateInfo(msg); .arg(entry.message);
out.append(std::make_pair(entry.level, msg)); out.append(std::make_pair(entry.level, msg));
} else if (std::holds_alternative<LogParser::PlainText>(item)) { last = entry.level;
auto msg = std::get<LogParser::PlainText>(item).message; } else if (std::holds_alternative<LogParser::PlainText>(item)) {
level = m_instance->guessLevel(msg, level); auto msg = std::get<LogParser::PlainText>(item).message;
msg = censorPrivateInfo(msg); auto level = LogParser::guessLevel(msg, last);
out.append(std::make_pair(entry.level, msg)); out.append(std::make_pair(level, msg));
last = level;
}
} }
} }
return out; return out;
} }
}; };
QTEST_GUILESS_MAIN(XmlLogParseTest)
#include "XmlLogs_test.moc"

View File

@ -0,0 +1,945 @@
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
INFO
ERROR
INFO
ERROR
ERROR
ERROR
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
WARN
INFO
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
INFO
INFO
WARN
WARN
WARN
INFO
WARN
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
WARN
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
INFO
INFO
WARN
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
ERROR
ERROR
ERROR
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN

View File

@ -0,0 +1,869 @@
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
ERROR
INFO
ERROR
ERROR
ERROR
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
WARN
INFO
WARN
WARN
WARN
WARN
WARN
INFO
WARN
WARN
INFO
INFO
WARN
WARN
WARN
INFO
WARN
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
WARN
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
WARN
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
INFO
INFO
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
ERROR
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
WARN
WARN
INFO
INFO
INFO
INFO
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
WARN
WARN
WARN
WARN
WARN
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
ERROR
ERROR
ERROR
ERROR
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO

View File

@ -0,0 +1,25 @@
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
WARN
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO
INFO