1 /**
2 * @file config.h
3 *
4 * @brief Compile-time configuration
5 *
6 * The definitions herein may be modified for fine-grained control over the
7 * appearance and content of log messages, default values, and various
8 * thresholds (e.g. file and buffer sizes).
9 *
10 * @version 2.2.6
11 *
12 * -----------------------------------------------------------------------------
13 *
14 * SPDX-License-Identifier: MIT
15 *
16 * Copyright (c) 2018-2024 Ryan M. Lederman <lederman@gmail.com>
17 *
18 * Permission is hereby granted, free of charge, to any person obtaining a copy of
19 * this software and associated documentation files (the "Software"), to deal in
20 * the Software without restriction, including without limitation the rights to
21 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
22 * the Software, and to permit persons to whom the Software is furnished to do so,
23 * subject to the following conditions:
24 *
25 * The above copyright notice and this permission notice shall be included in all
26 * copies or substantial portions of the Software.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
30 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
31 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
32 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
33 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 *
35 * -----------------------------------------------------------------------------
36 */
37
38 #ifndef _SIR_CONFIG_H_INCLUDED
39 # define _SIR_CONFIG_H_INCLUDED
40
41 /**
42 * The time stamp format string at the start of log messages-not including
43 * milliseconds (as::SIR_MSECFORMAT), which is added separately.
44 *
45 * @remark Only applies if ::SIRO_NOTIME is not set.
46 *
47 * **Example**
48 * ~~~
49 * 23:30:26
50 * ~~~
51 */
52 # if !defined(SIR_TIMEFORMAT)
53 # define SIR_TIMEFORMAT "%H:%M:%S"
54 # endif
55
56 /**
57 * The format for milliseconds (1000ths of a second) in time stamps.
58 *
59 * @remark Only applies if ::SIRO_NOTIME *or* ::SIRO_NOMSEC are not set.
60 * @remark ::SIRO_NOTIME implies ::SIRO_NOMSEC.
61 *
62 * **Example**
63 * ~~~
64 * .034
65 * ~~~
66 */
67 # if !defined(SIR_MSECFORMAT)
68 # define SIR_MSECFORMAT ".%03ld"
69 # endif
70
71 /**
72 * The carriage return (CR) character to use in the end of line
73 * sequence when SIR_USE_EOL_CRLF is defined.
74 */
75 # if !defined(SIR_EOL_CR)
76 # define SIR_EOL_CR "\r"
77 # endif
78
79 /**
80 * The line feed (LF) character to use in the end of line sequence.
81 */
82 # if !defined(SIR_EOL_LF)
83 # define SIR_EOL_LF "\n"
84 # endif
85
86 /**
87 * The end of line sequence. If SIR_USE_EOL_CRLF is defined, the
88 * sequence will be SIR_EOL_CR + SIR_EOL_LF; otherwise just SIR_EOL_LF.
89 */
90 # if !defined(SIR_USE_EOL_CRLF)
91 # define SIR_EOL SIR_EOL_LF
92 # else
93 # define SIR_EOL SIR_EOL_CR SIR_EOL_LF
94 # endif
95
96 /**
97 * The string placed directly before the human-readable logging level.
98 *
99 * @remark Only applies if ::SIRO_NOLEVEL is not set.
100 */
101 # if !defined(SIR_LEVELPREFIX)
102 # define SIR_LEVELPREFIX "["
103 # endif
104
105 /**
106 * The string placed directly after the human-readable logging level.
107 *
108 * @remark Only applies if ::SIRO_NOLEVEL is not set.
109 */
110 # if !defined(SIR_LEVELSUFFIX)
111 # define SIR_LEVELSUFFIX "]"
112 # endif
113
114 /**
115 * The string placed directly before process and thread IDs.
116 *
117 * @remark Only applies if ::SIRO_NONAME is not set.
118 */
119 # if !defined(SIR_PIDPREFIX)
120 # define SIR_PIDPREFIX "("
121 # endif
122
123 /**
124 * The character placed directly after process and thread IDs.
125 *
126 * @remark Only applies if ::SIRO_NONAME is not set.
127 */
128 # if !defined(SIR_PIDSUFFIX)
129 # define SIR_PIDSUFFIX ")"
130 # endif
131
132 /**
133 * The format for the current process ID.
134 *
135 * @remark Only applies if ::SIRO_NOPID is not set.
136 */
137 # if !defined(SIR_PIDFORMAT)
138 # define SIR_PIDFORMAT "%d"
139 # endif
140
141 /**
142 * The format for the current thread ID.
143 *
144 * @remark Only applies if ::SIRO_NOTID is not set.
145 */
146 # if !defined(SIR_TIDFORMAT)
147 # if defined(__USE_HEX_TIDS__)
148 # define SIR_TIDFORMAT "%x"
149 # else
150 # define SIR_TIDFORMAT "%d"
151 # endif
152 # endif
153
154 /**
155 * The string to place between process and thread IDs.
156 *
157 * @remark Only applies if both ::SIRO_NOPID and ::SIRO_NOTID are not set.
158 *
159 * **Example**
160 * ~~~
161 * 3435.1189
162 * ~~~
163 */
164 # if !defined(SIR_PIDSEPARATOR)
165 # define SIR_PIDSEPARATOR "."
166 # endif
167
168 /** The string passed to fopen/fopen_s for log files. */
169 # if !defined(SIR_FOPENMODE)
170 # define SIR_FOPENMODE "a"
171 # endif
172
173 /**
174 * The size, in bytes, at which a log file will be rolled/archived.
175 * @remark Default = 5 MiB.
176 */
177 # if !defined(SIR_FROLLSIZE)
178 # define SIR_FROLLSIZE (1024 * 1024 * 5)
179 # endif
180
181 /**
182 * The time format string used in file headers (see ::SIR_FHFORMAT).
183 *
184 * @remark Only applies if ::SIRO_NOHDR is not set.
185 *
186 * **Example**
187 * ~~~
188 * 15:13:41 Fri 9 Jun 2023 (-0600)
189 * ~~~
190 */
191 # if !defined(SIR_FHTIMEFORMAT)
192 # define SIR_FHTIMEFORMAT "%H:%M:%S %a %d %b %Y (%z)"
193 # endif
194
195 /**
196 * The format string written to a log file when logging begins or the file
197 * is rolled/archived.
198 *
199 * @remark Only applies if ::SIRO_NOHDR is not set.
200 *
201 * - The first `%%s` format specifier is the message:
202 * - ::SIR_FHBEGIN
203 * - ::SIR_FHROLLED
204 *
205 * - The second `%%s` is the current date/time in the format specified by
206 * ::SIR_FHTIMEFORMAT.
207 */
208 # if !defined(SIR_FHFORMAT)
209 # define SIR_FHFORMAT SIR_EOL SIR_EOL "----- %s %s -----" SIR_EOL SIR_EOL
210 # endif
211
212 /**
213 * The string included in ::SIR_FHFORMAT when a logging session begins.
214 *
215 * @remark Only applies if ::SIRO_NOHDR is not set.
216 */
217 # if !defined(SIR_FHBEGIN)
218 # define SIR_FHBEGIN "session begin @"
219 # endif
220
221 /**
222 * The string included in ::SIR_FHFORMAT when a file is rolled/archived due to
223 * becoming larger than ::SIR_FROLLSIZE bytes in size.
224 *
225 * @remark Only applies if ::SIRO_NOHDR is not set.
226 *
227 * The `%%s` format specifier is the path of the archived file.
228 */
229 # if !defined(SIR_FHROLLED)
230 # define SIR_FHROLLED "archived as %s due to size @"
231 # endif
232
233 /**
234 * The time format string for rolled/archived log files (see ::SIR_FNAMEFORMAT).
235 *
236 * **Example**
237 * ~~~
238 * 2023-06-09-122049
239 * ~~~
240 */
241 # if !defined(SIR_FNAMETIMEFORMAT)
242 # define SIR_FNAMETIMEFORMAT "%Y-%m-%d-%H%M%S"
243 # endif
244
245 /**
246 * The sequence number format string for rolled/archived log files (see
247 * ::SIR_FNAMEFORMAT).
248 *
249 * **Example**
250 * ~~~
251 * -1
252 * ~~~
253 */
254 # if !defined(SIR_FNAMESEQFORMAT)
255 # define SIR_FNAMESEQFORMAT "-%hu"
256 # endif
257
258 /**
259 * The format string for rolled/archived log file names.
260 *
261 * - The first %%s format specifier is the original file name, up to but not
262 * including the last full stop (.), if any exist.
263 *
264 * - The second %%s is the time stamp as defined by ::SIR_FNAMETIMEFORMAT.
265 *
266 * - The third %%s is a sequence number, which may be used in the event that
267 * a log file with the same name already exists (i.e., 2 or more files are
268 * rolled/archived within a second). Its format is defined by ::SIR_FNAMESEQFORMAT.
269 *
270 * - The fourth %%s is the original file name including, and beyond the last
271 * full stop, if one was found.
272 *
273 * **Example**
274 * ~~~
275 * `oldname.log` -> `oldname-23-06-09-122049-1.log`
276 * ~~~
277 */
278 # if !defined(SIR_FNAMEFORMAT)
279 # define SIR_FNAMEFORMAT "%s-%s%s%s"
280 # endif
281
282 /** The human-readable form of the ::SIRL_EMERG level. */
283 # if !defined(SIRL_S_EMERG)
284 # define SIRL_S_EMERG "emrg"
285 # endif
286
287 /** The human-readable form of the ::SIRL_ALERT level. */
288 # if !defined(SIRL_S_ALERT)
289 # define SIRL_S_ALERT "alrt"
290 # endif
291
292 /** The human-readable form of the ::SIRL_CRIT level. */
293 # if !defined(SIRL_S_CRIT)
294 # define SIRL_S_CRIT "crit"
295 # endif
296
297 /** The human-readable form of the ::SIRL_ERROR level. */
298 # if !defined(SIRL_S_ERROR)
299 # define SIRL_S_ERROR "erro"
300 # endif
301
302 /** The human-readable form of the ::SIRL_WARN level. */
303 # if !defined(SIRL_S_WARN)
304 # define SIRL_S_WARN "warn"
305 # endif
306
307 /** The human-readable form of the ::SIRL_NOTICE level. */
308 # if !defined(SIRL_S_NOTICE)
309 # define SIRL_S_NOTICE "noti"
310 # endif
311
312 /** The human-readable form of the ::SIRL_INFO level. */
313 # if !defined(SIRL_S_INFO)
314 # define SIRL_S_INFO "info"
315 # endif
316
317 /** The human-readable form of the ::SIRL_DEBUG level. */
318 # if !defined(SIRL_S_DEBUG)
319 # define SIRL_S_DEBUG "debg"
320 # endif
321
322 /** The maximum number of log files that may be registered at one time. */
323 # if !defined(SIR_MAXFILES)
324 # define SIR_MAXFILES 16
325 # endif
326
327 /** The maximum number of plugin modules that may be loaded at one time. */
328 # if !defined(SIR_MAXPLUGINS)
329 # define SIR_MAXPLUGINS 16
330 # endif
331
332 /** The size, in characters, of the buffer used to hold file header format strings. */
333 # if !defined(SIR_MAXFHEADER)
334 # define SIR_MAXFHEADER 128
335 # endif
336
337 /**
338 * The maximum number of characters allowable in one log message. This
339 * does not include accompanying formatted output (see ::SIR_MAXOUTPUT).
340 */
341 # if !defined(SIR_MAXMESSAGE)
342 # define SIR_MAXMESSAGE 4096
343 # endif
344
345 /** The size, in characters, of the buffer used to hold time format strings. */
346 # if !defined(SIR_MAXTIME)
347 # define SIR_MAXTIME 64
348 # endif
349
350 /** The size, in characters, of the buffer used to hold millisecond strings. */
351 # if !defined(SIR_MAXMSEC)
352 # define SIR_MAXMSEC 5
353 # endif
354
355 /** The size, in characters, of the buffer used to hold level format strings. */
356 # if !defined(SIR_MAXLEVEL)
357 # define SIR_MAXLEVEL 7
358 # endif
359
360 /**
361 * The size, in characters, of the buffer used to hold process/appname
362 * format strings.
363 */
364 # if !defined(SIR_MAXNAME)
365 # define SIR_MAXNAME 32
366 # endif
367
368 /**
369 * The size, in characters, of the buffer used to hold system logger identity
370 * strings.
371 */
372 # if !defined(SIR_MAX_SYSLOG_ID)
373 # define SIR_MAX_SYSLOG_ID 128
374 # endif
375
376 /**
377 * The size, in characters, of the buffer used to hold system logger category
378 * strings.
379 */
380 # if !defined(SIR_MAX_SYSLOG_CAT)
381 # define SIR_MAX_SYSLOG_CAT 64
382 # endif
383
384 /** The maximum number of whitespace and miscellaneous characters included in output. */
385 # if !defined(SIR_MAXMISC)
386 # define SIR_MAXMISC 7
387 # endif
388
389 /**
390 * The size, in characters, of the buffer used to hold a sequence of styling
391 * data in any color mode (the largest possible sequence, which is:
392 * `\x1b[a;fb;m;rrr;ggg;bbb;fb;m;rrr;ggg;bbbm`) plus a null terminator.
393 */
394 # if !defined(SIR_NO_TEXT_STYLING)
395 # if !defined(SIR_MAXSTYLE)
396 # if !defined(SIR_USE_EOL_CRLF)
397 # define SIR_MAXSTYLE 43
398 # else
399 # define SIR_MAXSTYLE 44
400 # endif
401 # endif
402 # else
403 # if !defined(SIR_MAXSTYLE)
404 # if !defined(SIR_USE_EOL_CRLF)
405 # define SIR_MAXSTYLE 1
406 # else
407 # define SIR_MAXSTYLE 2
408 # endif
409 # endif
410 # endif
411
412 /** The maximum size, in characters, of final formatted output. */
413 # define SIR_MAXOUTPUT \
414 (SIR_MAXMESSAGE + (SIR_MAXSTYLE * 2) + SIR_MAXTIME + SIR_MAXLEVEL + \
415 SIR_MAXNAME + (SIR_MAXPID * 2) + SIR_MAXMISC + 2 + 1)
416
417 /** The maximum size, in characters, of an error message. */
418 # if !defined(SIR_MAXERROR)
419 # define SIR_MAXERROR 256
420 # endif
421
422 /**
423 * The format string for error messages returned by ::sir_geterror.
424 *
425 * - The first `%%s` format specifier is the function name.
426 * - The second `%%s` is the file name.
427 * - The `%%lu` is the line number in the file.
428 * - The third `%%s` is the error message.
429 *
430 * **Example**
431 * ~~~
432 * Error in findneedle (haystack.c:384): 'Too much hay'
433 * ~~~
434 */
435 # define SIR_ERRORFORMAT "Error in %s (%s:%u): '%s'"
436
437 /** The string that represents any unknown. */
438 # if !defined(SIR_UNKNOWN)
439 # define SIR_UNKNOWN "<unknown>"
440 # endif
441
442 /** stderr destination string. */
443 # if !defined(SIR_DESTNAME_STDERR)
444 # define SIR_DESTNAME_STDERR "stderr"
445 # endif
446
447 /** stdout destination string. */
448 # if !defined(SIR_DESTNAME_STDOUT)
449 # define SIR_DESTNAME_STDOUT "stdout"
450 # endif
451
452 /** System logger destination string. */
453 # if !defined(SIR_DESTNAME_SYSLOG)
454 # define SIR_DESTNAME_SYSLOG "syslog"
455 # endif
456
457 /** Fallback system logger identity. */
458 # if !defined(SIR_FALLBACK_SYSLOG_ID)
459 # define SIR_FALLBACK_SYSLOG_ID "libsir"
460 # endif
461
462 /** Fallback system logger category. */
463 # if !defined(SIR_FALLBACK_SYSLOG_CAT)
464 # define SIR_FALLBACK_SYSLOG_CAT "general"
465 # endif
466
467 /**
468 * The number of actual levels; ::SIRL_NONE, ::SIRL_ALL, and ::SIRL_DEFAULT
469 * are pseudo levels and end up being mapped (or not) to the others.
470 */
471 # define SIR_NUMLEVELS 8
472
473 /**
474 * The number of actual options; ::SIRO_ALL, ::SIRO_DEFAULT, and ::SIRO_MSGONLY
475 * are pseudo options that end up being mapped (or not) to the others.
476 */
477 # define SIR_NUMOPTIONS 8
478
479 /**
480 * The number of seconds to let elapse before checking if the hostname needs
481 * refreshing. The default is an eager 1 minute. Better safe than wrong?
482 */
483 # if !defined(SIR_HNAME_CHK_INTERVAL)
484 # define SIR_HNAME_CHK_INTERVAL 60
485 # endif
486
487 /**
488 * The number of milliseconds to let elapse before re-formatting the current
489 * thread identifier and/or name.
490 */
491 # if !defined(SIR_THRD_CHK_INTERVAL)
492 # define SIR_THRD_CHK_INTERVAL 333.0
493 # endif
494
495 /**
496 * The number of writes to a file to let occur before checking its current size to
497 * determine if it needs to be rolled.
498 */
499 # if !defined(SIR_FILE_CHK_SIZE_WRITES)
500 # define SIR_FILE_CHK_SIZE_WRITES 10
501 # endif
502
503 # if defined(SIR_OS_LOG_ENABLED)
504 /**
505 * The special format specifier to send to os_log. By default, the log will only
506 * show "<private>" in place of the original message. By using "%{public}s", the
507 * message contents will be visible in the log.
508 */
509 # if !defined(SIR_OS_LOG_FORMAT)
510 # define SIR_OS_LOG_FORMAT "%{public}s"
511 # endif
512 # endif
513
514 /**
515 * The number of consecutive duplicate messages that will cause libsir to
516 * squelch further identical messages, and instead log the message
517 * ::SIR_SQUELCH_MSG_FORMAT.
518 */
519 # if !defined(SIR_SQUELCH_THRESHOLD)
520 # define SIR_SQUELCH_THRESHOLD 5
521 # endif
522
523 /**
524 * If duplicate messages continue to be logged after the threshold is met, the
525 * threshold will be multiplied by this number, resulting in longer intervals
526 * between ::SIR_SQUELCH_MSG_FORMAT messages.
527 */
528 # if !defined(SIR_SQUELCH_BACKOFF_FACTOR)
529 # define SIR_SQUELCH_BACKOFF_FACTOR 2
530 # endif
531
532 /**
533 * The message to be logged when ::SIR_SQUELCH_THRESHOLD (or a multiple thereof)
534 * consecutive duplicate messages are logged.
535 */
536 # if !defined(SIR_SQUELCH_MSG_FORMAT)
537 # define SIR_SQUELCH_MSG_FORMAT "previous message repeated %zu times"
538 # endif
539
540 #endif /* !_SIR_CONFIG_H_INCLUDED */