zf_log.h.master 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937
  1. #pragma once
  2. #ifndef _ZF_LOG_H_
  3. #define _ZF_LOG_H_
  4. /* To detect incompatible changes you can define ZF_LOG_VERSION_REQUIRED to be
  5. * the current value of ZF_LOG_VERSION before including this file (or via
  6. * compiler command line):
  7. *
  8. * #define ZF_LOG_VERSION_REQUIRED 4
  9. * #include <zf_log.h>
  10. *
  11. * Compilation will fail when included file has different version.
  12. */
  13. #define ZF_LOG_VERSION 4
  14. #if defined(ZF_LOG_VERSION_REQUIRED)
  15. #if ZF_LOG_VERSION_REQUIRED != ZF_LOG_VERSION
  16. #error different zf_log version required
  17. #endif
  18. #endif
  19. /* Log level guideline:
  20. * - ZF_LOG_FATAL - happened something impossible and absolutely unexpected.
  21. * Process can't continue and must be terminated.
  22. * Example: division by zero, unexpected modifications from other thread.
  23. * - ZF_LOG_ERROR - happened something possible, but highly unexpected. The
  24. * process is able to recover and continue execution.
  25. * Example: out of memory (could also be FATAL if not handled properly).
  26. * - ZF_LOG_WARN - happened something that *usually* should not happen and
  27. * significantly changes application behavior for some period of time.
  28. * Example: configuration file not found, auth error.
  29. * - ZF_LOG_INFO - happened significant life cycle event or major state
  30. * transition.
  31. * Example: app started, user logged in.
  32. * - ZF_LOG_DEBUG - minimal set of events that could help to reconstruct the
  33. * execution path. Usually disabled in release builds.
  34. * - ZF_LOG_VERBOSE - all other events. Usually disabled in release builds.
  35. *
  36. * *Ideally*, log file of debugged, well tested, production ready application
  37. * should be empty or very small. Choosing a right log level is as important as
  38. * providing short and self descriptive log message.
  39. */
  40. #define ZF_LOG_VERBOSE 1
  41. #define ZF_LOG_DEBUG 2
  42. #define ZF_LOG_INFO 3
  43. #define ZF_LOG_WARN 4
  44. #define ZF_LOG_ERROR 5
  45. #define ZF_LOG_FATAL 6
  46. #define ZF_LOG_NONE 0xFF
  47. /* "Current" log level is a compile time check and has no runtime overhead. Log
  48. * level that is below current log level it said to be "disabled". Otherwise,
  49. * it's "enabled". Log messages that are disabled has no runtime overhead - they
  50. * are converted to no-op by preprocessor and then eliminated by compiler.
  51. * Current log level is configured per compilation module (.c/.cpp/.m file) by
  52. * defining ZF_LOG_DEF_LEVEL or ZF_LOG_LEVEL. ZF_LOG_LEVEL has higer priority
  53. * and when defined overrides value provided by ZF_LOG_DEF_LEVEL.
  54. *
  55. * Common practice is to define default current log level with ZF_LOG_DEF_LEVEL
  56. * in build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
  57. * project or target:
  58. *
  59. * CC_ARGS := -DZF_LOG_DEF_LEVEL=ZF_LOG_INFO
  60. *
  61. * And when necessary to override it with ZF_LOG_LEVEL in .c/.cpp/.m files
  62. * before including zf_log.h:
  63. *
  64. * #define ZF_LOG_LEVEL ZF_LOG_VERBOSE
  65. * #include <zf_log.h>
  66. *
  67. * If both ZF_LOG_DEF_LEVEL and ZF_LOG_LEVEL are undefined, then ZF_LOG_INFO
  68. * will be used for release builds (NDEBUG is defined) and ZF_LOG_DEBUG
  69. * otherwise (NDEBUG is not defined).
  70. */
  71. #if defined(ZF_LOG_LEVEL)
  72. #define _ZF_LOG_LEVEL ZF_LOG_LEVEL
  73. #elif defined(ZF_LOG_DEF_LEVEL)
  74. #define _ZF_LOG_LEVEL ZF_LOG_DEF_LEVEL
  75. #else
  76. #ifdef NDEBUG
  77. #define _ZF_LOG_LEVEL ZF_LOG_INFO
  78. #else
  79. #define _ZF_LOG_LEVEL ZF_LOG_DEBUG
  80. #endif
  81. #endif
  82. /* "Output" log level is a runtime check. When log level is below output log
  83. * level it said to be "turned off" (or just "off" for short). Otherwise it's
  84. * "turned on" (or just "on"). Log levels that were "disabled" (see
  85. * ZF_LOG_LEVEL and ZF_LOG_DEF_LEVEL) can't be "turned on", but "enabled" log
  86. * levels could be "turned off". Only messages with log level which is
  87. * "turned on" will reach output facility. All other messages will be ignored
  88. * (and their arguments will not be evaluated). Output log level is a global
  89. * property and configured per process using zf_log_set_output_level() function
  90. * which can be called at any time.
  91. *
  92. * Though in some cases it could be useful to configure output log level per
  93. * compilation module or per library. There are two ways to achieve that:
  94. * - Define ZF_LOG_OUTPUT_LEVEL to expresion that evaluates to desired output
  95. * log level.
  96. * - Copy zf_log.h and zf_log.c files into your library and build it with
  97. * ZF_LOG_LIBRARY_PREFIX defined to library specific prefix. See
  98. * ZF_LOG_LIBRARY_PREFIX for more details.
  99. *
  100. * When defined, ZF_LOG_OUTPUT_LEVEL must evaluate to integral value that
  101. * corresponds to desired output log level. Use it only when compilation module
  102. * is required to have output log level which is different from global output
  103. * log level set by zf_log_set_output_level() function. For other cases,
  104. * consider defining ZF_LOG_LEVEL or using zf_log_set_output_level() function.
  105. *
  106. * Example:
  107. *
  108. * #define ZF_LOG_OUTPUT_LEVEL g_module_log_level
  109. * #include <zf_log.h>
  110. * static int g_module_log_level = ZF_LOG_INFO;
  111. * static void foo() {
  112. * ZF_LOGI("Will check g_module_log_level for output log level");
  113. * }
  114. * void debug_log(bool on) {
  115. * g_module_log_level = on? ZF_LOG_DEBUG: ZF_LOG_INFO;
  116. * }
  117. *
  118. * Note on performance. This expression will be evaluated each time message is
  119. * logged (except when message log level is "disabled" - see ZF_LOG_LEVEL for
  120. * details). Keep this expression as simple as possible, otherwise it will not
  121. * only add runtime overhead, but also will increase size of call site (which
  122. * will result in larger executable). The prefered way is to use integer
  123. * variable (as in example above). If structure must be used, log_level field
  124. * must be the first field in this structure:
  125. *
  126. * #define ZF_LOG_OUTPUT_LEVEL (g_config.log_level)
  127. * #include <zf_log.h>
  128. * struct config {
  129. * int log_level;
  130. * unsigned other_field;
  131. * [...]
  132. * };
  133. * static config g_config = {ZF_LOG_INFO, 0, ...};
  134. *
  135. * This allows compiler to generate more compact load instruction (no need to
  136. * specify offset since it's zero). Calling a function to get output log level
  137. * is generaly a bad idea, since it will increase call site size and runtime
  138. * overhead even further.
  139. */
  140. #if defined(ZF_LOG_OUTPUT_LEVEL)
  141. #define _ZF_LOG_OUTPUT_LEVEL ZF_LOG_OUTPUT_LEVEL
  142. #else
  143. #define _ZF_LOG_OUTPUT_LEVEL _zf_log_global_output_lvl
  144. #endif
  145. /* "Tag" is a compound string that could be associated with a log message. It
  146. * consists of tag prefix and tag (both are optional).
  147. *
  148. * Tag prefix is a global property and configured per process using
  149. * zf_log_set_tag_prefix() function. Tag prefix identifies context in which
  150. * component or module is running (e.g. process name). For example, the same
  151. * library could be used in both client and server processes that work on the
  152. * same machine. Tag prefix could be used to easily distinguish between them.
  153. * For more details about tag prefix see zf_log_set_tag_prefix() function. Tag
  154. * prefix
  155. *
  156. * Tag identifies component or module. It is configured per compilation module
  157. * (.c/.cpp/.m file) by defining ZF_LOG_TAG or ZF_LOG_DEF_TAG. ZF_LOG_TAG has
  158. * higer priority and when defined overrides value provided by ZF_LOG_DEF_TAG.
  159. * When defined, value must evaluate to (const char *), so for strings double
  160. * quotes must be used.
  161. *
  162. * Default tag could be defined with ZF_LOG_DEF_TAG in build script (e.g.
  163. * Makefile, CMakeLists.txt, gyp, etc.) for the entire project or target:
  164. *
  165. * CC_ARGS := -DZF_LOG_DEF_TAG=\"MISC\"
  166. *
  167. * And when necessary could be overriden with ZF_LOG_TAG in .c/.cpp/.m files
  168. * before including zf_log.h:
  169. *
  170. * #define ZF_LOG_TAG "MAIN"
  171. * #include <zf_log.h>
  172. *
  173. * If both ZF_LOG_DEF_TAG and ZF_LOG_TAG are undefined no tag will be added to
  174. * the log message (tag prefix still could be added though).
  175. *
  176. * Output example:
  177. *
  178. * 04-29 22:43:20.244 40059 1299 I hello.MAIN Number of arguments: 1
  179. * | |
  180. * | +- tag (e.g. module)
  181. * +- tag prefix (e.g. process name)
  182. */
  183. #if defined(ZF_LOG_TAG)
  184. #define _ZF_LOG_TAG ZF_LOG_TAG
  185. #elif defined(ZF_LOG_DEF_TAG)
  186. #define _ZF_LOG_TAG ZF_LOG_DEF_TAG
  187. #else
  188. #define _ZF_LOG_TAG 0
  189. #endif
  190. /* Source location is part of a log line that describes location (function or
  191. * method name, file name and line number, e.g. "[email protected]:68") of a
  192. * log statement that produced it.
  193. * Source location formats are:
  194. * - ZF_LOG_SRCLOC_NONE - don't add source location to log line.
  195. * - ZF_LOG_SRCLOC_SHORT - add source location in short form (file and line
  196. * number, e.g. "@main.cpp:68").
  197. * - ZF_LOG_SRCLOC_LONG - add source location in long form (function or method
  198. * name, file and line number, e.g. "[email protected]:68").
  199. */
  200. #define ZF_LOG_SRCLOC_NONE 0
  201. #define ZF_LOG_SRCLOC_SHORT 1
  202. #define ZF_LOG_SRCLOC_LONG 2
  203. /* Source location format is configured per compilation module (.c/.cpp/.m
  204. * file) by defining ZF_LOG_DEF_SRCLOC or ZF_LOG_SRCLOC. ZF_LOG_SRCLOC has
  205. * higer priority and when defined overrides value provided by
  206. * ZF_LOG_DEF_SRCLOC.
  207. *
  208. * Common practice is to define default format with ZF_LOG_DEF_SRCLOC in
  209. * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
  210. * project or target:
  211. *
  212. * CC_ARGS := -DZF_LOG_DEF_SRCLOC=ZF_LOG_SRCLOC_LONG
  213. *
  214. * And when necessary to override it with ZF_LOG_SRCLOC in .c/.cpp/.m files
  215. * before including zf_log.h:
  216. *
  217. * #define ZF_LOG_SRCLOC ZF_LOG_SRCLOC_NONE
  218. * #include <zf_log.h>
  219. *
  220. * If both ZF_LOG_DEF_SRCLOC and ZF_LOG_SRCLOC are undefined, then
  221. * ZF_LOG_SRCLOC_NONE will be used for release builds (NDEBUG is defined) and
  222. * ZF_LOG_SRCLOC_LONG otherwise (NDEBUG is not defined).
  223. */
  224. #if defined(ZF_LOG_SRCLOC)
  225. #define _ZF_LOG_SRCLOC ZF_LOG_SRCLOC
  226. #elif defined(ZF_LOG_DEF_SRCLOC)
  227. #define _ZF_LOG_SRCLOC ZF_LOG_DEF_SRCLOC
  228. #else
  229. #ifdef NDEBUG
  230. #define _ZF_LOG_SRCLOC ZF_LOG_SRCLOC_NONE
  231. #else
  232. #define _ZF_LOG_SRCLOC ZF_LOG_SRCLOC_LONG
  233. #endif
  234. #endif
  235. #if ZF_LOG_SRCLOC_LONG == _ZF_LOG_SRCLOC
  236. #define _ZF_LOG_SRCLOC_FUNCTION _ZF_LOG_FUNCTION
  237. #else
  238. #define _ZF_LOG_SRCLOC_FUNCTION 0
  239. #endif
  240. /* Censoring provides conditional logging of secret information, also known as
  241. * Personally Identifiable Information (PII) or Sensitive Personal Information
  242. * (SPI). Censoring can be either enabled (ZF_LOG_CENSORED) or disabled
  243. * (ZF_LOG_UNCENSORED). When censoring is enabled, log statements marked as
  244. * "secrets" will be ignored and will have zero overhead (arguments also will
  245. * not be evaluated).
  246. */
  247. #define ZF_LOG_CENSORED 1
  248. #define ZF_LOG_UNCENSORED 0
  249. /* Censoring is configured per compilation module (.c/.cpp/.m file) by defining
  250. * ZF_LOG_DEF_CENSORING or ZF_LOG_CENSORING. ZF_LOG_CENSORING has higer priority
  251. * and when defined overrides value provided by ZF_LOG_DEF_CENSORING.
  252. *
  253. * Common practice is to define default censoring with ZF_LOG_DEF_CENSORING in
  254. * build script (e.g. Makefile, CMakeLists.txt, gyp, etc.) for the entire
  255. * project or target:
  256. *
  257. * CC_ARGS := -DZF_LOG_DEF_CENSORING=ZF_LOG_CENSORED
  258. *
  259. * And when necessary to override it with ZF_LOG_CENSORING in .c/.cpp/.m files
  260. * before including zf_log.h (consider doing it only for debug purposes and be
  261. * very careful not to push such temporary changes to source control):
  262. *
  263. * #define ZF_LOG_CENSORING ZF_LOG_UNCENSORED
  264. * #include <zf_log.h>
  265. *
  266. * If both ZF_LOG_DEF_CENSORING and ZF_LOG_CENSORING are undefined, then
  267. * ZF_LOG_CENSORED will be used for release builds (NDEBUG is defined) and
  268. * ZF_LOG_UNCENSORED otherwise (NDEBUG is not defined).
  269. */
  270. #if defined(ZF_LOG_CENSORING)
  271. #define _ZF_LOG_CENSORING ZF_LOG_CENSORING
  272. #elif defined(ZF_LOG_DEF_CENSORING)
  273. #define _ZF_LOG_CENSORING ZF_LOG_DEF_CENSORING
  274. #else
  275. #ifdef NDEBUG
  276. #define _ZF_LOG_CENSORING ZF_LOG_CENSORED
  277. #else
  278. #define _ZF_LOG_CENSORING ZF_LOG_UNCENSORED
  279. #endif
  280. #endif
  281. /* Check censoring at compile time. Evaluates to true when censoring is disabled
  282. * (i.e. when secrets will be logged). For example:
  283. *
  284. * #if ZF_LOG_SECRETS
  285. * char ssn[16];
  286. * getSocialSecurityNumber(ssn);
  287. * ZF_LOGI("Customer ssn: %s", ssn);
  288. * #endif
  289. *
  290. * See ZF_LOG_SECRET() macro for a more convenient way of guarding single log
  291. * statement.
  292. */
  293. #define ZF_LOG_SECRETS (ZF_LOG_UNCENSORED == _ZF_LOG_CENSORING)
  294. /* Static (compile-time) initialization support allows to configure logging
  295. * before entering main() function. This mostly useful in C++ where functions
  296. * and methods could be called during initialization of global objects. Those
  297. * functions and methods could record log messages too and for that reason
  298. * static initialization of logging configuration is customizable.
  299. *
  300. * Macros below allow to specify values to use for initial configuration:
  301. * - ZF_LOG_EXTERN_TAG_PREFIX - tag prefix (default: none)
  302. * - ZF_LOG_EXTERN_GLOBAL_FORMAT - global format options (default: see
  303. * ZF_LOG_MEM_WIDTH in zf_log.c)
  304. * - ZF_LOG_EXTERN_GLOBAL_OUTPUT - global output facility (default: stderr or
  305. * platform specific, see ZF_LOG_USE_XXX macros in zf_log.c)
  306. * - ZF_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL - global output log level (default: 0 -
  307. * all levals are "turned on")
  308. *
  309. * For example, in log_config.c:
  310. *
  311. * #include <zf_log.h>
  312. * ZF_LOG_DEFINE_TAG_PREFIX = "MyApp";
  313. * ZF_LOG_DEFINE_GLOBAL_FORMAT = {CUSTOM_MEM_WIDTH};
  314. * ZF_LOG_DEFINE_GLOBAL_OUTPUT = {ZF_LOG_PUT_STD, custom_output_callback, 0};
  315. * ZF_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL = ZF_LOG_INFO;
  316. *
  317. * However, to use any of those macros zf_log library must be compiled with
  318. * following macros defined:
  319. * - to use ZF_LOG_DEFINE_TAG_PREFIX define ZF_LOG_EXTERN_TAG_PREFIX
  320. * - to use ZF_LOG_DEFINE_GLOBAL_FORMAT define ZF_LOG_EXTERN_GLOBAL_FORMAT
  321. * - to use ZF_LOG_DEFINE_GLOBAL_OUTPUT define ZF_LOG_EXTERN_GLOBAL_OUTPUT
  322. * - to use ZF_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL define
  323. * ZF_LOG_EXTERN_GLOBAL_OUTPUT_LEVEL
  324. *
  325. * When zf_log library compiled with one of ZF_LOG_EXTERN_XXX macros defined,
  326. * corresponding ZF_LOG_DEFINE_XXX macro MUST be used exactly once somewhere.
  327. * Otherwise build will fail with link error (undefined symbol).
  328. */
  329. #define ZF_LOG_DEFINE_TAG_PREFIX const char *_zf_log_tag_prefix
  330. #define ZF_LOG_DEFINE_GLOBAL_FORMAT zf_log_format _zf_log_global_format
  331. #define ZF_LOG_DEFINE_GLOBAL_OUTPUT zf_log_output _zf_log_global_output
  332. #define ZF_LOG_DEFINE_GLOBAL_OUTPUT_LEVEL int _zf_log_global_output_lvl
  333. /* Pointer to global format options. Direct modification is not allowed. Use
  334. * zf_log_set_mem_width() instead. Could be used to initialize zf_log_spec
  335. * structure:
  336. *
  337. * const zf_log_output g_output = {ZF_LOG_PUT_STD, output_callback, 0};
  338. * const zf_log_spec g_spec = {ZF_LOG_GLOBAL_FORMAT, &g_output};
  339. * ZF_LOGI_AUX(&g_spec, "Hello");
  340. */
  341. #define ZF_LOG_GLOBAL_FORMAT ((const zf_log_format *)&_zf_log_global_format)
  342. /* Pointer to global output variable. Direct modification is not allowed. Use
  343. * zf_log_set_output_v() or zf_log_set_output_p() instead. Could be used to
  344. * initialize zf_log_spec structure:
  345. *
  346. * const zf_log_format g_format = {40};
  347. * const zf_log_spec g_spec = {g_format, ZF_LOG_GLOBAL_OUTPUT};
  348. * ZF_LOGI_AUX(&g_spec, "Hello");
  349. */
  350. #define ZF_LOG_GLOBAL_OUTPUT ((const zf_log_output *)&_zf_log_global_output)
  351. /* When defined, all library symbols produced by linker will be prefixed with
  352. * provided value. That allows to use zf_log library privately in another
  353. * libraries without exposing zf_log symbols in their original form (to avoid
  354. * possible conflicts with other libraries / components that also could use
  355. * zf_log for logging). Value must be without quotes, for example:
  356. *
  357. * CC_ARGS := -DZF_LOG_LIBRARY_PREFIX=my_lib_
  358. *
  359. * Note, that in this mode ZF_LOG_LIBRARY_PREFIX must be defined when building
  360. * zf_log library AND it also must be defined to the same value when building
  361. * a library that uses it. For example, consider fictional KittyHttp library
  362. * that wants to use zf_log for logging. First approach that could be taken is
  363. * to add zf_log.h and zf_log.c to the KittyHttp's source code tree directly.
  364. * In that case it will be enough just to define ZF_LOG_LIBRARY_PREFIX in
  365. * KittyHttp's build script:
  366. *
  367. * // KittyHttp/CMakeLists.txt
  368. * target_compile_definitions(KittyHttp PRIVATE
  369. * "ZF_LOG_LIBRARY_PREFIX=KittyHttp_")
  370. *
  371. * If KittyHttp doesn't want to include zf_log source code in its source tree
  372. * and wants to build zf_log as a separate library than zf_log library must be
  373. * built with ZF_LOG_LIBRARY_PREFIX defined to KittyHttp_ AND KittyHttp library
  374. * itself also needs to define ZF_LOG_LIBRARY_PREFIX to KittyHttp_. It can do
  375. * so either in its build script, as in example above, or by providing a
  376. * wrapper header that KittyHttp library will need to use instead of zf_log.h:
  377. *
  378. * // KittyHttpLogging.h
  379. * #define ZF_LOG_LIBRARY_PREFIX KittyHttp_
  380. * #include <zf_log.h>
  381. *
  382. * Regardless of the method chosen, the end result is that zf_log symbols will
  383. * be prefixed with "KittyHttp_", so if a user of KittyHttp (say DogeBrowser)
  384. * also uses zf_log for logging, they will not interferer with each other. Both
  385. * will have their own log level, output facility, format options etc.
  386. */
  387. #ifdef ZF_LOG_LIBRARY_PREFIX
  388. #define _ZF_LOG_DECOR__(prefix, name) prefix ## name
  389. #define _ZF_LOG_DECOR_(prefix, name) _ZF_LOG_DECOR__(prefix, name)
  390. #define _ZF_LOG_DECOR(name) _ZF_LOG_DECOR_(ZF_LOG_LIBRARY_PREFIX, name)
  391. #define zf_log_set_tag_prefix _ZF_LOG_DECOR(zf_log_set_tag_prefix)
  392. #define zf_log_set_mem_width _ZF_LOG_DECOR(zf_log_set_mem_width)
  393. #define zf_log_set_output_level _ZF_LOG_DECOR(zf_log_set_output_level)
  394. #define zf_log_set_output_v _ZF_LOG_DECOR(zf_log_set_output_v)
  395. #define zf_log_set_output_p _ZF_LOG_DECOR(zf_log_set_output_p)
  396. #define zf_log_out_stderr_callback _ZF_LOG_DECOR(zf_log_out_stderr_callback)
  397. #define _zf_log_tag_prefix _ZF_LOG_DECOR(_zf_log_tag_prefix)
  398. #define _zf_log_global_format _ZF_LOG_DECOR(_zf_log_global_format)
  399. #define _zf_log_global_output _ZF_LOG_DECOR(_zf_log_global_output)
  400. #define _zf_log_global_output_lvl _ZF_LOG_DECOR(_zf_log_global_output_lvl)
  401. #define _zf_log_write_d _ZF_LOG_DECOR(_zf_log_write_d)
  402. #define _zf_log_write_aux_d _ZF_LOG_DECOR(_zf_log_write_aux_d)
  403. #define _zf_log_write _ZF_LOG_DECOR(_zf_log_write)
  404. #define _zf_log_write_aux _ZF_LOG_DECOR(_zf_log_write_aux)
  405. #define _zf_log_write_mem_d _ZF_LOG_DECOR(_zf_log_write_mem_d)
  406. #define _zf_log_write_mem_aux_d _ZF_LOG_DECOR(_zf_log_write_mem_aux_d)
  407. #define _zf_log_write_mem _ZF_LOG_DECOR(_zf_log_write_mem)
  408. #define _zf_log_write_mem_aux _ZF_LOG_DECOR(_zf_log_write_mem_aux)
  409. #define _zf_log_stderr_spec _ZF_LOG_DECOR(_zf_log_stderr_spec)
  410. #endif
  411. #if defined(__printflike)
  412. #define _ZF_LOG_PRINTFLIKE(a, b) __printflike(a, b)
  413. #else
  414. #define _ZF_LOG_PRINTFLIKE(a, b)
  415. #endif
  416. #if (defined(_WIN32) || defined(_WIN64)) && !defined(__GNUC__)
  417. #define _ZF_LOG_FUNCTION __FUNCTION__
  418. #else
  419. #define _ZF_LOG_FUNCTION __func__
  420. #endif
  421. #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
  422. #define _ZF_LOG_INLINE __inline
  423. #define _ZF_LOG_IF(cond) \
  424. __pragma(warning(push)) \
  425. __pragma(warning(disable:4127)) \
  426. if(cond) \
  427. __pragma(warning(pop))
  428. #define _ZF_LOG_WHILE(cond) \
  429. __pragma(warning(push)) \
  430. __pragma(warning(disable:4127)) \
  431. while(cond) \
  432. __pragma(warning(pop))
  433. #else
  434. #define _ZF_LOG_INLINE inline
  435. #define _ZF_LOG_IF(cond) if(cond)
  436. #define _ZF_LOG_WHILE(cond) while(cond)
  437. #endif
  438. #define _ZF_LOG_NEVER _ZF_LOG_IF(0)
  439. #define _ZF_LOG_ONCE _ZF_LOG_WHILE(0)
  440. #ifdef __cplusplus
  441. extern "C" {
  442. #endif
  443. /* Set tag prefix. Prefix will be separated from the tag with dot ('.').
  444. * Use 0 or empty string to disable (default). Common use is to set it to
  445. * the process (or build target) name (e.g. to separate client and server
  446. * processes). Function will NOT copy provided prefix string, but will store the
  447. * pointer. Hence specified prefix string must remain valid. See
  448. * ZF_LOG_DEFINE_TAG_PREFIX for a way to set it before entering main() function.
  449. * See ZF_LOG_TAG for more information about tag and tag prefix.
  450. */
  451. void zf_log_set_tag_prefix(const char *const prefix);
  452. /* Set number of bytes per log line in memory (ASCII-HEX) output. Example:
  453. *
  454. * I hello.MAIN 4c6f72656d20697073756d20646f6c6f Lorem ipsum dolo
  455. * |<- w bytes ->| |<- w chars ->|
  456. *
  457. * See ZF_LOGF_MEM and ZF_LOGF_MEM_AUX for more details.
  458. */
  459. void zf_log_set_mem_width(const unsigned w);
  460. /* Set "output" log level. See ZF_LOG_LEVEL and ZF_LOG_OUTPUT_LEVEL for more
  461. * info about log levels.
  462. */
  463. void zf_log_set_output_level(const int lvl);
  464. /* Put mask is a set of flags that define what fields will be added to each
  465. * log message. Default value is ZF_LOG_PUT_STD and other flags could be used to
  466. * alter its behavior. See zf_log_set_output_v() for more details.
  467. *
  468. * Note about ZF_LOG_PUT_SRC: it will be added only in debug builds (NDEBUG is
  469. * not defined).
  470. */
  471. enum
  472. {
  473. ZF_LOG_PUT_CTX = 1 << 0, /* context (time, pid, tid, log level) */
  474. ZF_LOG_PUT_TAG = 1 << 1, /* tag (including tag prefix) */
  475. ZF_LOG_PUT_SRC = 1 << 2, /* source location (file, line, function) */
  476. ZF_LOG_PUT_MSG = 1 << 3, /* message text (formatted string) */
  477. ZF_LOG_PUT_STD = 0xffff, /* everything (default) */
  478. };
  479. typedef struct zf_log_message
  480. {
  481. int lvl; /* Log level of the message */
  482. const char *tag; /* Associated tag (without tag prefix) */
  483. char *buf; /* Buffer start */
  484. char *e; /* Buffer end (last position where EOL with 0 could be written) */
  485. char *p; /* Buffer content end (append position) */
  486. char *tag_b; /* Prefixed tag start */
  487. char *tag_e; /* Prefixed tag end (if != tag_b, points to msg separator) */
  488. char *msg_b; /* Message start (expanded format string) */
  489. }
  490. zf_log_message;
  491. /* Type of output callback function. It will be called for each log line allowed
  492. * by both "current" and "output" log levels ("enabled" and "turned on").
  493. * Callback function is allowed to modify content of the buffers pointed by the
  494. * msg, but it's not allowed to modify any of msg fields. Buffer pointed by msg
  495. * is UTF-8 encoded (no BOM mark).
  496. */
  497. typedef void (*zf_log_output_cb)(const zf_log_message *msg, void *arg);
  498. /* Format options. For more details see zf_log_set_mem_width().
  499. */
  500. typedef struct zf_log_format
  501. {
  502. unsigned mem_width; /* Bytes per line in memory (ASCII-HEX) dump */
  503. }
  504. zf_log_format;
  505. /* Output facility.
  506. */
  507. typedef struct zf_log_output
  508. {
  509. unsigned mask; /* What to put into log line buffer (see ZF_LOG_PUT_XXX) */
  510. void *arg; /* User provided output callback argument */
  511. zf_log_output_cb callback; /* Output callback function */
  512. }
  513. zf_log_output;
  514. /* Set output callback function.
  515. *
  516. * Mask allows to control what information will be added to the log line buffer
  517. * before callback function is invoked. Default mask value is ZF_LOG_PUT_STD.
  518. */
  519. void zf_log_set_output_v(const unsigned mask, void *const arg,
  520. const zf_log_output_cb callback);
  521. static _ZF_LOG_INLINE void zf_log_set_output_p(const zf_log_output *const output)
  522. {
  523. zf_log_set_output_v(output->mask, output->arg, output->callback);
  524. }
  525. /* Used with _AUX macros and allows to override global format and output
  526. * facility. Use ZF_LOG_GLOBAL_FORMAT and ZF_LOG_GLOBAL_OUTPUT for values from
  527. * global configuration. Example:
  528. *
  529. * static const zf_log_output module_output = {
  530. * ZF_LOG_PUT_STD, 0, custom_output_callback
  531. * };
  532. * static const zf_log_spec module_spec = {
  533. * ZF_LOG_GLOBAL_FORMAT, &module_output
  534. * };
  535. * ZF_LOGI_AUX(&module_spec, "Position: %ix%i", x, y);
  536. *
  537. * See ZF_LOGF_AUX and ZF_LOGF_MEM_AUX for details.
  538. */
  539. typedef struct zf_log_spec
  540. {
  541. const zf_log_format *format;
  542. const zf_log_output *output;
  543. }
  544. zf_log_spec;
  545. #ifdef __cplusplus
  546. }
  547. #endif
  548. /* Execute log statement if condition is true. Example:
  549. *
  550. * ZF_LOG_IF(1 < 2, ZF_LOGI("Log this"));
  551. * ZF_LOG_IF(1 > 2, ZF_LOGI("Don't log this"));
  552. *
  553. * Keep in mind though, that if condition can't be evaluated at compile time,
  554. * then it will be evaluated at run time. This will increase exectuable size
  555. * and can have noticeable performance overhead. Try to limit conditions to
  556. * expressions that can be evaluated at compile time.
  557. */
  558. #define ZF_LOG_IF(cond, f) do { _ZF_LOG_IF((cond)) { f; } } _ZF_LOG_ONCE
  559. /* Mark log statement as "secret". Log statements that are marked as secrets
  560. * will NOT be executed when censoring is enabled (see ZF_LOG_CENSORED).
  561. * Example:
  562. *
  563. * ZF_LOG_SECRET(ZF_LOGI("Credit card: %s", credit_card));
  564. * ZF_LOG_SECRET(ZF_LOGD_MEM(cipher, cipher_sz, "Cipher bytes:"));
  565. */
  566. #define ZF_LOG_SECRET(f) ZF_LOG_IF(ZF_LOG_SECRETS, f)
  567. /* Check "current" log level at compile time (ignoring "output" log level).
  568. * Evaluates to true when specified log level is enabled. For example:
  569. *
  570. * #if ZF_LOG_ENABLED_DEBUG
  571. * const char *const g_enum_strings[] = {
  572. * "enum_value_0", "enum_value_1", "enum_value_2"
  573. * };
  574. * #endif
  575. * // ...
  576. * #if ZF_LOG_ENABLED_DEBUG
  577. * ZF_LOGD("enum value: %s", g_enum_strings[v]);
  578. * #endif
  579. *
  580. * See ZF_LOG_LEVEL for details.
  581. */
  582. #define ZF_LOG_ENABLED(lvl) ((lvl) >= _ZF_LOG_LEVEL)
  583. #define ZF_LOG_ENABLED_VERBOSE ZF_LOG_ENABLED(ZF_LOG_VERBOSE)
  584. #define ZF_LOG_ENABLED_DEBUG ZF_LOG_ENABLED(ZF_LOG_DEBUG)
  585. #define ZF_LOG_ENABLED_INFO ZF_LOG_ENABLED(ZF_LOG_INFO)
  586. #define ZF_LOG_ENABLED_WARN ZF_LOG_ENABLED(ZF_LOG_WARN)
  587. #define ZF_LOG_ENABLED_ERROR ZF_LOG_ENABLED(ZF_LOG_ERROR)
  588. #define ZF_LOG_ENABLED_FATAL ZF_LOG_ENABLED(ZF_LOG_FATAL)
  589. /* Check "output" log level at run time (taking into account "current" log
  590. * level as well). Evaluates to true when specified log level is turned on AND
  591. * enabled. For example:
  592. *
  593. * if (ZF_LOG_ON_DEBUG)
  594. * {
  595. * char hash[65];
  596. * sha256(data_ptr, data_sz, hash);
  597. * ZF_LOGD("data: len=%u, sha256=%s", data_sz, hash);
  598. * }
  599. *
  600. * See ZF_LOG_OUTPUT_LEVEL for details.
  601. */
  602. #define ZF_LOG_ON(lvl) \
  603. (ZF_LOG_ENABLED((lvl)) && (lvl) >= _ZF_LOG_OUTPUT_LEVEL)
  604. #define ZF_LOG_ON_VERBOSE ZF_LOG_ON(ZF_LOG_VERBOSE)
  605. #define ZF_LOG_ON_DEBUG ZF_LOG_ON(ZF_LOG_DEBUG)
  606. #define ZF_LOG_ON_INFO ZF_LOG_ON(ZF_LOG_INFO)
  607. #define ZF_LOG_ON_WARN ZF_LOG_ON(ZF_LOG_WARN)
  608. #define ZF_LOG_ON_ERROR ZF_LOG_ON(ZF_LOG_ERROR)
  609. #define ZF_LOG_ON_FATAL ZF_LOG_ON(ZF_LOG_FATAL)
  610. #ifdef __cplusplus
  611. extern "C" {
  612. #endif
  613. extern const char *_zf_log_tag_prefix;
  614. extern zf_log_format _zf_log_global_format;
  615. extern zf_log_output _zf_log_global_output;
  616. extern int _zf_log_global_output_lvl;
  617. extern const zf_log_spec _zf_log_stderr_spec;
  618. void _zf_log_write_d(
  619. const char *const func, const char *const file, const unsigned line,
  620. const int lvl, const char *const tag,
  621. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(6, 7);
  622. void _zf_log_write_aux_d(
  623. const char *const func, const char *const file, const unsigned line,
  624. const zf_log_spec *const log, const int lvl, const char *const tag,
  625. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(7, 8);
  626. void _zf_log_write(
  627. const int lvl, const char *const tag,
  628. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(3, 4);
  629. void _zf_log_write_aux(
  630. const zf_log_spec *const log, const int lvl, const char *const tag,
  631. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(4, 5);
  632. void _zf_log_write_mem_d(
  633. const char *const func, const char *const file, const unsigned line,
  634. const int lvl, const char *const tag,
  635. const void *const d, const unsigned d_sz,
  636. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(8, 9);
  637. void _zf_log_write_mem_aux_d(
  638. const char *const func, const char *const file, const unsigned line,
  639. const zf_log_spec *const log, const int lvl, const char *const tag,
  640. const void *const d, const unsigned d_sz,
  641. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(9, 10);
  642. void _zf_log_write_mem(
  643. const int lvl, const char *const tag,
  644. const void *const d, const unsigned d_sz,
  645. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(5, 6);
  646. void _zf_log_write_mem_aux(
  647. const zf_log_spec *const log, const int lvl, const char *const tag,
  648. const void *const d, const unsigned d_sz,
  649. const char *const fmt, ...) _ZF_LOG_PRINTFLIKE(6, 7);
  650. #ifdef __cplusplus
  651. }
  652. #endif
  653. /* Message logging macros:
  654. * - ZF_LOGV("format string", args, ...)
  655. * - ZF_LOGD("format string", args, ...)
  656. * - ZF_LOGI("format string", args, ...)
  657. * - ZF_LOGW("format string", args, ...)
  658. * - ZF_LOGE("format string", args, ...)
  659. * - ZF_LOGF("format string", args, ...)
  660. *
  661. * Memory logging macros:
  662. * - ZF_LOGV_MEM(data_ptr, data_sz, "format string", args, ...)
  663. * - ZF_LOGD_MEM(data_ptr, data_sz, "format string", args, ...)
  664. * - ZF_LOGI_MEM(data_ptr, data_sz, "format string", args, ...)
  665. * - ZF_LOGW_MEM(data_ptr, data_sz, "format string", args, ...)
  666. * - ZF_LOGE_MEM(data_ptr, data_sz, "format string", args, ...)
  667. * - ZF_LOGF_MEM(data_ptr, data_sz, "format string", args, ...)
  668. *
  669. * Auxiliary logging macros:
  670. * - ZF_LOGV_AUX(&log_instance, "format string", args, ...)
  671. * - ZF_LOGD_AUX(&log_instance, "format string", args, ...)
  672. * - ZF_LOGI_AUX(&log_instance, "format string", args, ...)
  673. * - ZF_LOGW_AUX(&log_instance, "format string", args, ...)
  674. * - ZF_LOGE_AUX(&log_instance, "format string", args, ...)
  675. * - ZF_LOGF_AUX(&log_instance, "format string", args, ...)
  676. *
  677. * Auxiliary memory logging macros:
  678. * - ZF_LOGV_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
  679. * - ZF_LOGD_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
  680. * - ZF_LOGI_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
  681. * - ZF_LOGW_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
  682. * - ZF_LOGE_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
  683. * - ZF_LOGF_MEM_AUX(&log_instance, data_ptr, data_sz, "format string", args, ...)
  684. *
  685. * Preformatted string logging macros:
  686. * - ZF_LOGV_STR("preformatted string");
  687. * - ZF_LOGD_STR("preformatted string");
  688. * - ZF_LOGI_STR("preformatted string");
  689. * - ZF_LOGW_STR("preformatted string");
  690. * - ZF_LOGE_STR("preformatted string");
  691. * - ZF_LOGF_STR("preformatted string");
  692. *
  693. * Explicit log level and tag macros:
  694. * - ZF_LOG_WRITE(level, tag, "format string", args, ...)
  695. * - ZF_LOG_WRITE_MEM(level, tag, data_ptr, data_sz, "format string", args, ...)
  696. * - ZF_LOG_WRITE_AUX(&log_instance, level, tag, "format string", args, ...)
  697. * - ZF_LOG_WRITE_MEM_AUX(&log_instance, level, tag, data_ptr, data_sz,
  698. * "format string", args, ...)
  699. *
  700. * Format string follows printf() conventions. Both data_ptr and data_sz could
  701. * be 0. Tag can be 0 as well. Most compilers will verify that type of arguments
  702. * match format specifiers in format string.
  703. *
  704. * Library assuming UTF-8 encoding for all strings (char *), including format
  705. * string itself.
  706. */
  707. #if ZF_LOG_SRCLOC_NONE == _ZF_LOG_SRCLOC
  708. #define ZF_LOG_WRITE(lvl, tag, ...) \
  709. do { \
  710. if (ZF_LOG_ON(lvl)) \
  711. _zf_log_write(lvl, tag, __VA_ARGS__); \
  712. } _ZF_LOG_ONCE
  713. #define ZF_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
  714. do { \
  715. if (ZF_LOG_ON(lvl)) \
  716. _zf_log_write_mem(lvl, tag, d, d_sz, __VA_ARGS__); \
  717. } _ZF_LOG_ONCE
  718. #define ZF_LOG_WRITE_AUX(log, lvl, tag, ...) \
  719. do { \
  720. if (ZF_LOG_ON(lvl)) \
  721. _zf_log_write_aux(log, lvl, tag, __VA_ARGS__); \
  722. } _ZF_LOG_ONCE
  723. #define ZF_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
  724. do { \
  725. if (ZF_LOG_ON(lvl)) \
  726. _zf_log_write_mem_aux(log, lvl, tag, d, d_sz, __VA_ARGS__); \
  727. } _ZF_LOG_ONCE
  728. #else
  729. #define ZF_LOG_WRITE(lvl, tag, ...) \
  730. do { \
  731. if (ZF_LOG_ON(lvl)) \
  732. _zf_log_write_d(_ZF_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
  733. lvl, tag, __VA_ARGS__); \
  734. } _ZF_LOG_ONCE
  735. #define ZF_LOG_WRITE_MEM(lvl, tag, d, d_sz, ...) \
  736. do { \
  737. if (ZF_LOG_ON(lvl)) \
  738. _zf_log_write_mem_d(_ZF_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
  739. lvl, tag, d, d_sz, __VA_ARGS__); \
  740. } _ZF_LOG_ONCE
  741. #define ZF_LOG_WRITE_AUX(log, lvl, tag, ...) \
  742. do { \
  743. if (ZF_LOG_ON(lvl)) \
  744. _zf_log_write_aux_d(_ZF_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
  745. log, lvl, tag, __VA_ARGS__); \
  746. } _ZF_LOG_ONCE
  747. #define ZF_LOG_WRITE_MEM_AUX(log, lvl, tag, d, d_sz, ...) \
  748. do { \
  749. if (ZF_LOG_ON(lvl)) \
  750. _zf_log_write_mem_aux_d(_ZF_LOG_SRCLOC_FUNCTION, __FILE__, __LINE__, \
  751. log, lvl, tag, d, d_sz, __VA_ARGS__); \
  752. } _ZF_LOG_ONCE
  753. #endif
  754. static _ZF_LOG_INLINE void _zf_log_unused(const int dummy, ...) {(void)dummy;}
  755. #define _ZF_LOG_UNUSED(...) \
  756. do { _ZF_LOG_NEVER _zf_log_unused(0, __VA_ARGS__); } _ZF_LOG_ONCE
  757. #if ZF_LOG_ENABLED_VERBOSE
  758. #define ZF_LOGV(...) \
  759. ZF_LOG_WRITE(ZF_LOG_VERBOSE, _ZF_LOG_TAG, __VA_ARGS__)
  760. #define ZF_LOGV_AUX(log, ...) \
  761. ZF_LOG_WRITE_AUX(log, ZF_LOG_VERBOSE, _ZF_LOG_TAG, __VA_ARGS__)
  762. #define ZF_LOGV_MEM(d, d_sz, ...) \
  763. ZF_LOG_WRITE_MEM(ZF_LOG_VERBOSE, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  764. #define ZF_LOGV_MEM_AUX(log, d, d_sz, ...) \
  765. ZF_LOG_WRITE_MEM(log, ZF_LOG_VERBOSE, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  766. #else
  767. #define ZF_LOGV(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  768. #define ZF_LOGV_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  769. #define ZF_LOGV_MEM(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  770. #define ZF_LOGV_MEM_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  771. #endif
  772. #if ZF_LOG_ENABLED_DEBUG
  773. #define ZF_LOGD(...) \
  774. ZF_LOG_WRITE(ZF_LOG_DEBUG, _ZF_LOG_TAG, __VA_ARGS__)
  775. #define ZF_LOGD_AUX(log, ...) \
  776. ZF_LOG_WRITE_AUX(log, ZF_LOG_DEBUG, _ZF_LOG_TAG, __VA_ARGS__)
  777. #define ZF_LOGD_MEM(d, d_sz, ...) \
  778. ZF_LOG_WRITE_MEM(ZF_LOG_DEBUG, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  779. #define ZF_LOGD_MEM_AUX(log, d, d_sz, ...) \
  780. ZF_LOG_WRITE_MEM_AUX(log, ZF_LOG_DEBUG, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  781. #else
  782. #define ZF_LOGD(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  783. #define ZF_LOGD_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  784. #define ZF_LOGD_MEM(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  785. #define ZF_LOGD_MEM_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  786. #endif
  787. #if ZF_LOG_ENABLED_INFO
  788. #define ZF_LOGI(...) \
  789. ZF_LOG_WRITE(ZF_LOG_INFO, _ZF_LOG_TAG, __VA_ARGS__)
  790. #define ZF_LOGI_AUX(log, ...) \
  791. ZF_LOG_WRITE_AUX(log, ZF_LOG_INFO, _ZF_LOG_TAG, __VA_ARGS__)
  792. #define ZF_LOGI_MEM(d, d_sz, ...) \
  793. ZF_LOG_WRITE_MEM(ZF_LOG_INFO, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  794. #define ZF_LOGI_MEM_AUX(log, d, d_sz, ...) \
  795. ZF_LOG_WRITE_MEM_AUX(log, ZF_LOG_INFO, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  796. #else
  797. #define ZF_LOGI(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  798. #define ZF_LOGI_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  799. #define ZF_LOGI_MEM(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  800. #define ZF_LOGI_MEM_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  801. #endif
  802. #if ZF_LOG_ENABLED_WARN
  803. #define ZF_LOGW(...) \
  804. ZF_LOG_WRITE(ZF_LOG_WARN, _ZF_LOG_TAG, __VA_ARGS__)
  805. #define ZF_LOGW_AUX(log, ...) \
  806. ZF_LOG_WRITE_AUX(log, ZF_LOG_WARN, _ZF_LOG_TAG, __VA_ARGS__)
  807. #define ZF_LOGW_MEM(d, d_sz, ...) \
  808. ZF_LOG_WRITE_MEM(ZF_LOG_WARN, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  809. #define ZF_LOGW_MEM_AUX(log, d, d_sz, ...) \
  810. ZF_LOG_WRITE_MEM_AUX(log, ZF_LOG_WARN, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  811. #else
  812. #define ZF_LOGW(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  813. #define ZF_LOGW_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  814. #define ZF_LOGW_MEM(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  815. #define ZF_LOGW_MEM_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  816. #endif
  817. #if ZF_LOG_ENABLED_ERROR
  818. #define ZF_LOGE(...) \
  819. ZF_LOG_WRITE(ZF_LOG_ERROR, _ZF_LOG_TAG, __VA_ARGS__)
  820. #define ZF_LOGE_AUX(log, ...) \
  821. ZF_LOG_WRITE_AUX(log, ZF_LOG_ERROR, _ZF_LOG_TAG, __VA_ARGS__)
  822. #define ZF_LOGE_MEM(d, d_sz, ...) \
  823. ZF_LOG_WRITE_MEM(ZF_LOG_ERROR, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  824. #define ZF_LOGE_MEM_AUX(log, d, d_sz, ...) \
  825. ZF_LOG_WRITE_MEM_AUX(log, ZF_LOG_ERROR, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  826. #else
  827. #define ZF_LOGE(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  828. #define ZF_LOGE_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  829. #define ZF_LOGE_MEM(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  830. #define ZF_LOGE_MEM_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  831. #endif
  832. #if ZF_LOG_ENABLED_FATAL
  833. #define ZF_LOGF(...) \
  834. ZF_LOG_WRITE(ZF_LOG_FATAL, _ZF_LOG_TAG, __VA_ARGS__)
  835. #define ZF_LOGF_AUX(log, ...) \
  836. ZF_LOG_WRITE_AUX(log, ZF_LOG_FATAL, _ZF_LOG_TAG, __VA_ARGS__)
  837. #define ZF_LOGF_MEM(d, d_sz, ...) \
  838. ZF_LOG_WRITE_MEM(ZF_LOG_FATAL, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  839. #define ZF_LOGF_MEM_AUX(log, d, d_sz, ...) \
  840. ZF_LOG_WRITE_MEM_AUX(log, ZF_LOG_FATAL, _ZF_LOG_TAG, d, d_sz, __VA_ARGS__)
  841. #else
  842. #define ZF_LOGF(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  843. #define ZF_LOGF_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  844. #define ZF_LOGF_MEM(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  845. #define ZF_LOGF_MEM_AUX(...) _ZF_LOG_UNUSED(__VA_ARGS__)
  846. #endif
  847. #define ZF_LOGV_STR(s) ZF_LOGV("%s", (s))
  848. #define ZF_LOGD_STR(s) ZF_LOGD("%s", (s))
  849. #define ZF_LOGI_STR(s) ZF_LOGI("%s", (s))
  850. #define ZF_LOGW_STR(s) ZF_LOGW("%s", (s))
  851. #define ZF_LOGE_STR(s) ZF_LOGE("%s", (s))
  852. #define ZF_LOGF_STR(s) ZF_LOGF("%s", (s))
  853. #ifdef __cplusplus
  854. extern "C" {
  855. #endif
  856. /* Output to standard error stream. Library uses it by default, though in few
  857. * cases it could be necessary to specify it explicitly. For example, when
  858. * zf_log library is compiled with ZF_LOG_EXTERN_GLOBAL_OUTPUT, application must
  859. * define and initialize global output variable:
  860. *
  861. * ZF_LOG_DEFINE_GLOBAL_OUTPUT = {ZF_LOG_OUT_STDERR};
  862. *
  863. * Another example is when using custom output, stderr could be used as a
  864. * fallback when custom output facility failed to initialize:
  865. *
  866. * zf_log_set_output_v(ZF_LOG_OUT_STDERR);
  867. */
  868. enum { ZF_LOG_OUT_STDERR_MASK = ZF_LOG_PUT_STD };
  869. void zf_log_out_stderr_callback(const zf_log_message *const msg, void *arg);
  870. #define ZF_LOG_OUT_STDERR ZF_LOG_OUT_STDERR_MASK, 0, zf_log_out_stderr_callback
  871. /* Predefined spec for stderr. Uses global format options (ZF_LOG_GLOBAL_FORMAT)
  872. * and ZF_LOG_OUT_STDERR. Could be used to force output to stderr for a
  873. * particular message. Example:
  874. *
  875. * f = fopen("foo.log", "w");
  876. * if (!f)
  877. * ZF_LOGE_AUX(ZF_LOG_STDERR, "Failed to open log file");
  878. */
  879. #define ZF_LOG_STDERR (&_zf_log_stderr_spec)
  880. #ifdef __cplusplus
  881. }
  882. #endif
  883. #endif