debug: move to hyprutils' logger (#12673)
This commit is contained in:
parent
f88deb928a
commit
6175ecd4c4
147 changed files with 1696 additions and 1709 deletions
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
};
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#ifdef USE_TRACY_GPU
|
||||
|
||||
#include "Log.hpp"
|
||||
#include "log/Logger.hpp"
|
||||
|
||||
#include <GL/gl.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
64
src/debug/log/Logger.cpp
Normal file
64
src/debug/log/Logger.cpp
Normal file
|
|
@ -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;
|
||||
}
|
||||
61
src/debug/log/Logger.hpp
Normal file
61
src/debug/log/Logger.hpp
Normal file
|
|
@ -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;
|
||||
};
|
||||
|
|
@ -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() {
|
||||
Loading…
Add table
Add a link
Reference in a new issue