forked from quickshell/quickshell
		
	core/log: create fully detailed logs by default
The .qslog logs now log messages for quickshell* by default.
This commit is contained in:
		
							parent
							
								
									291179ede2
								
							
						
					
					
						commit
						0fc98652a8
					
				
					 4 changed files with 85 additions and 13 deletions
				
			
		| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
#include <qbytearrayview.h>
 | 
			
		||||
#include <qdatetime.h>
 | 
			
		||||
#include <qendian.h>
 | 
			
		||||
#include <qhash.h>
 | 
			
		||||
#include <qhashfunctions.h>
 | 
			
		||||
#include <qlogging.h>
 | 
			
		||||
#include <qloggingcategory.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -92,10 +93,48 @@ void LogManager::messageHandler(
 | 
			
		|||
 | 
			
		||||
	auto* self = LogManager::instance();
 | 
			
		||||
 | 
			
		||||
	LogMessage::formatMessage(self->stdoutStream, message, self->colorLogs, false);
 | 
			
		||||
	self->stdoutStream << Qt::endl;
 | 
			
		||||
	auto display = true;
 | 
			
		||||
 | 
			
		||||
	emit self->logMessage(message);
 | 
			
		||||
	const auto* key = static_cast<const void*>(context.category);
 | 
			
		||||
 | 
			
		||||
	if (self->sparseFilters.contains(key)) {
 | 
			
		||||
		auto filter = self->sparseFilters.value(key);
 | 
			
		||||
		switch (type) {
 | 
			
		||||
		case QtDebugMsg: display = filter.debug; break;
 | 
			
		||||
		case QtInfoMsg: display = filter.info; break;
 | 
			
		||||
		case QtWarningMsg: display = filter.warn; break;
 | 
			
		||||
		case QtCriticalMsg: display = filter.critical; break;
 | 
			
		||||
		default: break;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (display) {
 | 
			
		||||
		LogMessage::formatMessage(self->stdoutStream, message, self->colorLogs, false);
 | 
			
		||||
		self->stdoutStream << Qt::endl;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	emit self->logMessage(message, display);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogManager::filterCategory(QLoggingCategory* category) {
 | 
			
		||||
	auto* instance = LogManager::instance();
 | 
			
		||||
 | 
			
		||||
	if (instance->lastCategoryFilter) {
 | 
			
		||||
		instance->lastCategoryFilter(category);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (QLatin1StringView(category->categoryName()).startsWith(QLatin1StringView("quickshell"))) {
 | 
			
		||||
		// We assume the category name pointer will always be the same and be comparable in the message handler.
 | 
			
		||||
		LogManager::instance()->sparseFilters.insert(
 | 
			
		||||
		    static_cast<const void*>(category->categoryName()),
 | 
			
		||||
		    CategoryFilter(category)
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		category->setEnabled(QtDebugMsg, true);
 | 
			
		||||
		category->setEnabled(QtInfoMsg, true);
 | 
			
		||||
		category->setEnabled(QtWarningMsg, true);
 | 
			
		||||
		category->setEnabled(QtCriticalMsg, true);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
LogManager* LogManager::instance() {
 | 
			
		||||
| 
						 | 
				
			
			@ -103,12 +142,16 @@ LogManager* LogManager::instance() {
 | 
			
		|||
	return instance;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LogManager::init(bool color) {
 | 
			
		||||
void LogManager::init(bool color, bool sparseOnly) {
 | 
			
		||||
	auto* instance = LogManager::instance();
 | 
			
		||||
	instance->colorLogs = color;
 | 
			
		||||
 | 
			
		||||
	qInstallMessageHandler(&LogManager::messageHandler);
 | 
			
		||||
 | 
			
		||||
	if (!sparseOnly) {
 | 
			
		||||
		instance->lastCategoryFilter = QLoggingCategory::installFilter(&LogManager::filterCategory);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	qCDebug(logLogging) << "Creating offthread logger...";
 | 
			
		||||
	auto* thread = new QThread();
 | 
			
		||||
	instance->threadProxy.moveToThread(thread);
 | 
			
		||||
| 
						 | 
				
			
			@ -269,10 +312,12 @@ void ThreadLogging::initFs() {
 | 
			
		|||
	qCDebug(logLogging) << "Switched threaded logger to queued eventloop connection.";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ThreadLogging::onMessage(const LogMessage& msg) {
 | 
			
		||||
	if (this->fileStream.device() == nullptr) return;
 | 
			
		||||
	LogMessage::formatMessage(this->fileStream, msg, false, true);
 | 
			
		||||
	this->fileStream << Qt::endl;
 | 
			
		||||
void ThreadLogging::onMessage(const LogMessage& msg, bool showInSparse) {
 | 
			
		||||
	if (showInSparse) {
 | 
			
		||||
		if (this->fileStream.device() == nullptr) return;
 | 
			
		||||
		LogMessage::formatMessage(this->fileStream, msg, false, true);
 | 
			
		||||
		this->fileStream << Qt::endl;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (this->detailedWriter.write(msg)) {
 | 
			
		||||
		this->detailedFile->flush();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@
 | 
			
		|||
#include <qhash.h>
 | 
			
		||||
#include <qlatin1stringview.h>
 | 
			
		||||
#include <qlogging.h>
 | 
			
		||||
#include <qloggingcategory.h>
 | 
			
		||||
#include <qobject.h>
 | 
			
		||||
#include <qtmetamacros.h>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -54,23 +55,42 @@ private:
 | 
			
		|||
	ThreadLogging* logging = nullptr;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct CategoryFilter {
 | 
			
		||||
	explicit CategoryFilter() = default;
 | 
			
		||||
	explicit CategoryFilter(QLoggingCategory* category)
 | 
			
		||||
	    : debug(category->isDebugEnabled())
 | 
			
		||||
	    , info(category->isInfoEnabled())
 | 
			
		||||
	    , warn(category->isWarningEnabled())
 | 
			
		||||
	    , critical(category->isCriticalEnabled()) {}
 | 
			
		||||
 | 
			
		||||
	bool debug = true;
 | 
			
		||||
	bool info = true;
 | 
			
		||||
	bool warn = true;
 | 
			
		||||
	bool critical = true;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
class LogManager: public QObject {
 | 
			
		||||
	Q_OBJECT;
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
	static void init(bool color);
 | 
			
		||||
	static void init(bool color, bool sparseOnly);
 | 
			
		||||
	static void initFs();
 | 
			
		||||
	static LogManager* instance();
 | 
			
		||||
 | 
			
		||||
	bool colorLogs = true;
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
	void logMessage(LogMessage msg);
 | 
			
		||||
	void logMessage(LogMessage msg, bool showInSparse);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	explicit LogManager();
 | 
			
		||||
	static void messageHandler(QtMsgType type, const QMessageLogContext& context, const QString& msg);
 | 
			
		||||
 | 
			
		||||
	static void filterCategory(QLoggingCategory* category);
 | 
			
		||||
 | 
			
		||||
	QLoggingCategory::CategoryFilter lastCategoryFilter = nullptr;
 | 
			
		||||
	QHash<const void*, CategoryFilter> sparseFilters;
 | 
			
		||||
 | 
			
		||||
	QTextStream stdoutStream;
 | 
			
		||||
	LoggingThreadProxy threadProxy;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -111,7 +111,7 @@ public:
 | 
			
		|||
	void setupFileLogging();
 | 
			
		||||
 | 
			
		||||
private slots:
 | 
			
		||||
	void onMessage(const LogMessage& msg);
 | 
			
		||||
	void onMessage(const LogMessage& msg, bool showInSparse);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
	QFile* file = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,8 +2,8 @@
 | 
			
		|||
#include <iostream>
 | 
			
		||||
#include <string>
 | 
			
		||||
 | 
			
		||||
#include <CLI/CLI.hpp> // NOLINT: Need to include this for impls of some CLI11 classes
 | 
			
		||||
#include <CLI/App.hpp>
 | 
			
		||||
#include <CLI/CLI.hpp> // NOLINT: Need to include this for impls of some CLI11 classes
 | 
			
		||||
#include <CLI/Validators.hpp>
 | 
			
		||||
#include <qapplication.h>
 | 
			
		||||
#include <qcoreapplication.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -129,9 +129,16 @@ int qs_main(int argc, char** argv) {
 | 
			
		|||
		    ->needs(debugPortArg);
 | 
			
		||||
 | 
			
		||||
		/// ---
 | 
			
		||||
		bool sparseLogsOnly = false;
 | 
			
		||||
		app.add_flag("--info", printInfo, "Print information about the shell")->excludes(debugPortArg);
 | 
			
		||||
		app.add_flag("--no-color", noColor, "Do not color the log output. (Env:NO_COLOR)");
 | 
			
		||||
 | 
			
		||||
		app.add_flag(
 | 
			
		||||
		    "--no-detailed-logs",
 | 
			
		||||
		    sparseLogsOnly,
 | 
			
		||||
		    "Do not enable this unless you know what you are doing."
 | 
			
		||||
		);
 | 
			
		||||
 | 
			
		||||
		/// ---
 | 
			
		||||
		QStringOption logpath;
 | 
			
		||||
		auto* readLog = app.add_subcommand("read-log", "Read a quickshell log file.");
 | 
			
		||||
| 
						 | 
				
			
			@ -143,7 +150,7 @@ int qs_main(int argc, char** argv) {
 | 
			
		|||
		const auto qApplication = QCoreApplication(qArgC, qArgV);
 | 
			
		||||
 | 
			
		||||
		// Start log manager - has to happen with an active event loop or offthread can't be started.
 | 
			
		||||
		LogManager::init(!noColor);
 | 
			
		||||
		LogManager::init(!noColor, sparseLogsOnly);
 | 
			
		||||
 | 
			
		||||
		if (*readLog) {
 | 
			
		||||
			auto file = QFile(*logpath);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue