1 /* SPDX-License-Identifier: GPL-3.0-or-later 2 * Copyright © 2016-2018 The TokTok team. 3 * Copyright © 2013 Tox project. 4 */ 5 6 /* 7 * Logger abstraction backed by callbacks for writing. 8 */ 9 #ifndef C_TOXCORE_TOXCORE_LOGGER_H 10 #define C_TOXCORE_TOXCORE_LOGGER_H 11 12 #include <stdint.h> 13 14 #include "ccompat.h" 15 16 #ifndef MIN_LOGGER_LEVEL 17 #define MIN_LOGGER_LEVEL LOGGER_LEVEL_INFO 18 #endif 19 20 // NOTE: Don't forget to update build system files after modifying the enum. 21 typedef enum Logger_Level { 22 LOGGER_LEVEL_TRACE, 23 LOGGER_LEVEL_DEBUG, 24 LOGGER_LEVEL_INFO, 25 LOGGER_LEVEL_WARNING, 26 LOGGER_LEVEL_ERROR, 27 } Logger_Level; 28 29 typedef struct Logger Logger; 30 31 typedef void logger_cb(void *context, Logger_Level level, const char *file, int line, 32 const char *func, const char *message, void *userdata); 33 34 /** 35 * Creates a new logger with logging disabled (callback is NULL) by default. 36 */ 37 Logger *logger_new(void); 38 39 /** 40 * Frees all resources associated with the logger. 41 */ 42 void logger_kill(Logger *log); 43 44 /** 45 * Sets the logger callback. Disables logging if set to NULL. 46 * The context parameter is passed to the callback as first argument. 47 */ 48 void logger_callback_log(Logger *log, logger_cb *function, void *context, void *userdata); 49 50 /** 51 * Main write function. If logging is disabled, this does nothing. 52 * 53 * If the logger is NULL, this writes to stderr. This behaviour should not be 54 * used in production code, but can be useful for temporarily debugging a 55 * function that does not have a logger available. It's essentially 56 * fprintf(stderr, ...), but with timestamps and source location. Toxcore must 57 * be built with -DUSE_STDERR_LOGGER for this to work. It will cause an 58 * assertion failure otherwise. 59 */ 60 void logger_write( 61 const Logger *log, Logger_Level level, const char *file, int line, const char *func, 62 const char *format, ...) GNU_PRINTF(6, 7); 63 64 65 #define LOGGER_WRITE(log, level, ...) \ 66 do { \ 67 if (level >= MIN_LOGGER_LEVEL) { \ 68 logger_write(log, level, __FILE__, __LINE__, __func__, __VA_ARGS__); \ 69 } \ 70 } while (0) 71 72 /* To log with an logger */ 73 #define LOGGER_TRACE(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_TRACE , __VA_ARGS__) 74 #define LOGGER_DEBUG(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_DEBUG , __VA_ARGS__) 75 #define LOGGER_INFO(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_INFO , __VA_ARGS__) 76 #define LOGGER_WARNING(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_WARNING, __VA_ARGS__) 77 #define LOGGER_ERROR(log, ...) LOGGER_WRITE(log, LOGGER_LEVEL_ERROR , __VA_ARGS__) 78 79 #define LOGGER_FATAL(log, ...) \ 80 do { \ 81 LOGGER_ERROR(log, __VA_ARGS__); \ 82 abort(); \ 83 } while(0) 84 85 #define LOGGER_ASSERT(log, cond, ...) \ 86 do { \ 87 if (!(cond)) { \ 88 LOGGER_ERROR(log, "Assertion failed"); \ 89 LOGGER_FATAL(log, __VA_ARGS__); \ 90 } \ 91 } while(0) 92 93 #endif // C_TOXCORE_TOXCORE_LOGGER_H 94