1 /**
2 * @file log.c Logging
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6
7 #include <re.h>
8 #include <baresip.h>
9
10
11 static struct {
12 struct list logl;
13 bool debug;
14 bool info;
15 bool enable_stdout;
16 } lg = {
17 LIST_INIT,
18 false,
19 true,
20 true
21 };
22
23
24 /**
25 * Register a log handler
26 *
27 * @param log Log handler
28 */
log_register_handler(struct log * log)29 void log_register_handler(struct log *log)
30 {
31 if (!log)
32 return;
33
34 list_append(&lg.logl, &log->le, log);
35 }
36
37
38 /**
39 * Unregister a log handler
40 *
41 * @param log Log handler
42 */
log_unregister_handler(struct log * log)43 void log_unregister_handler(struct log *log)
44 {
45 if (!log)
46 return;
47
48 list_unlink(&log->le);
49 }
50
51
52 /**
53 * Enable debug-level logging
54 *
55 * @param enable True to enable, false to disable
56 */
log_enable_debug(bool enable)57 void log_enable_debug(bool enable)
58 {
59 lg.debug = enable;
60 }
61
62
63 /**
64 * Enable info-level logging
65 *
66 * @param enable True to enable, false to disable
67 */
log_enable_info(bool enable)68 void log_enable_info(bool enable)
69 {
70 lg.info = enable;
71 }
72
73
74 /**
75 * Enable logging to standard-out
76 *
77 * @param enable True to enable, false to disable
78 */
log_enable_stdout(bool enable)79 void log_enable_stdout(bool enable)
80 {
81 lg.enable_stdout = enable;
82 }
83
84
85 /**
86 * Print a message to the logging system
87 *
88 * @param level Log level
89 * @param fmt Formatted message
90 * @param ap Variable argument list
91 */
vlog(enum log_level level,const char * fmt,va_list ap)92 void vlog(enum log_level level, const char *fmt, va_list ap)
93 {
94 char buf[4096];
95 struct le *le;
96
97 if (re_vsnprintf(buf, sizeof(buf), fmt, ap) < 0)
98 return;
99
100 if (lg.enable_stdout) {
101
102 bool color = level == LEVEL_WARN || level == LEVEL_ERROR;
103
104 if (color)
105 (void)re_fprintf(stdout, "\x1b[31m"); /* Red */
106
107 (void)re_fprintf(stdout, "%s", buf);
108
109 if (color)
110 (void)re_fprintf(stdout, "\x1b[;m");
111 }
112
113 le = lg.logl.head;
114
115 while (le) {
116
117 struct log *log = le->data;
118 le = le->next;
119
120 if (log->h)
121 log->h(level, buf);
122 }
123 }
124
125
126 /**
127 * Print a message to the logging system
128 *
129 * @param level Log level
130 * @param fmt Formatted message
131 * @param ... Variable arguments
132 */
loglv(enum log_level level,const char * fmt,...)133 void loglv(enum log_level level, const char *fmt, ...)
134 {
135 va_list ap;
136
137 if ((LEVEL_DEBUG == level) && !lg.debug)
138 return;
139
140 if ((LEVEL_INFO == level) && !lg.info)
141 return;
142
143 va_start(ap, fmt);
144 vlog(level, fmt, ap);
145 va_end(ap);
146 }
147
148
149 /**
150 * Print a DEBUG message to the logging system
151 *
152 * @param fmt Formatted message
153 * @param ... Variable arguments
154 */
debug(const char * fmt,...)155 void debug(const char *fmt, ...)
156 {
157 va_list ap;
158
159 if (!lg.debug)
160 return;
161
162 va_start(ap, fmt);
163 vlog(LEVEL_DEBUG, fmt, ap);
164 va_end(ap);
165 }
166
167
168 /**
169 * Print an INFO message to the logging system
170 *
171 * @param fmt Formatted message
172 * @param ... Variable arguments
173 */
info(const char * fmt,...)174 void info(const char *fmt, ...)
175 {
176 va_list ap;
177
178 if (!lg.info)
179 return;
180
181 va_start(ap, fmt);
182 vlog(LEVEL_INFO, fmt, ap);
183 va_end(ap);
184 }
185
186
187 /**
188 * Print a WARNING message to the logging system
189 *
190 * @param fmt Formatted message
191 * @param ... Variable arguments
192 */
warning(const char * fmt,...)193 void warning(const char *fmt, ...)
194 {
195 va_list ap;
196
197 va_start(ap, fmt);
198 vlog(LEVEL_WARN, fmt, ap);
199 va_end(ap);
200 }
201
202
203 /**
204 * Print an ERROR message to the logging system
205 *
206 * @param fmt Formatted message
207 * @param ... Variable arguments
208 */
error_msg(const char * fmt,...)209 void error_msg(const char *fmt, ...)
210 {
211 va_list ap;
212
213 va_start(ap, fmt);
214 vlog(LEVEL_ERROR, fmt, ap);
215 va_end(ap);
216 }
217