summaryrefslogtreecommitdiff
path: root/src/debug
diff options
context:
space:
mode:
authorVaxry <43317083+vaxerski@users.noreply.github.com>2025-12-18 17:23:24 +0000
committerGitHub <noreply@github.com>2025-12-18 17:23:24 +0000
commit6175ecd4c4ba817c4620f66a75e1e11da7c7a8ca (patch)
treecf73852f1fc08b1dcee5a3a7380f914aaad9c50a /src/debug
parentf88deb928a0f7dc02f427473f8c29e8f2bed14a3 (diff)
debug: move to hyprutils' logger (#12673)
Diffstat (limited to 'src/debug')
-rw-r--r--src/debug/HyprCtl.cpp43
-rw-r--r--src/debug/Log.cpp78
-rw-r--r--src/debug/Log.hpp75
-rw-r--r--src/debug/TracyDefines.hpp2
-rw-r--r--src/debug/crash/CrashReporter.cpp2
-rw-r--r--src/debug/log/Logger.cpp64
-rw-r--r--src/debug/log/Logger.hpp61
-rw-r--r--src/debug/log/RollingLogFollow.hpp (renamed from src/debug/RollingLogFollow.hpp)14
8 files changed, 157 insertions, 182 deletions
diff --git a/src/debug/HyprCtl.cpp b/src/debug/HyprCtl.cpp
index 5e21d699..90adab91 100644
--- a/src/debug/HyprCtl.cpp
+++ b/src/debug/HyprCtl.cpp
@@ -40,7 +40,7 @@ using namespace Hyprutils::OS;
#include "../devices/ITouch.hpp"
#include "../devices/Tablet.hpp"
#include "../protocols/GlobalShortcuts.hpp"
-#include "debug/RollingLogFollow.hpp"
+#include "debug/log/RollingLogFollow.hpp"
#include "config/ConfigManager.hpp"
#include "helpers/MiscFunctions.hpp"
#include "../desktop/view/LayerSurface.hpp"
@@ -957,11 +957,10 @@ static std::string rollinglogRequest(eHyprCtlOutputFormat format, std::string re
if (format == eHyprCtlOutputFormat::FORMAT_JSON) {
result += "[\n\"log\":\"";
- result += escapeJSONStrings(Debug::m_rollingLog);
+ result += escapeJSONStrings(Log::logger->rolling());
result += "\"]";
- } else {
- result = Debug::m_rollingLog;
- }
+ } else
+ result = Log::logger->rolling();
return result;
}
@@ -1260,7 +1259,7 @@ static std::string dispatchRequest(eHyprCtlOutputFormat format, std::string in)
SDispatchResult res = DISPATCHER->second(DISPATCHARG);
- Debug::log(LOG, "Hyprctl: dispatcher {} : {}{}", DISPATCHSTR, DISPATCHARG, res.success ? "" : " -> " + res.error);
+ Log::logger->log(Log::DEBUG, "Hyprctl: dispatcher {} : {}{}", DISPATCHSTR, DISPATCHARG, res.success ? "" : " -> " + res.error);
return res.success ? "ok" : res.error;
}
@@ -1340,7 +1339,7 @@ static std::string dispatchKeyword(eHyprCtlOutputFormat format, std::string in)
if (COMMAND.contains("workspace"))
g_pConfigManager->ensurePersistentWorkspacesPresent();
- Debug::log(LOG, "Hyprctl: keyword {} : {}", COMMAND, VALUE);
+ Log::logger->log(Log::DEBUG, "Hyprctl: keyword {} : {}", COMMAND, VALUE);
if (retval.empty())
return "ok";
@@ -2223,23 +2222,23 @@ static bool successWrite(int fd, const std::string& data, bool needLog = true) {
return true;
if (needLog)
- Debug::log(ERR, "Couldn't write to socket. Error: " + std::string(strerror(errno)));
+ Log::logger->log(Log::ERR, "Couldn't write to socket. Error: " + std::string(strerror(errno)));
return false;
}
static void runWritingDebugLogThread(const int conn) {
using namespace std::chrono_literals;
- Debug::log(LOG, "In followlog thread, got connection, start writing: {}", conn);
+ Log::logger->log(Log::DEBUG, "In followlog thread, got connection, start writing: {}", conn);
//will be finished, when reading side close connection
std::thread([conn]() {
- while (Debug::SRollingLogFollow::get().isRunning()) {
- if (Debug::SRollingLogFollow::get().isEmpty(conn)) {
+ while (Log::SRollingLogFollow::get().isRunning()) {
+ if (Log::SRollingLogFollow::get().isEmpty(conn)) {
std::this_thread::sleep_for(1000ms);
continue;
}
- auto line = Debug::SRollingLogFollow::get().getLog(conn);
+ auto line = Log::SRollingLogFollow::get().getLog(conn);
if (!successWrite(conn, line))
// We cannot write, when connection is closed. So thread will successfully exit by itself
break;
@@ -2247,7 +2246,7 @@ static void runWritingDebugLogThread(const int conn) {
std::this_thread::sleep_for(100ms);
}
close(conn);
- Debug::SRollingLogFollow::get().stopFor(conn);
+ Log::SRollingLogFollow::get().stopFor(conn);
}).detach();
}
@@ -2273,10 +2272,10 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
CRED_T creds;
uint32_t len = sizeof(creds);
if (getsockopt(ACCEPTEDCONNECTION, CRED_LVL, CRED_OPT, &creds, &len) == -1)
- Debug::log(ERR, "Hyprctl: failed to get peer creds");
+ Log::logger->log(Log::ERR, "Hyprctl: failed to get peer creds");
else {
g_pHyprCtl->m_currentRequestParams.pid = creds.CRED_PID;
- Debug::log(LOG, "Hyprctl: new connection from pid {}", creds.CRED_PID);
+ Log::logger->log(Log::DEBUG, "Hyprctl: new connection from pid {}", creds.CRED_PID);
}
//
@@ -2311,7 +2310,7 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
try {
reply = g_pHyprCtl->getReply(request);
} catch (std::exception& e) {
- Debug::log(ERR, "Error in request: {}", e.what());
+ Log::logger->log(Log::ERR, "Error in request: {}", e.what());
reply = "Err: " + std::string(e.what());
}
@@ -2331,10 +2330,10 @@ static int hyprCtlFDTick(int fd, uint32_t mask, void* data) {
successWrite(ACCEPTEDCONNECTION, reply);
if (isFollowUpRollingLogRequest(request)) {
- Debug::log(LOG, "Followup rollinglog request received. Starting thread to write to socket.");
- Debug::SRollingLogFollow::get().startFor(ACCEPTEDCONNECTION);
+ Log::logger->log(Log::DEBUG, "Followup rollinglog request received. Starting thread to write to socket.");
+ Log::SRollingLogFollow::get().startFor(ACCEPTEDCONNECTION);
runWritingDebugLogThread(ACCEPTEDCONNECTION);
- Debug::log(LOG, Debug::SRollingLogFollow::get().debugInfo());
+ Log::logger->log(Log::DEBUG, Log::SRollingLogFollow::get().debugInfo());
} else
close(ACCEPTEDCONNECTION);
@@ -2351,7 +2350,7 @@ void CHyprCtl::startHyprCtlSocket() {
m_socketFD = CFileDescriptor{socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0)};
if (!m_socketFD.isValid()) {
- Debug::log(ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
+ Log::logger->log(Log::ERR, "Couldn't start the Hyprland Socket. (1) IPC will not work.");
return;
}
@@ -2362,14 +2361,14 @@ void CHyprCtl::startHyprCtlSocket() {
snprintf(SERVERADDRESS.sun_path, sizeof(SERVERADDRESS.sun_path), "%s", m_socketPath.c_str());
if (bind(m_socketFD.get(), rc<sockaddr*>(&SERVERADDRESS), SUN_LEN(&SERVERADDRESS)) < 0) {
- Debug::log(ERR, "Couldn't start the Hyprland Socket. (2) IPC will not work.");
+ Log::logger->log(Log::ERR, "Couldn't start the Hyprland Socket. (2) IPC will not work.");
return;
}
// 10 max queued.
listen(m_socketFD.get(), 10);
- Debug::log(LOG, "Hypr socket started at {}", m_socketPath);
+ Log::logger->log(Log::DEBUG, "Hypr socket started at {}", m_socketPath);
m_eventSource = wl_event_loop_add_fd(g_pCompositor->m_wlEventLoop, m_socketFD.get(), WL_EVENT_READABLE, hyprCtlFDTick, nullptr);
}
diff --git a/src/debug/Log.cpp b/src/debug/Log.cpp
deleted file mode 100644
index e70617d3..00000000
--- a/src/debug/Log.cpp
+++ /dev/null
@@ -1,78 +0,0 @@
-#include "Log.hpp"
-#include "../defines.hpp"
-#include "RollingLogFollow.hpp"
-
-#include <fstream>
-#include <print>
-#include <fcntl.h>
-
-void Debug::init(const std::string& IS) {
- m_logFile = IS + (ISDEBUG ? "/hyprlandd.log" : "/hyprland.log");
- m_logOfs.open(m_logFile, std::ios::out | std::ios::app);
- auto handle = m_logOfs.native_handle();
- fcntl(handle, F_SETFD, FD_CLOEXEC);
-}
-
-void Debug::close() {
- m_logOfs.close();
-}
-
-void Debug::log(eLogLevel level, std::string str) {
- if (level == TRACE && !m_trace)
- return;
-
- if (m_shuttingDown)
- return;
-
- std::lock_guard<std::mutex> guard(m_logMutex);
-
- std::string coloredStr = str;
- //NOLINTBEGIN
- switch (level) {
- case LOG:
- str = "[LOG] " + str;
- coloredStr = str;
- break;
- case WARN:
- str = "[WARN] " + str;
- coloredStr = "\033[1;33m" + str + "\033[0m"; // yellow
- break;
- case ERR:
- str = "[ERR] " + str;
- coloredStr = "\033[1;31m" + str + "\033[0m"; // red
- break;
- case CRIT:
- str = "[CRITICAL] " + str;
- coloredStr = "\033[1;35m" + str + "\033[0m"; // magenta
- break;
- case INFO:
- str = "[INFO] " + str;
- coloredStr = "\033[1;32m" + str + "\033[0m"; // green
- break;
- case TRACE:
- str = "[TRACE] " + str;
- coloredStr = "\033[1;34m" + str + "\033[0m"; // blue
- break;
- default: break;
- }
- //NOLINTEND
-
- m_rollingLog += str + "\n";
- if (m_rollingLog.size() > ROLLING_LOG_SIZE)
- m_rollingLog = m_rollingLog.substr(m_rollingLog.size() - ROLLING_LOG_SIZE);
-
- if (SRollingLogFollow::get().isRunning())
- SRollingLogFollow::get().addLog(str);
-
- if (!m_disableLogs || !**m_disableLogs) {
- // log to a file
- m_logOfs << str << "\n";
- m_logOfs.flush();
- }
-
- // log it to the stdout too.
- if (!m_disableStdout) {
- std::println("{}", ((m_coloredLogs && !**m_coloredLogs) ? str : coloredStr));
- std::fflush(stdout);
- }
-}
diff --git a/src/debug/Log.hpp b/src/debug/Log.hpp
deleted file mode 100644
index c3146805..00000000
--- a/src/debug/Log.hpp
+++ /dev/null
@@ -1,75 +0,0 @@
-#pragma once
-#include <string>
-#include <format>
-#include <iostream>
-#include <fstream>
-#include <chrono>
-#include <mutex>
-
-#define LOGMESSAGESIZE 1024
-#define ROLLING_LOG_SIZE 4096
-
-enum eLogLevel : int8_t {
- NONE = -1,
- LOG = 0,
- WARN,
- ERR,
- CRIT,
- INFO,
- TRACE
-};
-
-// NOLINTNEXTLINE(readability-identifier-naming)
-namespace Debug {
- inline std::string m_logFile;
- inline std::ofstream m_logOfs;
- inline int64_t* const* m_disableLogs = nullptr;
- inline int64_t* const* m_disableTime = nullptr;
- inline bool m_disableStdout = false;
- inline bool m_trace = false;
- inline bool m_shuttingDown = false;
- inline int64_t* const* m_coloredLogs = nullptr;
-
- inline std::string m_rollingLog = ""; // rolling log contains the ROLLING_LOG_SIZE tail of the log
- inline std::mutex m_logMutex;
-
- void init(const std::string& IS);
- void close();
-
- //
- void log(eLogLevel level, std::string str);
-
- template <typename... Args>
- //NOLINTNEXTLINE
- void log(eLogLevel level, std::format_string<Args...> fmt, Args&&... args) {
- if (level == TRACE && !m_trace)
- return;
-
- if (m_shuttingDown)
- return;
-
- std::string logMsg = "";
-
- // print date and time to the ofs
- if (m_disableTime && !**m_disableTime) {
-#ifndef _LIBCPP_VERSION
- static auto current_zone = std::chrono::current_zone();
- const auto zt = std::chrono::zoned_time{current_zone, std::chrono::system_clock::now()};
- const auto hms = std::chrono::hh_mm_ss{zt.get_local_time() - std::chrono::floor<std::chrono::days>(zt.get_local_time())};
-#else
- // TODO: current clang 17 does not support `zoned_time`, remove this once clang 19 is ready
- const auto hms = std::chrono::hh_mm_ss{std::chrono::system_clock::now() - std::chrono::floor<std::chrono::days>(std::chrono::system_clock::now())};
-#endif
- logMsg += std::format("[{}] ", hms);
- }
-
- // no need for try {} catch {} because std::format_string<Args...> ensures that vformat never throw std::format_error
- // because
- // 1. any faulty format specifier that sucks will cause a compilation error.
- // 2. and `std::bad_alloc` is catastrophic, (Almost any operation in stdlib could throw this.)
- // 3. this is actually what std::format in stdlib does
- logMsg += std::vformat(fmt.get(), std::make_format_args(args...));
-
- log(level, logMsg);
- }
-};
diff --git a/src/debug/TracyDefines.hpp b/src/debug/TracyDefines.hpp
index 49d296f6..d06332f3 100644
--- a/src/debug/TracyDefines.hpp
+++ b/src/debug/TracyDefines.hpp
@@ -2,7 +2,7 @@
#ifdef USE_TRACY_GPU
-#include "Log.hpp"
+#include "log/Logger.hpp"
#include <GL/gl.h>
#include <GLES2/gl2ext.h>
diff --git a/src/debug/crash/CrashReporter.cpp b/src/debug/crash/CrashReporter.cpp
index 1b18fce4..fad6ad21 100644
--- a/src/debug/crash/CrashReporter.cpp
+++ b/src/debug/crash/CrashReporter.cpp
@@ -248,5 +248,5 @@ void CrashReporter::createAndSaveCrash(int sig) {
finalCrashReport += "\n\nLog tail:\n";
- finalCrashReport += std::string_view(Debug::m_rollingLog).substr(Debug::m_rollingLog.find('\n') + 1);
+ finalCrashReport += Log::logger->rolling();
}
diff --git a/src/debug/log/Logger.cpp b/src/debug/log/Logger.cpp
new file mode 100644
index 00000000..44b82a50
--- /dev/null
+++ b/src/debug/log/Logger.cpp
@@ -0,0 +1,64 @@
+#include "Logger.hpp"
+#include "RollingLogFollow.hpp"
+
+#include "../../defines.hpp"
+
+#include "../../managers/HookSystemManager.hpp"
+#include "../../config/ConfigValue.hpp"
+
+using namespace Log;
+
+CLogger::CLogger() {
+ const auto IS_TRACE = Env::isTrace();
+ m_logger.setLogLevel(IS_TRACE ? Hyprutils::CLI::LOG_TRACE : Hyprutils::CLI::LOG_DEBUG);
+}
+
+void CLogger::log(Hyprutils::CLI::eLogLevel level, const std::string_view& str) {
+
+ static bool TRACE = Env::isTrace();
+
+ if (!m_logsEnabled)
+ return;
+
+ if (level == Hyprutils::CLI::LOG_TRACE && !TRACE)
+ return;
+
+ if (SRollingLogFollow::get().isRunning())
+ SRollingLogFollow::get().addLog(str);
+
+ m_logger.log(level, str);
+}
+
+void CLogger::initIS(const std::string_view& IS) {
+ // NOLINTNEXTLINE
+ m_logger.setOutputFile(std::string{IS} + (ISDEBUG ? "/hyprlandd.log" : "/hyprland.log"));
+ m_logger.setEnableRolling(true);
+ m_logger.setEnableColor(false);
+ m_logger.setEnableStdout(true);
+ m_logger.setTime(false);
+}
+
+void CLogger::initCallbacks() {
+ static auto P = g_pHookSystem->hookDynamic("configReloaded", [this](void* hk, SCallbackInfo& info, std::any param) { recheckCfg(); });
+ recheckCfg();
+}
+
+void CLogger::recheckCfg() {
+ static auto PDISABLELOGS = CConfigValue<Hyprlang::INT>("debug:disable_logs");
+ static auto PDISABLETIME = CConfigValue<Hyprlang::INT>("debug:disable_time");
+ static auto PENABLESTDOUT = CConfigValue<Hyprlang::INT>("debug:enable_stdout_logs");
+ static auto PENABLECOLOR = CConfigValue<Hyprlang::INT>("debug:colored_stdout_logs");
+
+ m_logger.setEnableStdout(!*PDISABLELOGS && *PENABLESTDOUT);
+ m_logsEnabled = !*PDISABLELOGS;
+ m_logger.setTime(!*PDISABLETIME);
+ m_logger.setEnableColor(*PENABLECOLOR);
+}
+
+const std::string& CLogger::rolling() {
+ return m_logger.rollingLog();
+}
+
+Hyprutils::CLI::CLogger& CLogger::hu() {
+ return m_logger;
+}
diff --git a/src/debug/log/Logger.hpp b/src/debug/log/Logger.hpp
new file mode 100644
index 00000000..d4e868de
--- /dev/null
+++ b/src/debug/log/Logger.hpp
@@ -0,0 +1,61 @@
+#pragma once
+
+#include <hyprutils/cli/Logger.hpp>
+
+#include "../../helpers/memory/Memory.hpp"
+#include "../../helpers/env/Env.hpp"
+
+namespace Log {
+ class CLogger {
+ public:
+ CLogger();
+ ~CLogger() = default;
+
+ void initIS(const std::string_view& IS);
+ void initCallbacks();
+
+ void log(Hyprutils::CLI::eLogLevel level, const std::string_view& str);
+
+ template <typename... Args>
+ //NOLINTNEXTLINE
+ void log(Hyprutils::CLI::eLogLevel level, std::format_string<Args...> fmt, Args&&... args) {
+ static bool TRACE = Env::isTrace();
+
+ if (!m_logsEnabled)
+ return;
+
+ if (level == Hyprutils::CLI::LOG_TRACE && !TRACE)
+ return;
+
+ std::string logMsg = "";
+
+ // no need for try {} catch {} because std::format_string<Args...> ensures that vformat never throw std::format_error
+ // because
+ // 1. any faulty format specifier that sucks will cause a compilation error.
+ // 2. and `std::bad_alloc` is catastrophic, (Almost any operation in stdlib could throw this.)
+ // 3. this is actually what std::format in stdlib does
+ logMsg += std::vformat(fmt.get(), std::make_format_args(args...));
+
+ log(level, logMsg);
+ }
+
+ const std::string& rolling();
+ Hyprutils::CLI::CLogger& hu();
+
+ private:
+ void recheckCfg();
+
+ Hyprutils::CLI::CLogger m_logger;
+ bool m_logsEnabled = true;
+ };
+
+ inline UP<CLogger> logger = makeUnique<CLogger>();
+
+ //
+ inline constexpr const Hyprutils::CLI::eLogLevel DEBUG = Hyprutils::CLI::LOG_DEBUG;
+ inline constexpr const Hyprutils::CLI::eLogLevel WARN = Hyprutils::CLI::LOG_WARN;
+ inline constexpr const Hyprutils::CLI::eLogLevel ERR = Hyprutils::CLI::LOG_ERR;
+ inline constexpr const Hyprutils::CLI::eLogLevel CRIT = Hyprutils::CLI::LOG_CRIT;
+ inline constexpr const Hyprutils::CLI::eLogLevel INFO = Hyprutils::CLI::LOG_DEBUG;
+ inline constexpr const Hyprutils::CLI::eLogLevel TRACE = Hyprutils::CLI::LOG_TRACE;
+};
diff --git a/src/debug/RollingLogFollow.hpp b/src/debug/log/RollingLogFollow.hpp
index 07b4387d..c1cce9eb 100644
--- a/src/debug/RollingLogFollow.hpp
+++ b/src/debug/log/RollingLogFollow.hpp
@@ -1,9 +1,11 @@
#pragma once
#include <shared_mutex>
+#include <unordered_map>
+#include <format>
+#include <vector>
-// NOLINTNEXTLINE(readability-identifier-naming)
-namespace Debug {
+namespace Log {
struct SRollingLogFollow {
std::unordered_map<int, std::string> m_socketToRollingLogFollowQueue;
std::shared_mutex m_mutex;
@@ -30,12 +32,14 @@ namespace Debug {
return ret;
};
- void addLog(const std::string& log) {
+ void addLog(const std::string_view& log) {
std::unique_lock<std::shared_mutex> w(m_mutex);
m_running = true;
std::vector<int> to_erase;
- for (const auto& p : m_socketToRollingLogFollowQueue)
- m_socketToRollingLogFollowQueue[p.first] += log + "\n";
+ for (const auto& p : m_socketToRollingLogFollowQueue) {
+ m_socketToRollingLogFollowQueue[p.first] += log;
+ m_socketToRollingLogFollowQueue[p.first] += "\n";
+ }
}
bool isRunning() {