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