147enum class Level :
int
159namespace fs = std::filesystem;
164 std::ofstream m_sink;
175 [[nodiscard]] pid_t
get_pid()
const;
200static void fork_handler_parent()
220 logger.set_sink_file(
"/dev/null");
228 : m_sink(
"/dev/null")
229 , m_level(Level::CRITICAL)
232 static thread_local bool registered =
false;
248 if (
const char* var = std::getenv(
"FIM_DEBUG"); var && std::string_view{var} ==
"1" )
250 if(path_file_sink !=
"/dev/null")
252 std::println(
"D::Logger file: {}", path_file_sink.string());
256 m_sink = std::ofstream(path_file_sink, std::ios::out | std::ios::trunc);
258 if(not m_sink.is_open())
260 std::println(
"E::Could not open file '{}'", path_file_sink.string());
279 if (
auto& file = this->m_sink)
351 return logger.get_level();
361 logger.set_sink_file(path_file_sink);
413 consteval Location(
const char* str_file = __builtin_FILE() , uint32_t str_line = __builtin_LINE())
425 constexpr auto get()
const
439template<
typename... Ts>
440std::string
vformat(std::string_view fmt, Ts&&... ts)
442 return std::vformat(fmt, std::make_format_args(ts...));
456 std::string m_prefix;
457 std::reference_wrapper<std::ostream> ostream;
468 Writer(
Location const& location, Level
const& level, std::string prefix, std::ostream& ostream)
487 pid_t pid = getpid();
491 line += (pid ==
logger.get_pid())? std::format(
"{}::{}::", m_prefix, m_loc.get())
492 : std::format(
"{}::{}::", m_prefix, pid);
496 | std::views::filter([](
char c){
return c !=
'\n'; })
498 | std::ranges::to<std::string>();
502 if(std::ofstream& sink =
logger.get_sink_file(); sink.is_open())
507 if(
logger.get_level() >= m_level)
509 ostream.get() << line;
531 :
Writer(location, Level::DEBUG,
"D", std::cout)
552 :
Writer(location, Level::INFO,
"I", std::cout)
573 :
Writer(location, Level::WARN,
"W", std::cerr)
594 :
Writer(location, Level::ERROR,
"E", std::cerr)
615 :
Writer(location, Level::CRITICAL,
"C", std::cerr)
682#define logger(fmt, ...) ::ns_log::impl_log<fmt>(::ns_log::Location{})(__VA_ARGS__)
727#define logger_loc(loc, fmt, ...) ::ns_log::impl_log<fmt>(loc)(__VA_ARGS__)
736template<ns_
string::static_
string str>
739 return [=]<
typename... Ts>(Ts&&... ts)
741 constexpr std::string_view sv = str.data;
742 if constexpr (sv.starts_with(
"I::"))
744 info{loc}(sv.substr(3), std::forward<Ts>(ts)...);
746 else if constexpr (sv.starts_with(
"W::"))
748 warn{loc}(sv.substr(3), std::forward<Ts>(ts)...);
750 else if constexpr (sv.starts_with(
"E::"))
752 error{loc}(sv.substr(3), std::forward<Ts>(ts)...);
754 else if constexpr (sv.starts_with(
"C::"))
756 critical{loc}(sv.substr(3), std::forward<Ts>(ts)...);
758 else if constexpr (sv.starts_with(
"Q::"))
765 static_assert(sv.starts_with(
"D::")
766 or sv.starts_with(
"I::")
767 or sv.starts_with(
"W::")
768 or sv.starts_with(
"E::")
769 or sv.starts_with(
"C::")
770 or sv.starts_with(
"Q::")
void operator()(T &&format, Args &&... args)
Writes a formatted log message.
Writer(Location const &location, Level const &level, std::string prefix, std::ostream &ostream)
Constructs a Writer with location and level information.
std::ofstream & get_sink_file()
Gets the sink file of the logger.
Logger()
Construct a new Logger:: Logger object.
Level get_level() const
Get current verbosity level of the logger.
void set_as_fork()
Marks the logger as being in a forked child process.
pid_t get_pid() const
Get the PID that was active when this logger was initialized.
void set_level(Level level)
Sets the logging verbosity (CRITICAL,ERROR,INFO,DEBUG)
void set_sink_file(fs::path const &path_file_sink)
Sets the sink file of the logger.
void flush()
Flushes the buffer content to the log file if it is defined.
Critical-level logger (highest priority, always shown)
critical(Location location=Location())
Constructs a critical logger.
Debug-level logger (lowest priority)
debug(Location location=Location())
Constructs a debug logger.
Error-level logger (recoverable errors)
error(Location location=Location())
Constructs an error logger.
Info-level logger (informational messages)
info(Location location=Location())
Constructs an info logger.
Warning-level logger (potential issues)
warn(Location location=Location())
Constructs a warning logger.
Custom C++ concepts for type constraints and compile-time validation.
Concept for iterable containers (has begin() and end())
Concept for types that can be represented as a string.
#define logger(fmt,...)
Compile-time log level dispatch macro with automatic location capture.
void fork_handler_child()
Fork handler that resets the logger in child processes.
thread_local Logger logger
Thread-local logger instance.
Multi-level logging system with file and stdout sinks.
constexpr decltype(auto) impl_log(Location loc)
Implementation function for compile-time log level dispatch.
void set_as_fork()
Marks the logger as being in a forked child process.
std::string vformat(std::string_view fmt, Ts &&... ts)
Workaround make_format_args only taking references.
void set_level(Level level)
Sets the logging verbosity (CRITICAL,ERROR,INFO,DEBUG)
Level get_level()
Get current verbosity level of the logger.
void set_sink_file(fs::path const &path_file_sink)
Sets the sink file of the logger.
std::string to_string(T &&t) noexcept
Converts a type to a string.
Source code location information for log messages.
consteval Location(const char *str_file=__builtin_FILE(), uint32_t str_line=__builtin_LINE())
Constructs a Location with automatic file/line capture.
std::string_view m_str_file
Source file name (basename only)
constexpr auto get() const
Formats location as "filename::line".
uint32_t m_line
Source line number.