libstp
Robotics library for Botball
Loading...
Searching...
No Matches
logging.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <string>
4#include <string_view>
5#include <tuple>
6#include <utility>
7
8#include <spdlog/fmt/bundled/format.h>
9
10// Compile-time level values for the custom macros.
11#define LIBSTP_LOG_LEVEL_TRACE 0
12#define LIBSTP_LOG_LEVEL_DEBUG 1
13#define LIBSTP_LOG_LEVEL_INFO 2
14#define LIBSTP_LOG_LEVEL_WARN 3
15#define LIBSTP_LOG_LEVEL_ERROR 4
16#define LIBSTP_LOG_LEVEL_CRITICAL 5
17#define LIBSTP_LOG_LEVEL_OFF 6
18
19// Compile-time floor for the LIBSTP_LOG_* macros. DEBUG by default so C++ debug
20// statements are compiled in and can reach the per-run log file; TRACE stays
21// behind the LIBSTP_TRACE_LOGGING build flag (see CMakeLists.txt) to avoid the
22// cost of the highest-rate trace sites in normal builds.
23#ifndef FOUNDATION_LOG_ACTIVE_LEVEL
24#define FOUNDATION_LOG_ACTIVE_LEVEL LIBSTP_LOG_LEVEL_DEBUG
25#endif
26
27namespace spdlog { class logger; }
28
29namespace logging {
30
41
42 namespace detail {
43 constexpr int level_value(Level level) {
44 return static_cast<int>(level);
45 }
46
47 // Extract basename from full path (e.g., "/path/to/file.cpp" -> "file.cpp")
48 constexpr const char* basename(const char* path) {
49 const char* file = path;
50 while (*path) {
51 if (*path == '/' || *path == '\\') {
52 file = path + 1;
53 }
54 ++path;
55 }
56 return file;
57 }
58 }
59
62
64 void init();
65
70 bool is_enabled(Level level);
71
73 void log(Level level, std::string_view message);
74
77 void log(Level level, const char* source_file, int line, const char* func,
78 std::string_view message);
79
80 // Format-aware logging helper that keeps formatting outside of the logging backend.
81 template <typename... Args>
82 inline void logf(Level level, std::string_view fmt_str, Args&&... args) {
83 if (!is_enabled(level)) {
84 return;
85 }
86 if constexpr (sizeof...(Args) == 0) {
87 log(level, fmt_str);
88 } else {
89 auto args_tuple = std::make_tuple(std::forward<Args>(args)...);
90 auto message = std::apply(
91 [&](auto&... unpacked) {
92 return fmt::vformat(fmt::string_view(fmt_str.data(), fmt_str.size()),
93 fmt::make_format_args(unpacked...));
94 },
95 args_tuple);
96 log(level, message);
97 }
98 }
99
100 // Format-aware logging helper that annotates the originating source location.
101 template <typename... Args>
102 inline void logf_loc(Level level, const char* file, int line, const char* func,
103 std::string_view fmt_str, Args&&... args) {
104 if (!is_enabled(level)) {
105 return;
106 }
107 if constexpr (sizeof...(Args) == 0) {
108 log(level, file, line, func, fmt_str);
109 } else {
110 auto args_tuple = std::make_tuple(std::forward<Args>(args)...);
111 auto message = std::apply(
112 [&](auto&... unpacked) {
113 return fmt::vformat(fmt::string_view(fmt_str.data(), fmt_str.size()),
114 fmt::make_format_args(unpacked...));
115 },
116 args_tuple);
117 log(level, file, line, func, message);
118 }
119 }
120
124 void shutdown();
125
127 std::shared_ptr<spdlog::logger> core();
128}
129
130#define LIBSTP_LOG_CALL(level_enum, fmt, ...) \
131 do { \
132 if constexpr (::logging::detail::level_value(level_enum) >= FOUNDATION_LOG_ACTIVE_LEVEL) { \
133 ::logging::logf_loc(level_enum, __FILE__, __LINE__, \
134 static_cast<const char*>(__FUNCTION__), \
135 fmt __VA_OPT__(, __VA_ARGS__)); \
136 } \
137 } while (0)
138
139#define LIBSTP_LOG_TRACE(fmt, ...) LIBSTP_LOG_CALL(::logging::Level::trace, fmt __VA_OPT__(, __VA_ARGS__))
140#define LIBSTP_LOG_DEBUG(fmt, ...) LIBSTP_LOG_CALL(::logging::Level::debug, fmt __VA_OPT__(, __VA_ARGS__))
141#define LIBSTP_LOG_INFO(fmt, ...) LIBSTP_LOG_CALL(::logging::Level::info, fmt __VA_OPT__(, __VA_ARGS__))
142#define LIBSTP_LOG_WARN(fmt, ...) LIBSTP_LOG_CALL(::logging::Level::warn, fmt __VA_OPT__(, __VA_ARGS__))
143#define LIBSTP_LOG_ERROR(fmt, ...) LIBSTP_LOG_CALL(::logging::Level::error, fmt __VA_OPT__(, __VA_ARGS__))
144#define LIBSTP_LOG_CRITICAL(fmt, ...) LIBSTP_LOG_CALL(::logging::Level::critical, fmt __VA_OPT__(, __VA_ARGS__))
#define LIBSTP_LOG_LEVEL_TRACE
Definition logging.hpp:11
#define LIBSTP_LOG_LEVEL_ERROR
Definition logging.hpp:15
#define LIBSTP_LOG_LEVEL_DEBUG
Definition logging.hpp:12
#define LIBSTP_LOG_LEVEL_OFF
Definition logging.hpp:17
#define LIBSTP_LOG_LEVEL_INFO
Definition logging.hpp:13
#define LIBSTP_LOG_LEVEL_CRITICAL
Definition logging.hpp:16
#define LIBSTP_LOG_LEVEL_WARN
Definition logging.hpp:14
constexpr const char * basename(const char *path)
Definition logging.hpp:48
constexpr int level_value(Level level)
Definition logging.hpp:43
void initialize_timer()
Reset the relative elapsed-time clock used by the log formatter.
void init()
Initialize the shared logger, sinks, and formatter. Safe to call more than once.
void logf_loc(Level level, const char *file, int line, const char *func, std::string_view fmt_str, Args &&... args)
Definition logging.hpp:102
void log(Level level, std::string_view message)
Log a preformatted message without source-location context.
Level
Runtime severity used by the foundation logger and its Python bindings.
Definition logging.hpp:32
void shutdown()
void logf(Level level, std::string_view fmt_str, Args &&... args)
Definition logging.hpp:82
std::shared_ptr< spdlog::logger > core()
Access the shared spdlog logger after initialization.
bool is_enabled(Level level)