1 /*
2  * Copyright (c) 2002-2004 MontaVista Software, Inc.
3  * Copyright (c) 2006-2012 Red Hat, Inc.
4  *
5  * Author: Steven Dake (sdake@redhat.com)
6  * Author: Lon Hohberger (lhh@redhat.com)
7  * Author: Fabio M. Di Nitto (fdinitto@redhat.com)
8  *
9  * All rights reserved.
10  *
11  * This software licensed under BSD license, the text of which follows:
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions are met:
15  *
16  * - Redistributions of source code must retain the above copyright notice,
17  *   this list of conditions and the following disclaimer.
18  * - Redistributions in binary form must reproduce the above copyright notice,
19  *   this list of conditions and the following disclaimer in the documentation
20  *   and/or other materials provided with the distribution.
21  * - Neither the name of the MontaVista Software, Inc. nor the names of its
22  *   contributors may be used to endorse or promote products derived from this
23  *   software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
35  * THE POSSIBILITY OF SUCH DAMAGE.
36  */
37 #ifndef LOGSYS_H_DEFINED
38 #define LOGSYS_H_DEFINED
39 
40 #include <stdarg.h>
41 #include <stdlib.h>
42 #include <syslog.h>
43 #include <pthread.h>
44 #include <limits.h>
45 
46 #include <qb/qbconfig.h>
47 #include <qb/qblog.h>
48 
49 #ifdef __cplusplus
50 extern "C" {
51 #endif
52 
53 /*
54  * All of the LOGSYS_MODE's can be ORed together for combined behavior
55  *
56  * FORK and THREADED are ignored for SUBSYSTEMS
57  */
58 #define LOGSYS_MODE_OUTPUT_FILE		(1<<0)
59 #define LOGSYS_MODE_OUTPUT_STDERR	(1<<1)
60 #define LOGSYS_MODE_OUTPUT_SYSLOG	(1<<2)
61 #define LOGSYS_MODE_FORK		(1<<3)
62 #define LOGSYS_MODE_THREADED		(1<<4)
63 
64 /*
65  * Log priorities, compliant with syslog and SA Forum Log spec.
66  */
67 #define LOGSYS_LEVEL_EMERG		LOG_EMERG
68 #define LOGSYS_LEVEL_ALERT		LOG_ALERT
69 #define LOGSYS_LEVEL_CRIT		LOG_CRIT
70 #define LOGSYS_LEVEL_ERROR		LOG_ERR
71 #define LOGSYS_LEVEL_WARNING		LOG_WARNING
72 #define LOGSYS_LEVEL_NOTICE		LOG_NOTICE
73 #define LOGSYS_LEVEL_INFO		LOG_INFO
74 #define LOGSYS_LEVEL_DEBUG		LOG_DEBUG
75 #define LOGSYS_LEVEL_TRACE		LOG_TRACE
76 
77 /*
78  * logsys_logger bits
79  *
80  * SUBSYS_COUNT defines the maximum number of subsystems
81  * SUBSYS_NAMELEN defines the maximum len of a subsystem name
82  */
83 #define LOGSYS_MAX_SUBSYS_COUNT		32
84 #define LOGSYS_MAX_SUBSYS_NAMELEN	64
85 #define LOGSYS_MAX_PERROR_MSG_LEN	128
86 
87 /*
88  * Debug levels
89  */
90 #define LOGSYS_DEBUG_OFF		0
91 #define LOGSYS_DEBUG_ON			1
92 #define LOGSYS_DEBUG_TRACE		2
93 
94 #ifndef LOGSYS_UTILS_ONLY
95 
96 /**
97  * @brief configuration bits that can only be done for the whole system
98  * @param format
99  * @return
100  */
101 extern int logsys_format_set (
102 	const char *format);
103 
104 /**
105  * @brief logsys_format_get
106  * @return
107  */
108 extern char *logsys_format_get (void);
109 
110 /**
111  * @brief per system/subsystem settings.
112  *
113  * NOTE: once a subsystem is created and configured, changing
114  * the default does NOT affect the subsystems.
115  *
116  * Pass a NULL subsystem to change them all
117  *
118  * @param subsys
119  * @param facility
120  * @return
121  */
122 extern int logsys_config_syslog_facility_set (
123 	const char *subsys,
124 	unsigned int facility);
125 
126 /**
127  * @brief logsys_config_syslog_priority_set
128  * @param subsys
129  * @param priority
130  * @return
131  */
132 extern int logsys_config_syslog_priority_set (
133 	const char *subsys,
134 	unsigned int priority);
135 
136 /**
137  * @brief logsys_config_mode_set
138  * @param subsys
139  * @param mode
140  * @return
141  */
142 extern int logsys_config_mode_set (
143 	const char *subsys,
144 	unsigned int mode);
145 
146 /**
147  * @brief logsys_config_mode_get
148  * @param subsys
149  * @return
150  */
151 extern unsigned int logsys_config_mode_get (
152 	const char *subsys);
153 
154 /**
155  * @brief logsys_config_apply
156  */
157 void logsys_config_apply(void);
158 
159 /**
160  * @brief to close a logfile, just invoke this function with a NULL
161  * file or if you want to change logfile, the old one will
162  * be closed for you.
163  *
164  * @param subsys
165  * @param error_string
166  * @param file
167  * @return
168  */
169 extern int logsys_config_file_set (
170 	const char *subsys,
171 	const char **error_string,
172 	const char *file);
173 
174 /**
175  * @brief logsys_config_logfile_priority_set
176  * @param subsys
177  * @param priority
178  * @return
179  */
180 extern int logsys_config_logfile_priority_set (
181 	const char *subsys,
182 	unsigned int priority);
183 
184 /**
185  * @brief enabling debug, disable message priority filtering.
186  * everything is sent everywhere. priority values
187  * for file and syslog are not overwritten.
188  *
189  * @param subsys
190  * @param value
191  * @return
192  */
193 extern int logsys_config_debug_set (
194 	const char *subsys,
195 	unsigned int value);
196 
197 /*
198  * External API - helpers
199  *
200  * convert facility/priority to/from name/values
201  */
202 /**
203  * @brief logsys_priority_id_get
204  * @param name
205  * @return
206  */
207 extern int logsys_priority_id_get (
208 	const char *name);
209 
210 /**
211  * @brief logsys_priority_name_get
212  * @param priority
213  * @return
214  */
215 extern const char *logsys_priority_name_get (
216 	unsigned int priority);
217 
218 /**
219  * @brief _logsys_system_setup
220  * @param mainsystem
221  * @param mode
222  * @param syslog_facility
223  * @param syslog_priority
224  * @return
225  */
226 extern int _logsys_system_setup(
227 	const char *mainsystem,
228 	unsigned int mode,
229 	int syslog_facility,
230 	int syslog_priority);
231 
232 /**
233  * @brief logsys_system_fini
234  */
235 extern void logsys_system_fini (void);
236 
237 /**
238  * @brief _logsys_config_subsys_get
239  * @param subsys
240  * @return
241  */
242 extern int _logsys_config_subsys_get (
243 	const char *subsys);
244 
245 /**
246  * @brief _logsys_subsys_create
247  * @param subsys
248  * @param filename
249  * @return
250  */
251 extern int _logsys_subsys_create (const char *subsys, const char *filename);
252 
253 /**
254  * @brief logsys_thread_start
255  * @return
256  */
257 extern int logsys_thread_start (void);
258 
259 extern void logsys_blackbox_set(int enable);
260 
261 extern void logsys_blackbox_prefork(void);
262 
263 extern void logsys_blackbox_postfork(void);
264 
265 
266 /**
267  * @brief logsys_subsys_id
268  */
269 static int logsys_subsys_id __attribute__((unused)) = LOGSYS_MAX_SUBSYS_COUNT;
270 
271 /**
272  * @brief The LOGSYS_DECLARE_SYSTEM macro
273  * @param name
274  * @param mode
275  * @param syslog_facility
276  * @param syslog_priority
277  */
278 #define LOGSYS_DECLARE_SYSTEM(name,mode,syslog_facility,syslog_priority)\
279 QB_LOG_INIT_DATA(logsys_qb_init);					\
280 __attribute__ ((constructor))						\
281 static void logsys_system_init (void)					\
282 {									\
283 	if (_logsys_system_setup (name,mode,syslog_facility,syslog_priority) < 0) { \
284 		fprintf (stderr,					\
285 			"Unable to setup logging system: %s.\n", name);	\
286 		exit (-1);						\
287 	}								\
288 }
289 
290 /**
291  * @brief The LOGSYS_DECLARE_SUBSYS macro
292  * @param subsys
293  */
294 #define LOGSYS_DECLARE_SUBSYS(subsys)					\
295 __attribute__ ((constructor))						\
296 static void logsys_subsys_init (void)					\
297 {									\
298 	logsys_subsys_id =						\
299 		_logsys_subsys_create ((subsys), __FILE__);		\
300 	if (logsys_subsys_id == -1) {					\
301 		fprintf (stderr,					\
302 		"Unable to create logging subsystem: %s.\n", subsys);	\
303 		exit (-1);						\
304 	}								\
305 }
306 
307 /**
308  * @brief The LOGSYS_PERROR macro
309  * @param err_num
310  * @param level
311  * @param fmt
312  * @param args
313  */
314 #define LOGSYS_PERROR(err_num, level, fmt, args...) do {						\
315 		char _error_str[LOGSYS_MAX_PERROR_MSG_LEN];						\
316 		const char *_error_ptr = qb_strerror_r(err_num, _error_str, sizeof(_error_str));	\
317 		qb_log(level, fmt ": %s (%d)", ##args, _error_ptr, err_num);				\
318 	} while(0)
319 
320 #define log_printf(level, format, args...) qb_log(level, format, ##args)
321 #define ENTER qb_enter
322 #define LEAVE qb_leave
323 #define TRACE1(format, args...) qb_log(LOG_TRACE, "TRACE1:" #format, ##args)
324 #define TRACE2(format, args...) qb_log(LOG_TRACE, "TRACE2:" #format, ##args)
325 #define TRACE3(format, args...) qb_log(LOG_TRACE, "TRACE3:" #format, ##args)
326 #define TRACE4(format, args...) qb_log(LOG_TRACE, "TRACE4:" #format, ##args)
327 #define TRACE5(format, args...) qb_log(LOG_TRACE, "TRACE5:" #format, ##args)
328 #define TRACE6(format, args...) qb_log(LOG_TRACE, "TRACE6:" #format, ##args)
329 #define TRACE7(format, args...) qb_log(LOG_TRACE, "TRACE7:" #format, ##args)
330 #define TRACE8(format, args...) qb_log(LOG_TRACE, "TRACE8:" #format, ##args)
331 
332 #endif /* LOGSYS_UTILS_ONLY */
333 
334 #ifdef __cplusplus
335 }
336 #endif
337 
338 #endif /* LOGSYS_H_DEFINED */
339