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