From c78381f6d00dabcf864e6c5343edbbbd0828902d Mon Sep 17 00:00:00 2001 From: outfoxxed Date: Tue, 10 Sep 2024 01:02:43 -0700 Subject: [PATCH] core/command: add --tail to log subcommand --- src/core/logging.cpp | 24 ++++++++++++++++++++---- src/core/logging.hpp | 2 +- src/core/main.cpp | 10 +++++++++- 3 files changed, 30 insertions(+), 6 deletions(-) diff --git a/src/core/logging.cpp b/src/core/logging.cpp index 60d2c3c2..a6360fe5 100644 --- a/src/core/logging.cpp +++ b/src/core/logging.cpp @@ -28,6 +28,7 @@ #include "logging_p.hpp" #include "logging_qtprivate.cpp" // NOLINT #include "paths.hpp" +#include "ringbuf.hpp" Q_LOGGING_CATEGORY(logBare, "quickshell.bare"); @@ -65,6 +66,7 @@ void LogMessage::formatMessage( } if (msg.category == "quickshell.bare") { + if (!prefix.isEmpty()) stream << ' '; stream << msg.body; } else { if (color) { @@ -243,9 +245,9 @@ void LogManager::init( thread->start(); QMetaObject::invokeMethod( - &instance->threadProxy, - &LoggingThreadProxy::initInThread, - Qt::BlockingQueuedConnection + &instance->threadProxy, + &LoggingThreadProxy::initInThread, + Qt::BlockingQueuedConnection ); qCDebug(logLogging) << "Logger initialized."; @@ -735,7 +737,7 @@ bool EncodedLogReader::registerCategory() { return true; } -bool readEncodedLogs(QIODevice* device, bool timestamps, const QString& rulespec) { +bool readEncodedLogs(QIODevice* device, bool timestamps, int tail, const QString& rulespec) { QList rules; { @@ -767,6 +769,8 @@ bool readEncodedLogs(QIODevice* device, bool timestamps, const QString& rulespec auto filters = QHash(); + auto tailRing = RingBuffer(tail); + LogMessage message; auto stream = QTextStream(stdout); while (reader.read(&message)) { @@ -782,6 +786,18 @@ bool readEncodedLogs(QIODevice* device, bool timestamps, const QString& rulespec } if (filter.shouldDisplay(message.type)) { + if (tail == 0) { + LogMessage::formatMessage(stream, message, color, timestamps); + stream << '\n'; + } else { + tailRing.emplace(message); + } + } + } + + if (tail != 0) { + for (auto i = tailRing.size() - 1; i != -1; i--) { + auto& message = tailRing.at(i); LogMessage::formatMessage(stream, message, color, timestamps); stream << '\n'; } diff --git a/src/core/logging.hpp b/src/core/logging.hpp index bd3be771..131e840f 100644 --- a/src/core/logging.hpp +++ b/src/core/logging.hpp @@ -130,7 +130,7 @@ private: LoggingThreadProxy threadProxy; }; -bool readEncodedLogs(QIODevice* device, bool timestamps, const QString& rulespec); +bool readEncodedLogs(QIODevice* device, bool timestamps, int tail, const QString& rulespec); } // namespace qs::log diff --git a/src/core/main.cpp b/src/core/main.cpp index 749f8a05..2e3a43fe 100644 --- a/src/core/main.cpp +++ b/src/core/main.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,7 @@ struct CommandState { bool noColor = !qEnvironmentVariableIsEmpty("NO_COLOR"); bool sparse = false; size_t verbosity = 0; + int tail = 0; QStringOption rules; QStringOption readoutRules; QStringOption file; @@ -249,6 +251,10 @@ int runCommand(int argc, char** argv, QCoreApplication* coreApplication) { auto* file = sub->add_option("--file", state.log.file, "Log file to read."); + sub->add_option("-t,--tail", state.log.tail) + ->description("Maximum number of lines to print, starting from the bottom.") + ->check(CLI::Range(1, std::numeric_limits::max(), "INT > 0")); + sub->add_option("-r,--rules", state.log.readoutRules, "Log file to read.") ->description("Rules to apply to the log being read, in the format of QT_LOGGING_RULES."); @@ -466,7 +472,9 @@ int readLogFile(CommandState& cmd) { return -1; } - return qs::log::readEncodedLogs(&file, cmd.log.timestamp, *cmd.log.readoutRules) ? 0 : -1; + return qs::log::readEncodedLogs(&file, cmd.log.timestamp, cmd.log.tail, *cmd.log.readoutRules) + ? 0 + : -1; } int listInstances(CommandState& cmd) {