|
1 #include "log.h" |
|
2 |
|
3 #include <stdio.h> |
|
4 #include <stdarg.h> |
|
5 #include <string.h> |
|
6 #include <stdlib.h> |
|
7 #include <errno.h> |
|
8 |
|
9 /** |
|
10 * The global log level |
|
11 */ |
|
12 static enum log_level _log_level = LOG_LEVEL_DEFAULT; |
|
13 |
|
14 /** |
|
15 * List of log level names |
|
16 */ |
|
17 const char *log_level_names[] = { |
|
18 "DEBUG", |
|
19 "INFO", |
|
20 "WARN", |
|
21 "ERROR", |
|
22 "FATAL", |
|
23 NULL |
|
24 }; |
|
25 |
|
26 #define _LOG_LEVEL_NAME(ll) case LOG_ ## ll: return #ll; |
|
27 const char *log_level_name (enum log_level level) |
|
28 { |
|
29 switch (level) { |
|
30 _LOG_LEVEL_NAME(DEBUG) |
|
31 _LOG_LEVEL_NAME(INFO) |
|
32 _LOG_LEVEL_NAME(WARN) |
|
33 _LOG_LEVEL_NAME(ERROR) |
|
34 _LOG_LEVEL_NAME(FATAL) |
|
35 default: return "???"; |
|
36 } |
|
37 } |
|
38 #undef _LOG_LEVEL_NAME |
|
39 |
|
40 void set_log_level (enum log_level level) |
|
41 { |
|
42 // meep meep |
|
43 _log_level = level; |
|
44 } |
|
45 |
|
46 size_t str_append_fmt_va (char *buf_ptr, size_t *buf_size, const char *fmt, va_list args) |
|
47 { |
|
48 int ret; |
|
49 |
|
50 if (*buf_size && (ret = vsnprintf(buf_ptr, *buf_size, fmt, args)) < 0) |
|
51 return 0; |
|
52 |
|
53 if (ret > *buf_size) |
|
54 *buf_size = 0; |
|
55 |
|
56 else |
|
57 *buf_size -= ret; |
|
58 |
|
59 return ret; |
|
60 } |
|
61 |
|
62 size_t str_append_fmt (char *buf_ptr, size_t *buf_size, const char *fmt, ...) |
|
63 { |
|
64 va_list vargs; |
|
65 size_t ret; |
|
66 |
|
67 va_start(vargs, fmt); |
|
68 ret = str_append_fmt_va(buf_ptr, buf_size, fmt, vargs); |
|
69 va_end(vargs); |
|
70 |
|
71 return ret; |
|
72 } |
|
73 |
|
74 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) |
|
75 { |
|
76 char buf[LOG_MSG_MAX], *buf_ptr = buf; |
|
77 size_t buf_size = sizeof(buf); |
|
78 |
|
79 // filter out? |
|
80 if (level < _log_level) |
|
81 return; |
|
82 |
|
83 buf_ptr += str_append_fmt(buf_ptr, &buf_size, "[%5s] %20s : ", tag, func); |
|
84 |
|
85 // output the user data |
|
86 if (user_fmt) |
|
87 buf_ptr += str_append_fmt_va(buf_ptr, &buf_size, user_fmt, user_fmtargs); |
|
88 |
|
89 // output the suffix |
|
90 if (log_fmt) |
|
91 buf_ptr += str_append_fmt_va(buf_ptr, &buf_size, log_fmt, log_fmtargs); |
|
92 |
|
93 // display |
|
94 // XXX: handle SIGINTR? |
|
95 fprintf(stderr, "%s\n", buf); |
|
96 } |
|
97 |
|
98 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, ...) |
|
99 { |
|
100 va_list vargs; |
|
101 |
|
102 va_start(vargs, log_fmt); |
|
103 log_output_tag_va(level, tag, func, user_fmt, user_fmtargs, log_fmt, vargs); |
|
104 va_end(vargs); |
|
105 } |
|
106 |
|
107 void _log_msg (enum log_level level, const char *func, const char *format, ...) |
|
108 { |
|
109 va_list vargs; |
|
110 |
|
111 // formatted output: no suffix |
|
112 va_start(vargs, format); |
|
113 log_output_tag(level, log_level_name(level), func, format, vargs, NULL); |
|
114 va_end(vargs); |
|
115 } |
|
116 |
|
117 void _log_msg_va2 (enum log_level level, const char *func, const char *fmt1, va_list fmtargs1, const char *fmt2, va_list fmtargs2) |
|
118 { |
|
119 log_output_tag_va(level, log_level_name(level), func, fmt1, fmtargs1, fmt2, fmtargs2); |
|
120 } |
|
121 |
|
122 void _log_errno (enum log_level level, const char *func, const char *format, ...) |
|
123 { |
|
124 va_list vargs; |
|
125 |
|
126 // formatted output: suffix strerror() |
|
127 va_start(vargs, format); |
|
128 log_output_tag(level, log_level_name(level), func, format, vargs, ": %s", strerror(errno)); |
|
129 va_end(vargs); |
|
130 } |
|
131 |
|
132 void _log_exit (enum log_level level, int exit_code, const char *func, const char *format, ...) |
|
133 { |
|
134 va_list vargs; |
|
135 |
|
136 // formatted output without any suffix |
|
137 va_start(vargs, format); |
|
138 log_output_tag(level, "EXIT", func, format, vargs, NULL); |
|
139 va_end(vargs); |
|
140 |
|
141 // exit |
|
142 exit(exit_code); |
|
143 } |
|
144 |