VaneDB 0.1.0
Embeddable vector database for edge AI
Loading...
Searching...
No Matches
logging.h
Go to the documentation of this file.
1#pragma once
2
21#include <chrono>
22#include <cstdio>
23#include <cstring>
24#include <iomanip>
25#include <mutex>
26#include <sstream>
27#include <string>
28
29namespace vanedb {
30namespace logging {
31
35enum class Level {
36 TRACE = 0,
37 DEBUG = 1,
38 INFO = 2,
39 WARN = 3,
40 ERROR = 4,
41 OFF = 5
42};
43
47inline const char* level_to_string(Level level) {
48 switch (level) {
49 case Level::TRACE: return "TRACE";
50 case Level::DEBUG: return "DEBUG";
51 case Level::INFO: return "INFO";
52 case Level::WARN: return "WARN";
53 case Level::ERROR: return "ERROR";
54 default: return "UNKNOWN";
55 }
56}
57
62 static Level level =
63#if defined(VANEDB_LOG_LEVEL_TRACE)
65#elif defined(VANEDB_LOG_LEVEL_DEBUG)
67#elif defined(VANEDB_LOG_LEVEL_WARN)
69#elif defined(VANEDB_LOG_LEVEL_ERROR)
71#else
73#endif
74 return level;
75}
76
80inline void set_level(Level level) {
81 global_level() = level;
82}
83
87inline Level get_level() {
88 return global_level();
89}
90
94inline std::mutex& log_mutex() {
95 static std::mutex mtx;
96 return mtx;
97}
98
102template <typename T>
103inline void format_kv(std::ostringstream& ss, const char* key, const T& value) {
104 ss << " " << key << "=" << value;
105}
106
110inline void format_kvs(std::ostringstream&) {}
111
115template <typename V, typename... Args>
116inline void format_kvs(std::ostringstream& ss, const char* key, const V& value, Args&&... args) {
117 format_kv(ss, key, value);
118 format_kvs(ss, std::forward<Args>(args)...);
119}
120
124template <typename... Args>
125inline void log(Level level, const char* file, int line, const char* message, Args&&... args) {
126#ifdef VANEDB_ENABLE_LOGGING
127 if (level < global_level()) {
128 return;
129 }
130
131 // Get timestamp
132 auto now = std::chrono::system_clock::now();
133 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(
134 now.time_since_epoch()) % 1000;
135 auto time = std::chrono::system_clock::to_time_t(now);
136 std::tm tm_buf;
137#ifdef _WIN32
138 localtime_s(&tm_buf, &time);
139#else
140 localtime_r(&time, &tm_buf);
141#endif
142
143 // Extract filename from path
144 const char* filename = std::strrchr(file, '/');
145 if (!filename) filename = std::strrchr(file, '\\');
146 filename = filename ? filename + 1 : file;
147
148 // Build structured log message
149 std::ostringstream ss;
150 ss << std::put_time(&tm_buf, "%Y-%m-%d %H:%M:%S") << "."
151 << std::setfill('0') << std::setw(3) << ms.count()
152 << " [" << level_to_string(level) << "] "
153 << filename << ":" << line << " "
154 << message;
155 format_kvs(ss, std::forward<Args>(args)...);
156 ss << "\n";
157
158 // Thread-safe output
159 {
160 std::lock_guard<std::mutex> lock(log_mutex());
161 std::fputs(ss.str().c_str(), stderr);
162 }
163#else
164 (void)level;
165 (void)file;
166 (void)line;
167 (void)message;
168 // Suppress unused warnings for args in disabled logging
169 (void)std::initializer_list<int>{(static_cast<void>(args), 0)...};
170#endif
171}
172
173} // namespace logging
174} // namespace vanedb
175
176// Convenience macros
177#define VANEDB_LOG(level, msg, ...) \
178 ::vanedb::logging::log(level, __FILE__, __LINE__, msg, ##__VA_ARGS__)
179
180#define VANEDB_LOG_TRACE(msg, ...) \
181 VANEDB_LOG(::vanedb::logging::Level::TRACE, msg, ##__VA_ARGS__)
182
183#define VANEDB_LOG_DEBUG(msg, ...) \
184 VANEDB_LOG(::vanedb::logging::Level::DEBUG, msg, ##__VA_ARGS__)
185
186#define VANEDB_LOG_INFO(msg, ...) \
187 VANEDB_LOG(::vanedb::logging::Level::INFO, msg, ##__VA_ARGS__)
188
189#define VANEDB_LOG_WARN(msg, ...) \
190 VANEDB_LOG(::vanedb::logging::Level::WARN, msg, ##__VA_ARGS__)
191
192#define VANEDB_LOG_ERROR(msg, ...) \
193 VANEDB_LOG(::vanedb::logging::Level::ERROR, msg, ##__VA_ARGS__)
void format_kv(std::ostringstream &ss, const char *key, const T &value)
Format a single key-value pair.
Definition logging.h:103
std::mutex & log_mutex()
Mutex for thread-safe logging.
Definition logging.h:94
Level get_level()
Get the global log level.
Definition logging.h:87
void log(Level level, const char *file, int line, const char *message, Args &&... args)
Core logging function.
Definition logging.h:125
void format_kvs(std::ostringstream &)
Format key-value pairs (base case).
Definition logging.h:110
void set_level(Level level)
Set the global log level.
Definition logging.h:80
Level & global_level()
Global log level (can be changed at runtime).
Definition logging.h:61
const char * level_to_string(Level level)
Convert log level to string.
Definition logging.h:47
Level
Log level enumeration.
Definition logging.h:35