1 #ifndef LOG_H |
|
2 #define LOG_H |
|
3 |
|
4 /** @file log.h |
|
5 * |
|
6 * Local logging functions |
|
7 */ |
|
8 #include "error.h" |
|
9 #include <stdarg.h> |
|
10 |
|
11 /** |
|
12 * Log level definitions |
|
13 * |
|
14 * XXX: these names conflict with <syslog.h> |
|
15 */ |
|
16 enum log_level { |
|
17 LOG_DEBUG, |
|
18 LOG_INFO, |
|
19 LOG_WARN, |
|
20 LOG_ERROR, |
|
21 LOG_FATAL, |
|
22 }; |
|
23 |
|
24 /** |
|
25 * List of log_level values as strings, NULL-terminated |
|
26 */ |
|
27 extern const char *log_level_names[]; |
|
28 |
|
29 /** |
|
30 * The default log level |
|
31 */ |
|
32 #define LOG_LEVEL_DEFAULT LOG_INFO |
|
33 |
|
34 /** |
|
35 * Maximum length of a log message, including terminating NUL |
|
36 */ |
|
37 #define LOG_MSG_MAX 1024 |
|
38 |
|
39 /** |
|
40 * Log output function, for displaying a line of text, without any trailing newline. |
|
41 */ |
|
42 typedef void (*log_output_func) (const char *line, void *arg); |
|
43 |
|
44 /** |
|
45 * Set the current log level to filter out messages below the given level |
|
46 */ |
|
47 void set_log_level (enum log_level level); |
|
48 |
|
49 /** |
|
50 * Set the current log output function, replacing any default or previous value. |
|
51 * |
|
52 * Pass in func as NULL to revert to the default handler. |
|
53 */ |
|
54 void log_set_func (log_output_func func, void *arg); |
|
55 |
|
56 /** |
|
57 * Internal logging func, meant for using custom level tags. This performs the filtering of log levels. |
|
58 * |
|
59 * Format the full output line, and pass it to the log_output_func. The line will be of the form: |
|
60 * "[<tag>] <func> : <user_fmt> [ <log_fmt> ]" |
|
61 */ |
|
62 void log_output_tag (enum log_level level, const char *tag, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, ...) |
|
63 __attribute__ ((format (printf, 6, 7))); |
|
64 |
|
65 /** |
|
66 * va_list version of log_output_tag |
|
67 */ |
|
68 void log_output_tag_va (enum log_level level, const char *tag, const char *func, const char *user_fmt, va_list user_fmtargs, const char *log_fmt, va_list log_fmtargs); |
|
69 |
|
70 /** |
|
71 * Log a message with the given level |
|
72 */ |
|
73 #define log_msg(level, ...) _log_msg(level, __func__, __VA_ARGS__) |
|
74 void _log_msg (enum log_level level, const char *func, const char *format, ...) |
|
75 __attribute__ ((format (printf, 3, 4))); |
|
76 |
|
77 /** |
|
78 * Log a message with the given level with the given format and varargs |
|
79 */ |
|
80 #define log_msg_va2(level, fmt1, vargs1, fmt2, vargs2) _log_msg_va(level, __func__, fmt1, vargs1, fmt2, vargs2) |
|
81 void _log_msg_va2 (enum log_level level, const char *func, const char *fmt1, va_list fmtargs1, const char *fmt2, va_list fmtargs2); |
|
82 |
|
83 |
|
84 /** |
|
85 * Shorthand for log_msg |
|
86 */ |
|
87 #define log_debug(...) log_msg(LOG_DEBUG, __VA_ARGS__) |
|
88 #define log_info(...) log_msg(LOG_INFO, __VA_ARGS__) |
|
89 #define log_warn(...) log_msg(LOG_WARN, __VA_ARGS__) |
|
90 /* #define log_error(...) log_msg(LOG_ERROR, __func__, __VA_ARGS__) */ |
|
91 #define log_fatal(...) log_msg(LOG_FATAL, __VA_ARGS__) |
|
92 |
|
93 /** |
|
94 * Log a message with the given level, appending the formatted error code name |
|
95 */ |
|
96 #define log_err(err_code, ...) _log_err(LOG_ERROR, err_code, __func__, __VA_ARGS__) |
|
97 #define log_warn_err(err_code, ...) _log_err(LOG_WARN, err_code, __func__, __VA_ARGS__) |
|
98 void _log_err (enum log_level level, err_t err, const char *func, const char *format, ...) |
|
99 __attribute__ ((format (printf, 4, 5))); |
|
100 |
|
101 /** |
|
102 * Log a message with the given level, appending the formatted error message |
|
103 */ |
|
104 #define log_error(err_info, ...) _log_error(LOG_ERROR, err_info, __func__, __VA_ARGS__) |
|
105 #define log_warn_error(err_info, ...) _log_error(LOG_WARN, err_info, __func__, __VA_ARGS__) |
|
106 void _log_error (enum log_level level, const error_t *err, const char *func, const char *format, ...) |
|
107 __attribute__ ((format (printf, 4, 5))); |
|
108 |
|
109 /** |
|
110 * Log using errno. |
|
111 */ |
|
112 #define log_perr(...) _log_perr(LOG_ERROR, __func__, __VA_ARGS__) |
|
113 void _log_perr (enum log_level level, const char *func, const char *format, ...) |
|
114 __attribute__ ((format (printf, 3, 4))); |
|
115 |
|
116 /** |
|
117 * Log with an [EXIT] tag at given level, and then exit with given exit code |
|
118 */ |
|
119 #define log_exit(level, exit_code, ...) _log_exit(level, exit_code, __func__, __VA_ARGS__) |
|
120 void _log_exit (enum log_level level, int exit_code, const char *func, const char *format, ...) |
|
121 __attribute__ ((format (printf, 4, 5))) |
|
122 __attribute__ ((noreturn)); |
|
123 |
|
124 |
|
125 /** |
|
126 * log_fatal + exit failure |
|
127 */ |
|
128 #define FATAL(...) do { log_fatal(__VA_ARGS__); abort(); } while (0) |
|
129 |
|
130 /** |
|
131 * log_err + exit failure |
|
132 */ |
|
133 #define FATAL_ERR(err_code, ...) do { _log_err(LOG_FATAL, err_code, __func__, __VA_ARGS__); abort(); } while (0) |
|
134 |
|
135 /** |
|
136 * log_err_info + exit failure |
|
137 */ |
|
138 #define FATAL_ERROR(err_info, ...) do { _log_error(LOG_FATAL, err_info, __func__, __VA_ARGS__); abort(); } while (0) |
|
139 |
|
140 /** |
|
141 * log_perr + exit failure |
|
142 */ |
|
143 #define FATAL_PERROR(...) do { _log_perr(LOG_FATAL, __func__, __VA_ARGS__); abort(); } while (0) |
|
144 |
|
145 /** |
|
146 * Exit with given code, also logging a message at LOG_INFO with anĀ [EXIT] tag |
|
147 */ |
|
148 #define EXIT_INFO(exit_code, ...) log_exit(LOG_INFO, exit_code, __VA_ARGS__) |
|
149 #define EXIT_WARN(exit_code, ...) log_exit(LOG_WARN, exit_code, __VA_ARGS__) |
|
150 #define EXIT_ERROR(exit_code, ...) log_exit(LOG_ERROR, exit_code, __VA_ARGS__) |
|
151 #define EXIT_FATAL(exit_code, ...) log_exit(LOG_FATAL, exit_code, __VA_ARGS__) |
|
152 |
|
153 #endif /* LOG_H */ |
|