Files
linuxSmartie/include/log.hpp
2025-12-22 14:06:40 +01:00

92 lines
2.6 KiB
C++

#ifndef LOG_HPP
#define LOG_HPP
#define log(level, fmt, ...) _log(level, std::source_location::current(), fmt, ##__VA_ARGS__) // comment to disable logging
// #define LOG_FILE_LOCATION "linuxSmartie.log.gz"
#ifdef log
#include <chrono>
#include <mutex>
#include <print>
#include <source_location>
#include <string_view>
#ifdef LOG_FILE_LOCATION
#include <zlib.h>
inline std::mutex fmtx; // file logging mutex
#endif
// #define FUNC_NAME pFname(std::source_location::current().function_name())
inline std::mutex cmtx; // console logging mutex
enum class LOG { INF, WRN, ERR, DBG, START };
inline std::string_view pFname(std::string_view full) {
if (auto pos = full.find(' '); pos != std::string_view::npos)
full.remove_prefix(pos + 1);
if (auto pos = full.rfind('('); pos != std::string_view::npos)
full.remove_suffix(full.size() - pos);
return full;
}
template <typename... Args>
inline void _log(LOG level, const std::source_location& loc, std::format_string<Args...> str, Args&&... args) {
constexpr std::string_view reset = "\033[0m";
constexpr std::string_view pattern = "[{}{}{}] ";
std::string_view tag = pFname(loc.function_name());
std::string_view color = "";
switch (level) {
case LOG::INF:
color = "\033[1;32m";
break; // bold; green
case LOG::WRN:
color = "\033[1;33m"; // bold; yellow
break;
case LOG::ERR:
color = "\033[1;31m"; // bold; red
break;
case LOG::DBG:
break;
case LOG::START:
color = "\033[1;3;5;36m"; // bold; italics; blinking; cyan
break;
}
/* log to console */
{
std::scoped_lock lock(cmtx);
std::print(pattern, color, tag, reset);
std::println(str, std::forward<Args>(args)...);
}
#ifdef LOG_FILE_LOCATION
/* log to file */
{
auto now = std::chrono::system_clock::now();
auto local = std::chrono::current_zone()->to_local(now);
std::string msg = std::format("{:%x %H:%M:%S }", floor<std::chrono::milliseconds>(local)); // timestamp
std::format_to(std::back_inserter(msg), pattern, color, tag, reset); // tag
std::format_to(std::back_inserter(msg), str, std::forward<Args>(args)...); // actual log message
std::scoped_lock lock(fmtx);
gzFile file = gzopen(LOG_FILE_LOCATION, "ab");
if (file) {
gzprintf(file, "%s\n", msg.c_str());
gzclose(file);
}
}
#endif
}
#else
#define log(...)
#endif
#endif