]> arthur.barton.de Git - netatalk.git/blob - doc/README.logger
fix LFS test for cross compilation, from Bolke de Bruin
[netatalk.git] / doc / README.logger
1
2 =============================================================================
3     The logger
4
5 This document explains the function and hence api of libatalk/util/logger.c
6 it was written on 4th January 2002, by Simon Bazley (sibaz@sibaz.com)
7
8 =============================================================================
9
10
11 The logger was written to provide a means of storing log messages relating to
12 netatalk in a file rather than using the syslog facility.  The feature list 
13 was increased to include a number of ideas culminating in the current code.
14
15 -----------------------------------------------------------------------------
16     Feature list
17
18 1) logging to syslog (old behaviour).
19 2) logging the file name and line number of the caller.
20 3) logging to a file.
21 4) allowing callers to specify what logical area of code the log comes from.
22 4) maintaining different log levels for different logical areas of code.
23 5) logging separate files for separate areas if required.
24
25 -----------------------------------------------------------------------------
26     Method
27
28 The logger works by storing an array of data containers each responsible for
29 logging to a single file.  
30 Initally the array is initalised containing NULL references to the data, 
31 except for the zeroth position with contains the defaults (default data is
32 statically defined in the logger code, but can be overridden easily).  
33 As calls are made to the log_setup and syslog_setup functions with unused
34 code area references, new memory is allocated then a pointer to that memory
35 stored in the array.  It is intended that all data containers are setup and
36 initialised early on in the program life cycle.  There is no means to erase
37 initialised data containers other than by calling the log_close function, 
38 which should only be done after the last log messages has been sent.  Logger 
39 behaviour is unspecified after log_close has been called.  
40
41 =============================================================================
42     API Functions
43 =============================================================================
44
45 -----------------------------------------------------------------------------
46     void log_init();
47 Log_init allocates and zeros memory for the global data containers, then 
48 sets up then copies the statically defined default loggers into the zero 
49 position.  It is called by both of the setup functions and will only do 
50 anything if the global data hasn't already been initialised.  
51 Its only made externally accessibly for completeness, and need never be used.  
52
53 -----------------------------------------------------------------------------
54     bool log_setup(char *filename, enum loglevels loglevel, 
55                    enum logtypes logtype, int display_options);
56 log_setup specifies the filename and the loglevel that should be used when 
57 logging logs with the specified logtype.  The display_options indicate what
58 system stuff should be prepended to each line in the log file, in the same
59 way as the parameters in an openlog call.  The options defined in the logger.h
60 file correspond to equivalents in the syslog.h file.  The values they represent
61 are equivalent in both files, but should not be assumed.  
62 Some logoptions not in syslog have been added, see logger.h for details.  
63
64 -----------------------------------------------------------------------------
65     void syslog_setup(enum loglevels loglevel, enum logtypes logtype, 
66                      int display_options, int facility);
67 syslog_setup is equivalent to the log_setup call but setups data to log to the
68 syslogger for the area specified instead of a file.  syslog_setup will call 
69 openlog for each call to syslog_setup.  The facility parameter is stored, but 
70 used purely in this call to openlog.  I assume it you call syslog_setup 
71 multiple times with different values for display_options and facility, only the
72 last call is used.  Refer to syslog(3) for more details.  
73 The display options are global and are only stored once regardless of the 
74 logtype.  The value is only used by the logger used in-so-far-as the option is 
75 not a feature of the syslogger. 
76 The loglevel of the given logtype is stored even though the syslogger is used. 
77 The loglevel passed to each call to LOG is translated before being sent to the
78 syslogger.  The assumtion is that a log_severe (for example) applies only to 
79 netatalk and hence should not be translated to LOG_CRIT, but instead LOG_ERR 
80 is used.  (this translation is implemented in the function at the end of the 
81 logger.c file.  This means should you want to you could log debug messages to 
82 the syslogger without having to alter the syslogger for every other 
83 application.  
84 Some logoptions not in syslog have been added, see logger.h for details.  
85
86 -----------------------------------------------------------------------------
87     void log_close();
88 log_close simply frees up all the memory and closes any open files.  Ideally 
89 you could then recall log_setup and start again, but I think its too permanent 
90 for that.  This also closes up the syslogger.  
91
92 -----------------------------------------------------------------------------
93     void set_processname(char *processname);
94 set_processname stores the name of the funning process for use in identifying 
95 the caller in each line in the log.  This is equivalent to the parameter used 
96 in the call to openlog, but since it is global for the process it seemed 
97 sensible to separate it from every log_setup call.
98
99 -----------------------------------------------------------------------------
100     make_log_func set_log_location(char *srcfilename, int srclinenumber);
101 This sets up the temporary variables indicating the caller name and line number
102 logged in calls to make_log_entry.  The return value is a pointer to the 
103 make_log_entry function, thus enabling a single command to call both functions,
104 hidden behind a macro (the LOG macro, see later).  
105
106 -----------------------------------------------------------------------------
107     void make_log_entry(enum loglevels loglevel, enum logtypes logtype, 
108                           char *message, ...);
109 make_log_entry is an equivalent function to syslog except for the logtype 
110 parameter.  The logtype given indicates which area of code the call has come 
111 from and is used to determine which log_setup call is used to log the message.
112
113 -----------------------------------------------------------------------------
114     void load_proccessname_from_proc();
115 This function can be called instead of set_processname, to determine the 
116 processname from the /proc file system instead of from a given parameter.  This
117 probably only works on linux, but is included because it was the original 
118 method used to get the procname.  
119
120 -----------------------------------------------------------------------------
121     LOG Macro
122 This is actually defined as a call to set_log_location with parameters 
123 __FILE__ and __LINE__.  This returns a pointer to the make_log_entry function
124 which is then what the compiler will use to pass the given parameters to.  
125 What this means on the face of it is the LOG Macro can be considered to be this
126     void LOG(enum loglevels loglevel, enum logtypes logtype,
127               char *message, ...);
128
129 -----------------------------------------------------------------------------
130     LogTypes
131 logtypes have been mentioned earlier.  They specify the logical area of the 
132 code that a log call has come from.  This information is then used in a 
133 number of ways (see earlier).  
134 logtypes is infact an enum defined in the logger.h file.  To add a new 
135 logtype for a new area of code, add a new item to the logtypes enum, and a
136 corresponding string to the LOGTYPE_STRING_IDENTIFIERS macro.  
137 The string identifier is used as part of the message string for each log
138 message.  
139
140 =============================================================================
141     API in brief
142 =============================================================================
143 -----------------------------------------------------------------------------
144     SyslogSetup in brief
145 To setup the logger for use in a new application, call set_processname with 
146 the proccess's name, then call syslog_setup with your prefered default loglevel
147 and the default logtype (logtype_default).  The display_options and facility
148 are dependant on how you choose to display your logs.  
149
150 For Example:
151
152 set_processname("afpd");
153 syslog_setup(log_debug, logtype_default, logoption_ndelay | logoption_pid, 
154                 logfacility_daemon);
155
156 this sets the default loglevel to debug and the display options to include the
157 pid with the each log message.  The syslogger is told the application is of
158 type LOG_DAEMON
159 Make further calls to syslog_setup if other logtypes should have a different
160 loglevel.  
161
162 -----------------------------------------------------------------------------
163     LogSetup in brief
164 Logsetup is similar to syslogsetup except multiple calls are more common.  
165 First setup the filename and loglevel for the default logtype then call 
166 log_setup with the filename and loglevel for any logtypes that should take 
167 nondefault parameters.  A NULL filename indicates that the default filename 
168 should be used (this removes the need to store multiple instances of the same string).  
169
170 For Example:
171
172 log_setup("/var/log/netatalk.log", log_debug, logtype_default, 
173             logoption_ndelay | logoption_pid);
174
175 -----------------------------------------------------------------------------
176     Logging in brief
177 Logging is very similar to using the syslogger, just call the LOG macro in 
178 your code with the level of that log message, and the area of code it applies 
179 to (or logtype_default if you can't think of one), and a message.  The message
180 is passed with identical parameters to that in an sprintf statement.  Give a
181 format string as first parameter, then any variables in that string as extra
182 parameters.  
183 The logger will only log the message if the loglevel given is more severe 
184 (lower in value) than that given in the call to logsetup for the given logtype 
185 (or default logtype if your given one is uninitialised).
186
187 For Example:
188
189   LOG(log_info, logtype_logger, "Logger %d setup complete", n);
190
191