forked from quickshell/quickshell
		
	core/command: allow qs log to retrieve logs of dead instances
				
					
				
			If no live instances are found matching the current config, the youngest dead instance will be used instead.
This commit is contained in:
		
							parent
							
								
									0662c37d67
								
							
						
					
					
						commit
						eabf79ebb6
					
				
					 3 changed files with 28 additions and 16 deletions
				
			
		| 
						 | 
					@ -262,7 +262,7 @@ void QsPaths::createLock() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info) {
 | 
					bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info, bool allowDead) {
 | 
				
			||||||
	auto file = QFile(QDir(path).filePath("instance.lock"));
 | 
						auto file = QFile(QDir(path).filePath("instance.lock"));
 | 
				
			||||||
	if (!file.open(QFile::ReadOnly)) return false;
 | 
						if (!file.open(QFile::ReadOnly)) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -275,10 +275,12 @@ bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info) {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fcntl(file.handle(), F_GETLK, &lock); // NOLINT
 | 
						fcntl(file.handle(), F_GETLK, &lock); // NOLINT
 | 
				
			||||||
	if (lock.l_type == F_UNLCK) return false;
 | 
						auto isLocked = lock.l_type != F_UNLCK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!isLocked && !allowDead) return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (info) {
 | 
						if (info) {
 | 
				
			||||||
		info->pid = lock.l_pid;
 | 
							info->pid = isLocked ? lock.l_pid : -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto stream = QDataStream(&file);
 | 
							auto stream = QDataStream(&file);
 | 
				
			||||||
		stream >> info->instance;
 | 
							stream >> info->instance;
 | 
				
			||||||
| 
						 | 
					@ -287,7 +289,7 @@ bool QsPaths::checkLock(const QString& path, InstanceLockInfo* info) {
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
QVector<InstanceLockInfo> QsPaths::collectInstances(const QString& path) {
 | 
					QVector<InstanceLockInfo> QsPaths::collectInstances(const QString& path, bool fallbackDead) {
 | 
				
			||||||
	qCDebug(logPaths) << "Collecting instances from" << path;
 | 
						qCDebug(logPaths) << "Collecting instances from" << path;
 | 
				
			||||||
	auto instances = QVector<InstanceLockInfo>();
 | 
						auto instances = QVector<InstanceLockInfo>();
 | 
				
			||||||
	auto dir = QDir(path);
 | 
						auto dir = QDir(path);
 | 
				
			||||||
| 
						 | 
					@ -296,13 +298,18 @@ QVector<InstanceLockInfo> QsPaths::collectInstances(const QString& path) {
 | 
				
			||||||
	for (auto& entry: dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
 | 
						for (auto& entry: dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
 | 
				
			||||||
		auto path = dir.filePath(entry);
 | 
							auto path = dir.filePath(entry);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (QsPaths::checkLock(path, &info)) {
 | 
							if (QsPaths::checkLock(path, &info, fallbackDead)) {
 | 
				
			||||||
			qCDebug(logPaths).nospace() << "Found live instance " << info.instance.instanceId << " (pid "
 | 
								if (fallbackDead && info.pid != -1) {
 | 
				
			||||||
 | 
									fallbackDead = false;
 | 
				
			||||||
 | 
									instances.clear();
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								qCDebug(logPaths).nospace() << "Found instance " << info.instance.instanceId << " (pid "
 | 
				
			||||||
			                            << info.pid << ") at " << path;
 | 
								                            << info.pid << ") at " << path;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			instances.push_back(info);
 | 
								instances.push_back(info);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			qCDebug(logPaths) << "Skipped dead instance at" << path;
 | 
								qCDebug(logPaths) << "Skipped potential instance at" << path;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -20,8 +20,9 @@ public:
 | 
				
			||||||
	static QDir crashDir(const QString& id);
 | 
						static QDir crashDir(const QString& id);
 | 
				
			||||||
	static QString basePath(const QString& id);
 | 
						static QString basePath(const QString& id);
 | 
				
			||||||
	static QString ipcPath(const QString& id);
 | 
						static QString ipcPath(const QString& id);
 | 
				
			||||||
	static bool checkLock(const QString& path, InstanceLockInfo* info = nullptr);
 | 
						static bool
 | 
				
			||||||
	static QVector<InstanceLockInfo> collectInstances(const QString& path);
 | 
						checkLock(const QString& path, InstanceLockInfo* info = nullptr, bool allowDead = false);
 | 
				
			||||||
 | 
						static QVector<InstanceLockInfo> collectInstances(const QString& path, bool fallbackDead = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QDir* cacheDir();
 | 
						QDir* cacheDir();
 | 
				
			||||||
	QDir* baseRunDir();
 | 
						QDir* baseRunDir();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -109,7 +109,7 @@ void sortInstances(QVector<InstanceLockInfo>& list, bool newestFirst) {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
 | 
					int selectInstance(CommandState& cmd, InstanceLockInfo* instance, bool deadFallback = false) {
 | 
				
			||||||
	auto* basePath = QsPaths::instance()->baseRunDir();
 | 
						auto* basePath = QsPaths::instance()->baseRunDir();
 | 
				
			||||||
	if (!basePath) return -1;
 | 
						if (!basePath) return -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,13 +117,13 @@ int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (cmd.instance.pid != -1) {
 | 
						if (cmd.instance.pid != -1) {
 | 
				
			||||||
		path = QDir(basePath->filePath("by-pid")).filePath(QString::number(cmd.instance.pid));
 | 
							path = QDir(basePath->filePath("by-pid")).filePath(QString::number(cmd.instance.pid));
 | 
				
			||||||
		if (!QsPaths::checkLock(path, instance)) {
 | 
							if (!QsPaths::checkLock(path, instance, deadFallback)) {
 | 
				
			||||||
			qCInfo(logBare) << "No instance found for pid" << cmd.instance.pid;
 | 
								qCInfo(logBare) << "No instance found for pid" << cmd.instance.pid;
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (!cmd.instance.id->isEmpty()) {
 | 
						} else if (!cmd.instance.id->isEmpty()) {
 | 
				
			||||||
		path = basePath->filePath("by-pid");
 | 
							path = basePath->filePath("by-pid");
 | 
				
			||||||
		auto instances = QsPaths::collectInstances(path);
 | 
							auto instances = QsPaths::collectInstances(path, deadFallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		instances.removeIf([&](const InstanceLockInfo& info) {
 | 
							instances.removeIf([&](const InstanceLockInfo& info) {
 | 
				
			||||||
			return !info.instance.instanceId.startsWith(*cmd.instance.id);
 | 
								return !info.instance.instanceId.startsWith(*cmd.instance.id);
 | 
				
			||||||
| 
						 | 
					@ -136,7 +136,8 @@ int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
 | 
				
			||||||
			qCInfo(logBare) << "More than one instance starts with" << *cmd.instance.id;
 | 
								qCInfo(logBare) << "More than one instance starts with" << *cmd.instance.id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			for (auto& instance: instances) {
 | 
								for (auto& instance: instances) {
 | 
				
			||||||
				qCInfo(logBare).noquote() << " -" << instance.instance.instanceId;
 | 
									qCInfo(logBare).noquote() << " -" << instance.instance.instanceId
 | 
				
			||||||
 | 
									                          << (instance.pid == -1 ? " (dead)" : "");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			return -1;
 | 
								return -1;
 | 
				
			||||||
| 
						 | 
					@ -153,8 +154,11 @@ int selectInstance(CommandState& cmd, InstanceLockInfo* instance) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		path = QDir(basePath->filePath("by-path")).filePath(pathId);
 | 
							path = QDir(basePath->filePath("by-path")).filePath(pathId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto instances = QsPaths::collectInstances(path);
 | 
							auto instances = QsPaths::collectInstances(path, deadFallback);
 | 
				
			||||||
		sortInstances(instances, cmd.config.newest);
 | 
							sortInstances(
 | 
				
			||||||
 | 
							    instances,
 | 
				
			||||||
 | 
							    cmd.config.newest || (!instances.empty() && instances.first().pid == -1)
 | 
				
			||||||
 | 
							);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (instances.isEmpty()) {
 | 
							if (instances.isEmpty()) {
 | 
				
			||||||
			qCInfo(logBare) << "No running instances for" << configFilePath;
 | 
								qCInfo(logBare) << "No running instances for" << configFilePath;
 | 
				
			||||||
| 
						 | 
					@ -172,7 +176,7 @@ int readLogFile(CommandState& cmd) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (path.isEmpty()) {
 | 
						if (path.isEmpty()) {
 | 
				
			||||||
		InstanceLockInfo instance;
 | 
							InstanceLockInfo instance;
 | 
				
			||||||
		auto r = selectInstance(cmd, &instance);
 | 
							auto r = selectInstance(cmd, &instance, true);
 | 
				
			||||||
		if (r != 0) return r;
 | 
							if (r != 0) return r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		path = QDir(QsPaths::basePath(instance.instance.instanceId)).filePath("log.qslog");
 | 
							path = QDir(QsPaths::basePath(instance.instance.instanceId)).filePath("log.qslog");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue