]> arthur.barton.de Git - netatalk.git/blob - include/atalk/logger.h
27e870cf1bc09531248383c7a0fb84c64a47796f
[netatalk.git] / include / atalk / logger.h
1 #ifndef _ATALK_LOGGER_H
2 #define _ATALK_LOGGER_H 1
3
4 /* 
5  * logger LOG Macro Usage
6  * ======================
7  *
8  * LOG(<logtype>, <loglevel>, "<string>"[, args]);
9  * 
10  *
11  * logger API Setup
12  * ================
13  * 
14  * Standard interface:
15  * -------------------
16  *
17  *    setuplog(char *confstring)
18  *    confstring = "<logtype> <loglevel> [<filename>]"
19  *
20  * Calling without <filename> configures basic logging to syslog. Specifying <filename>
21  * configures extended logging to <filename>.
22  * 
23  * You can later disable logging by calling
24  *
25  *    unsetuplog(char *confstring)
26  *    confstring = "<logtype> [<any_string>]"
27  *
28  * Calling without <any_string> disables syslog logging, calling with <any_string>
29  * disables file logging.
30  *
31  * <logtype>:
32  * you can setup a default with "Default". Any other logtype used in LOG will then
33  * use the default if not setup itself. This is probabyl the only thing you may
34  * want to use.
35  *
36  * Example:
37  * setuplog("default log_debug /var/log/debug.log");
38  * See also libatalk/util/test/logger_test.c
39  *
40  * "Legacy" interface:
41  * -------------------
42  *
43  * Some netatalk daemons (31.3.2009.: e.g. atalkd, papd) may not be converted to
44  * use the new API and might still call
45  *
46  *    syslog_setup(int loglevel, enum logtypes logtype, int display_options, int facility);
47  *
48  * directly. These daemons are therefore limited to syslog logging. Also their
49  * loglevel can't be changed at runtime.
50  *
51  *
52  * Note:
53  * dont get confused by log_init(). It only gets called if your app
54  * forgets to setup logging before calling LOG.
55  */
56
57
58 #include <limits.h>
59 #include <stdio.h>
60
61 #include <atalk/boolean.h>
62
63 #ifdef HAVE_CONFIG_H
64 #include "config.h"
65 #endif
66
67 #define MAXLOGSIZE 512
68
69 enum loglevels {
70     log_none,
71     log_severe,
72     log_error,
73     log_warning,
74     log_note,
75     log_info,
76 #ifndef NO_DEBUG
77     log_debug,
78     log_debug6,
79     log_debug7,
80     log_debug8,
81     log_debug9,
82     log_maxdebug
83 #else
84 #define log_debug -1
85 #define log_debug6 -1
86 #define log_debug7 -1
87 #define log_debug8 -1
88 #define log_debug9 -1
89 #define log_maxdebug -1 
90 #endif    
91 };
92
93 #define LOGLEVEL_STRING_IDENTIFIERS { \
94   "LOG_NOTHING",                      \
95   "LOG_SEVERE",                       \
96   "LOG_ERROR",                        \
97   "LOG_WARN",                         \
98   "LOG_NOTE",                         \
99   "LOG_INFO",                         \
100   "LOG_DEBUG",                        \
101   "LOG_DEBUG6",                       \
102   "LOG_DEBUG7",                       \
103   "LOG_DEBUG8",                       \
104   "LOG_DEBUG9",                       \
105   "LOG_MAXDEBUG"}                        
106
107 /* this is the enum specifying all availiable logtypes */
108 enum logtypes {
109   logtype_default,
110   logtype_core,
111   logtype_logger,
112   logtype_cnid,
113   logtype_afpd,
114   logtype_atalkd,
115   logtype_papd,
116   logtype_uams,
117
118   logtype_end_of_list_marker  /* don't put any logtypes after this */
119 };
120
121 /* these are the string identifiers corresponding to each logtype */
122 #define LOGTYPE_STRING_IDENTIFIERS { \
123   "Default",                         \
124   "Core",                            \
125   "Logger",                          \
126   "CNID",                            \
127   "AFPDaemon",                       \
128   "ATalkDaemon",                     \
129   "PAPDaemon",                       \
130   "UAMSDaemon",                      \
131                                      \
132   "end_of_list_marker"}              \
133
134 /* Display Option flags. */
135 /* redefine these so they can don't interfeer with syslog */
136 /* these can be used in standard logging too */
137 #define logoption_nsrcinfo    0x04   /* don't log source info */
138 /* the following do not work anymore, they're only provided in order to not
139  * break existing source code */
140 #define logoption_pid         0x01   /* log the pid with each message */
141 #define logoption_cons        0x02   /* log on the console if error logging */
142 #define logoption_ndelay      0x08   /* don't delay open */
143 #define logoption_perror      0x20   /* log to stderr as well */
144 #define logoption_nfile       0x40   /* ignore the file that called the log */
145 #define logoption_nline       0x80   /* ignore the line that called the log*/
146
147 /* facility codes */
148 /* redefine these so they can don't interfeer with syslog */
149 #define logfacility_user        (1<<3)  /* random user-level messages */
150 #define logfacility_mail        (2<<3)  /* mail system */
151 #define logfacility_daemon      (3<<3)  /* system daemons */
152 #define logfacility_auth        (4<<3)  /* security/authorization messages */
153 #define logfacility_syslog      (5<<3)  /* messages generated by syslogd */
154 #define logfacility_lpr         (6<<3)  /* line printer subsystem */
155 #define logfacility_authpriv    (10<<3) /* security/auth messages (private) */
156 #define logfacility_ftp         (11<<3) /* ftp daemon */
157
158 /* ========================================================================= 
159     Structure definitions
160    ========================================================================= */
161
162 /* Main log config */
163 typedef struct {
164     int   inited;                 /* file log config initialized ? */
165     int   filelogging;            /* Any level set to filelogging ? */
166                                   /* Deactivates syslog logging */
167     char  processname[16];
168     int   syslog_opened;          /* syslog opened ? */
169     int   facility;               /* syslog facility to use */
170     int   syslog_display_options;
171     int   syslog_level;           /* Log Level to send to syslog */
172 } log_config_t;
173
174 /* This stores the config and options for one filelog type (e.g. logger, afpd etc.) */
175 typedef struct {
176     int  set;                     /* set individually ? yes: changing default
177                                    * doesnt change it. no: it changes it.*/
178     char *filename;               /* Name of file */
179     int  fd;                      /* logfiles fd */
180     int  level;                   /* Log Level to put in this file */
181     int  display_options;
182 } filelog_conf_t;
183
184 /* ========================================================================= 
185     Global variables
186    ========================================================================= */
187
188 #ifndef LOGGER_C
189 /* Make config accessible for LOG macro */
190 extern log_config_t log_config;
191 extern filelog_conf_t file_configs[logtype_end_of_list_marker];
192
193 /* These are used by the LOG macro to store __FILE__ and __LINE__ */
194 extern char *log_src_filename;
195 extern int  log_src_linenumber;
196 #endif
197
198 /* =========================================================================
199     Global function decarations
200    ========================================================================= */
201
202 /*  */
203 void log_init(void);
204
205 /* Setup the level and type of log that will be logged for file loggging */
206 void log_setup(const char *filename, enum loglevels loglevel, enum logtypes logtype);
207
208 /* Setup the level and type of log that will be logged to syslog. */
209 void syslog_setup(int loglevel, enum logtypes logtype, 
210                   int display_options, int facility);
211
212 /* This gets called e.g. from afpd.conf parsing code with a string like: */
213 /* "default log_maxdebug /var/log/afpd.log" */
214 void setuplog(const char *logstr);
215
216 /* This gets called e.g. from afpd.conf parsing code with a string like: */
217 /* "default dummyname" */
218 void unsetuplog(const char *logstr);
219
220 /* finish up and close the logs */
221 void log_close(void);
222
223 /* This function sets up the ProcessName */
224 void set_processname(const char *processname);
225
226 /*
227  * How to write a LOG macro:
228  * http://c-faq.com/cpp/debugmacs.html
229  * 
230  * We choose the verbose form in favor of the obfuscated ones, its easier
231  * to parse for human beings and facilitates expanding the macro for
232  * inline checks for debug levels.
233  *
234  * How to properly enclose multistatement macros:
235  * http://en.wikipedia.org/wiki/C_macro#Multiple_statements
236  */
237
238 /* LOG macro func no.1: log the message to file */
239 void make_log_entry(enum loglevels loglevel, enum logtypes logtype, char *message, ...);
240
241 /* LOG macro func no.2: log the message to syslog */
242 void make_syslog_entry(enum loglevels loglevel, enum logtypes logtype, char *message, ...);
243
244 /* 
245    Note:
246    any configured file-logging deactivates syslog logging
247  */
248 #define LOG(log_level, type, ...)  \
249   do { \
250     if (log_level < 0) \
251       break; \
252     if ( ! log_config.inited) \
253       log_init(); \
254     if (file_configs[(type)].level >= (log_level)) \
255       log_src_filename = __FILE__, \
256       log_src_linenumber = __LINE__, \
257       make_log_entry((log_level), (type), __VA_ARGS__); \
258     else if (( ! log_config.filelogging) && (log_config.syslog_level >= (log_level))) \
259        make_syslog_entry((log_level), (type), __VA_ARGS__); \
260   } while(0)  
261 #endif /* _ATALK_LOGGER_H */