2022-03-16 20:50:55 +01:00
|
|
|
#pragma once
|
|
|
|
#include <string>
|
2023-09-06 12:51:36 +02:00
|
|
|
#include <format>
|
|
|
|
#include <iostream>
|
|
|
|
#include <fstream>
|
|
|
|
#include <chrono>
|
2024-07-31 21:00:14 +02:00
|
|
|
#include <mutex>
|
2023-10-16 18:39:12 +02:00
|
|
|
#include "../includes.hpp"
|
2023-09-06 12:51:36 +02:00
|
|
|
#include "../helpers/MiscFunctions.hpp"
|
2022-03-16 20:50:55 +01:00
|
|
|
|
2023-11-14 21:06:04 +01:00
|
|
|
#define LOGMESSAGESIZE 1024
|
|
|
|
#define ROLLING_LOG_SIZE 4096
|
2022-03-16 20:50:55 +01:00
|
|
|
|
2023-12-06 23:54:56 +01:00
|
|
|
enum LogLevel {
|
2022-03-16 20:50:55 +01:00
|
|
|
NONE = -1,
|
2022-12-16 18:17:31 +01:00
|
|
|
LOG = 0,
|
2022-03-16 20:50:55 +01:00
|
|
|
WARN,
|
|
|
|
ERR,
|
2022-06-25 20:50:29 +02:00
|
|
|
CRIT,
|
2023-08-21 19:36:09 +02:00
|
|
|
INFO,
|
|
|
|
TRACE
|
2022-03-16 20:50:55 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
namespace Debug {
|
2024-02-18 16:00:34 +01:00
|
|
|
inline std::string logFile;
|
2024-07-31 21:00:14 +02:00
|
|
|
inline std::ofstream logOfs;
|
2024-02-18 16:00:34 +01:00
|
|
|
inline int64_t* const* disableLogs = nullptr;
|
|
|
|
inline int64_t* const* disableTime = nullptr;
|
|
|
|
inline bool disableStdout = false;
|
|
|
|
inline bool trace = false;
|
|
|
|
inline bool shuttingDown = false;
|
2024-04-29 17:07:35 +02:00
|
|
|
inline int64_t* const* coloredLogs = nullptr;
|
2023-09-06 12:51:36 +02:00
|
|
|
|
2024-02-18 16:00:34 +01:00
|
|
|
inline std::string rollingLog = ""; // rolling log contains the ROLLING_LOG_SIZE tail of the log
|
2024-07-31 21:00:14 +02:00
|
|
|
inline std::mutex logMutex;
|
2023-11-14 21:06:04 +01:00
|
|
|
|
2024-02-18 16:00:34 +01:00
|
|
|
void init(const std::string& IS);
|
2024-07-31 21:00:14 +02:00
|
|
|
void close();
|
2024-04-22 19:44:25 +02:00
|
|
|
|
|
|
|
//
|
|
|
|
void log(LogLevel level, std::string str);
|
|
|
|
|
2023-09-06 12:51:36 +02:00
|
|
|
template <typename... Args>
|
2023-09-20 09:26:20 +02:00
|
|
|
void log(LogLevel level, std::format_string<Args...> fmt, Args&&... args) {
|
2024-07-31 21:00:14 +02:00
|
|
|
std::lock_guard<std::mutex> guard(logMutex);
|
|
|
|
|
2023-09-06 12:51:36 +02:00
|
|
|
if (level == TRACE && !trace)
|
|
|
|
return;
|
2023-12-06 15:46:18 +01:00
|
|
|
|
|
|
|
if (shuttingDown)
|
|
|
|
return;
|
2023-09-06 12:51:36 +02:00
|
|
|
|
|
|
|
std::string logMsg = "";
|
|
|
|
|
|
|
|
// print date and time to the ofs
|
2024-02-18 16:00:34 +01:00
|
|
|
if (disableTime && !**disableTime) {
|
2023-09-06 12:51:36 +02:00
|
|
|
#ifndef _LIBCPP_VERSION
|
2024-06-05 18:30:46 +02:00
|
|
|
const auto zt = std::chrono::zoned_time{std::chrono::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())};
|
2023-09-06 12:51:36 +02:00
|
|
|
#else
|
2024-06-05 18:30:46 +02:00
|
|
|
// 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())};
|
2023-09-06 12:51:36 +02:00
|
|
|
#endif
|
2024-06-05 18:30:46 +02:00
|
|
|
logMsg += std::format("[{}] ", hms);
|
2023-09-06 12:51:36 +02:00
|
|
|
}
|
|
|
|
|
2023-09-20 09:26:20 +02:00
|
|
|
// 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...));
|
2023-09-06 12:51:36 +02:00
|
|
|
|
2024-04-22 19:44:25 +02:00
|
|
|
log(level, logMsg);
|
2023-09-06 12:51:36 +02:00
|
|
|
}
|
2023-10-16 18:39:12 +02:00
|
|
|
};
|