libmemalloc  v4.0.00
Modern Memory Allocator
Loading...
Searching...
No Matches
logs.h
Go to the documentation of this file.
1
19#pragma once
20
21/* < C++ Compatibility > */
22#ifdef __cplusplus
23extern "C"
24{
25#endif
26
31/*< Dependencies >*/
32#include <errno.h>
33#include <pthread.h>
34#include <stdarg.h>
35#include <stdint.h>
36#include <stdio.h>
37#include <stdlib.h>
38#include <string.h>
39#include <time.h>
40#include <unistd.h>
41
59typedef enum LogLevel
61 LOG_LEVEL_NONE = (uint8_t)(0u),
62 LOG_LEVEL_ERROR = (uint8_t)(1u),
63 LOG_LEVEL_WARNING = (uint8_t)(2u),
64 LOG_LEVEL_INFO = (uint8_t)(3u),
65 LOG_LEVEL_DEBUG = (uint8_t)(4u)
67
76#ifndef LOG_LEVEL
77 #define LOG_LEVEL LOG_LEVEL_DEBUG
78#endif
79
85#ifndef _POSIX_C_SOURCE
86 #define _POSIX_C_SOURCE 200809UL
87#endif
88
93#if defined(__GNUC__)
94 #define LOG_PRINTF(file, format, ...) \
95 __builtin_fprintf((FILE *)(file), (format), ##__VA_ARGS__)
96#else
97 #define LOG_PRINTF(file, ...) fprintf(file, __VA_ARGS__)
98#endif
99
104#if defined(__GNUC__)
105 #define LOG_VPRINTF(file, format, args) \
106 __builtin_vfprintf((FILE *)(file), (format), (args))
107#else
108 #define LOG_VPRINTF(file, fmt, args) vfprintf(file, fmt, args)
109#endif
110
115#define PREFIX_ERROR "[ERROR]"
116#define PREFIX_WARNING "[WARNING]"
117#define PREFIX_INFO "[INFO]"
118#define PREFIX_DEBUG "[DEBUG]"
119
125#define COLOR_RED "\033[0;31m"
126#define COLOR_YELLOW "\033[0;33m"
127#define COLOR_BLUE "\033[0;34m"
128#define COLOR_GREEN "\033[0;32m"
129#define COLOR_RESET "\033[0m"
130
136#ifndef ATTR_PRINTF
137 #define ATTR_PRINTF(fmt_idx, var_idx) \
138 __attribute__((format(printf, fmt_idx, var_idx)))
139#endif
140
177static inline int LOG_output(log_level_t level,
178 const char *color,
179 const char *prefix,
180 const char *file,
181 const char *func,
182 int line,
183 const char *fmt,
184 ...) ATTR_PRINTF(7, 8);
185
218static inline int LOG_output(log_level_t level,
219 const char *color,
220 const char *prefix,
221 const char *file,
222 const char *func,
223 int line,
224 const char *fmt,
225 ...)
226{
227 int ret = EXIT_SUCCESS;
228
229 FILE *out = (FILE *)NULL;
230
231 static pthread_mutex_t log_mutex = PTHREAD_MUTEX_INITIALIZER;
232
233 struct timespec ts;
234 struct tm *ptm = (struct tm *)NULL;
235
236 time_t now = 0;
237
238 long msec = 0u;
239
240 if (level > LOG_LEVEL)
241 {
242 ret = -EIO;
243 goto function_output;
244 }
245
246 pthread_mutex_lock(&log_mutex);
247
248 memset(&ts, 0, sizeof(ts));
249
250 clock_gettime(CLOCK_REALTIME, &ts);
251
252 now = ts.tv_sec;
253 ptm = localtime(&now);
254
255 out = (level <= LOG_LEVEL_WARNING) ? stderr : stdout;
256 msec = ts.tv_nsec / 1000000L;
257
258 LOG_PRINTF(out,
259 "[%02d:%02d:%02d.%03ld] ",
260 ptm->tm_hour,
261 ptm->tm_min,
262 ptm->tm_sec,
263 msec);
264
265 if (isatty(fileno(out)))
266 LOG_PRINTF(out, "%s%s%s ", color, prefix, COLOR_RESET);
267 else
268 LOG_PRINTF(out, "%s ", prefix);
269
270 va_list args;
271 va_start(args, fmt);
272 LOG_VPRINTF(out, fmt, args);
273 va_end(args);
274
275 LOG_PRINTF(out, " (at %s:%d:%s())\n", file, line, func);
276 pthread_mutex_unlock(&log_mutex);
277
278function_output:
279 return ret;
280}
281
286#define LOG_ERROR(fmt, ...) \
287 LOG_output(LOG_LEVEL_ERROR, \
288 COLOR_RED, \
289 PREFIX_ERROR, \
290 __FILE__, \
291 __func__, \
292 __LINE__, \
293 fmt, \
294 ##__VA_ARGS__)
295
300#define LOG_WARNING(fmt, ...) \
301 LOG_output(LOG_LEVEL_WARNING, \
302 COLOR_YELLOW, \
303 PREFIX_WARNING, \
304 __FILE__, \
305 __func__, \
306 __LINE__, \
307 fmt, \
308 ##__VA_ARGS__)
309
314#define LOG_INFO(fmt, ...) \
315 LOG_output(LOG_LEVEL_INFO, \
316 COLOR_BLUE, \
317 PREFIX_INFO, \
318 __FILE__, \
319 __func__, \
320 __LINE__, \
321 fmt, \
322 ##__VA_ARGS__)
323
328#define LOG_DEBUG(fmt, ...) \
329 LOG_output(LOG_LEVEL_DEBUG, \
330 COLOR_GREEN, \
331 PREFIX_DEBUG, \
332 __FILE__, \
333 __func__, \
334 __LINE__, \
335 fmt, \
336 ##__VA_ARGS__)
337
338/* < C++ Compatibility End > */
339#ifdef __cplusplus
340}
341#endif
342
344/* < End of header file > */
#define LOG_LEVEL
Default log level if not defined.
Definition logs.h:74
static int LOG_output(log_level_t level, const char *color, const char *prefix, const char *file, const char *func, int line, const char *fmt,...) __attribute__((format(printf
Internal logging implementation: thread‐safe, prints timestamp, optional ANSI color,...
Definition logs.h:214
#define COLOR_RESET
Definition logs.h:126
#define LOG_VPRINTF(file, fmt, args)
Compiler-specific vprintf abstraction.
Definition logs.h:105
#define ATTR_PRINTF(fmt_idx, var_idx)
Macro to apply GCC printf-style format checking on custom functions.
Definition logs.h:134
log_level_t
Defines log levels for the logging system.
Definition logs.h:58
#define LOG_PRINTF(file,...)
Compiler-specific printf abstraction.
Definition logs.h:94
@ LOG_LEVEL_DEBUG
Definition logs.h:63
@ LOG_LEVEL_ERROR
Definition logs.h:60
@ LOG_LEVEL_WARNING
Definition logs.h:61
@ LOG_LEVEL_NONE
Definition logs.h:59
@ LOG_LEVEL_INFO
Definition logs.h:62