1 /*   (C) Copyright 2002, 2003, 2004, 2005 Stijn van Dongen
2  *   (C) Copyright 2006, 2007, 2008, 2009 Stijn van Dongen
3  *
4  * This file is part of tingea.  You can redistribute and/or modify tingea
5  * under the terms of the GNU General Public License; either version 3 of the
6  * License or (at your option) any later version.  You should have received a
7  * copy of the GPL along with tingea, in the file COPYING.
8 */
9 
10 #ifndef tingea_err_h
11 #define tingea_err_h
12 
13 #include <stdio.h>
14 #include <signal.h>
15 #include "types.h"
16 
17 
18 /* Experimental scheme for logging
19  * Contains
20  *    Three axes that have scales:
21  *    -  data            1  2  3
22  *                       CELL
23  *                          LIST
24  *                             AGGR
25  *    -  function/code   1  2  3  4
26  *                       LINE
27  *                          FUNCTION
28  *                             MODULE
29  *                                APP
30  *    -  monitoring      1  2  3  4  5
31  *                       DEBUG
32  *                          INFO
33  *                             WARN
34  *                                ERR
35  *                                   PANIC
36  *
37  *    These scales correspond with
38  *
39  *    what     (data, what are its parameters)
40  *    how      (function, what is changing)
41  *    pulse    (anything)
42  *
43  *    Several axes that are radio buttons:
44  *    -  IO
45  *    -  Thread
46  *    -  gauge       progress bars
47  *    -  IP          inter (process)
48  *    -  SLOT1       custom
49  *    -  SLOT2       custom
50  *    -  SLOT3       custom
51  *
52  * The programmer associates one or more logging levels with a logging
53  * statement. The user sets logging levels in terms of quietness.
54  * Quietness is quantified as shown in the list below. It may be applied
55  * to a single axis or to several axes simultaneously.
56  *
57  *    x  is silent
58  *    5  is tersest monitoring level
59  *    4  is tersest function/code level
60  *    3  is tersest data level
61  *    9  is tersest level possible, may exceed actual upper bound
62  *    1  is yappiest level.
63  *
64  * Only those statements for which the quiet level is quieter than the
65  * user-specified level will be printed.  If the programmer combines several
66  * axes generally all the corresponding levels are checked and all have to be
67  * OK, unless the user has specified that she is happy if at least one level is
68  * OK. This is done by including a literal 'V' in the MCXLOGTAG string or in
69  * the corresponding command-line option (usually -q).
70  *
71  * MCXLOGTAG is of the following form:
72  *
73  *       [<lead-tag>]<[dfgimstABC][0-9]>+[V]
74  *
75  * The optional <lead-tag> is one of [19x] as described above. The rest are
76  * pairs consisting of an indicator
77  *
78  *    d  data
79  *    f  function
80  *    g  gauge/progress
81  *    i  IO
82  *    m  monitoring
83  *    n  network
84  *    t  thread
85  *    A  custom axis 1
86  *    B  custom axis 1
87  *    C  custom axis 1
88  *
89  * followed by a level. Each indicator specifies an axis; each axis has its
90  * own scale and number of steps on the scale (see above).  Finally, a 'V'
91  * occurring anywhere signifies that OR logic is applied to loggin clauses
92  * rather than AND logic.
93  *
94  *    The lead tag sets a logging level for all axes simultaneously as follows:
95  *    1  MCX_LOG_ALL
96  *    9  MCX_LOG_TERSER
97  *    8  MCX_LOG_TERSE
98  *    x  MCX_LOG_NONE
99 */
100 
101 
102 extern mcxbits mcxLogLevel;
103 
104    /* When called this one optionally checks environment variable
105     * MCXLOGTAG to set the logging levels mcxLogLevelSetByString
106    */
107 void mcxLogSetFILE
108 (  FILE* fp
109 ,  mcxbool  ENV_LOG
110 )  ;
111 
112    /* When writing to this file embed the print statement in an if statement
113     * that checks whether your priority is ok with mcxLogGet.
114     * This is paramount with GAUGE type logging as a GAUGE = x setting
115     * may indicate that the user is logging to a shared stream.
116    */
117 FILE* mcxLogGetFILE
118 (  void
119 )  ;
120 
121 
122 extern volatile sig_atomic_t mcxLogSigGuard ;
123 
124 void mcxLogSig
125 (  int sig
126 )  ;
127 
128 
129 /* ******************** data */
130 
131 #define MCX_LOG_CELL       1 <<   0    /* node, point, scalar */
132 #define MCX_LOG_LIST       1 <<   1    /* list, tree, hash    */
133 #define MCX_LOG_AGGR       1 <<   2    /* everything else     */
134 
135 #define     MCX_LOG_DATA  (MCX_LOG_CELL | MCX_LOG_LIST | MCX_LOG_AGGR)
136 #define     MCX_LOG_DATA0  MCX_LOG_CELL
137 
138 
139 /* ******************** function */
140 
141 #define MCX_LOG_LINE       1u <<  3
142 #define MCX_LOG_FUNCTION   1u <<  4
143 #define MCX_LOG_MODULE     1u <<  5
144 #define MCX_LOG_APP        1u <<  6
145 
146 #define     MCX_LOG_FUNC  (MCX_LOG_LINE | MCX_LOG_FUNCTION | MCX_LOG_MODULE | MCX_LOG_APP)
147 #define     MCX_LOG_FUNC0  MCX_LOG_LINE
148 
149 
150 /* ******************** monitoring */
151 
152 #define MCX_LOG_DEBUG      1u <<  7
153 #define MCX_LOG_INFO       1u <<  8
154 #define MCX_LOG_WARN       1u <<  9
155 #define MCX_LOG_ERR        1u << 10
156 #define MCX_LOG_PANIC      1u << 11
157 
158 #define     MCX_LOG_MON  ( MCX_LOG_DEBUG| MCX_LOG_INFO | MCX_LOG_WARN | MCX_LOG_ERR| MCX_LOG_PANIC )
159 #define     MCX_LOG_MON0   MCX_LOG_DEBUG
160 
161 
162 /* ********************* unimodal axes   */
163 
164 #define MCX_LOG_IO         1u << 12
165 #define MCX_LOG_IP         1u << 13
166 #define MCX_LOG_THREAD     1u << 15
167 #define MCX_LOG_NETWORK    1u << 16
168 
169 #define  MCX_LOG_ASPECTS ( MCX_LOG_IO | MCX_LOG_IP | MCX_LOG_THREAD | MCX_LOG_GAUGE | MCX_LOG_NETWORK )
170 
171 
172 /* ********************* miscellaneous*/
173 
174 #define MCX_LOG_GAUGE      1u << 17
175 
176 
177 /* ********************* control      */
178 
179 #define MCX_LOG_AND        1u << 18
180 #define MCX_LOG_OR         1u << 19
181 #define MCX_LOG_NULL       1u << 20     /* turns of logging */
182 
183 
184 /* ********************* unspecified  */
185 
186 #define MCX_LOG_SLOT1      1u << 22
187 #define MCX_LOG_SLOT2      1u << 22
188 #define MCX_LOG_SLOT3      1u << 23
189 
190 #define  MCX_LOG_SLOT    ( MCX_LOG_SLOT1 | MCX_LOG_SLOT2 | MCX_LOG_SLOT3 )
191 
192 
193 /* ********************* all / terse  */
194 
195 #define MCX_LOG_NONE       0
196 #define MCX_LOG_VERBOSE  ( MCX_LOG_CELL | MCX_LOG_LINE | MCX_LOG_DEBUG | MCX_LOG_SLOT | MCX_LOG_ASPECTS )
197 #define MCX_LOG_TERSER   ( MCX_LOG_PANIC | MCX_LOG_AGGR | MCX_LOG_APP )
198 #define MCX_LOG_TERSE    ( MCX_LOG_TERSER | MCX_LOG_ASPECTS )
199 #define MCX_LOG_UNIVERSE ( MCX_LOG_DATA | MCX_LOG_FUNC | MCX_LOG_MON | MCX_LOG_SLOT | MCX_LOG_ASPECTS )
200 
201 
202 /* ********************* unused       */
203 
204 #define MCX_LOG_UNUSED     1u << 24
205 
206 
207 void mcxLogLevelSetByString
208 (  const char* str
209 )  ;
210 
211 void mcxLog
212 (  mcxbits level_programmer
213 ,  const char* tag
214 ,  const char* fmt
215 ,  ...
216 )
217 #ifdef __GNUC__
218 __attribute__ ((format (printf, 3, 4)))
219 #endif
220    ;
221 
222 mcxbool mcxLogGet
223 (  mcxbits level_programmer
224 )  ;
225 
226 
227 void mcxLog2
228 (  const char* tag
229 ,  const char* fmt
230 ,  ...
231 )
232 #ifdef __GNUC__
233 __attribute__ ((format (printf, 2, 3)))
234 #endif
235    ;
236 
237 
238 void  mcxTell
239 (  const char  *caller
240 ,  const char  *fmt
241 ,  ...
242 )
243 #ifdef __GNUC__
244 __attribute__ ((format (printf, 2, 3)))
245 #endif
246    ;
247 
248 
249 void  mcxTellf
250 (  FILE*       fp
251 ,  const char  *caller
252 ,  const char  *fmt
253 ,  ...
254 )
255 #ifdef __GNUC__
256 __attribute__ ((format (printf, 3, 4)))
257 #endif
258    ;
259 
260 
261 void  mcxWarn
262 (  const char  *caller
263 ,  const char  *fmt
264 ,  ...
265 )
266 #ifdef __GNUC__
267 __attribute__ ((format (printf, 2, 3)))
268 #endif
269    ;
270 
271 void  mcxErr
272 (  const char  *caller
273 ,  const char  *fmt
274 ,  ...
275 )
276 #ifdef __GNUC__
277 __attribute__ ((format (printf, 2, 3)))
278 #endif
279    ;
280 
281 void  mcxErrf
282 (  FILE*       fp
283 ,  const char  *caller
284 ,  const char  *fmt
285 ,  ...
286 )
287 #ifdef __GNUC__
288 __attribute__ ((format (printf, 3, 4)))
289 #endif
290    ;
291 
292 void  mcxDie
293 (  int status
294 ,  const char  *caller
295 ,  const char  *fmt
296 ,  ...
297 )
298 #ifdef __GNUC__
299 __attribute__ ((format (printf, 3, 4)))
300 #endif
301    ;
302 
303 void mcxTellFile
304 (  FILE* fp
305 )  ;
306 
307 void mcxWarnFile
308 (  FILE* fp
309 )  ;
310 
311 void mcxErrorFile
312 (  FILE* fp
313 )  ;
314 
315 
316 void mcxFail
317 (  void
318 )  ;
319 
320 void mcxExit
321 (  int val
322 )  ;
323 
324 #endif
325 
326