diff options
author | David Robillard <d@drobilla.net> | 2018-11-26 22:14:39 +0100 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2020-10-27 13:13:58 +0100 |
commit | a08759985ce25cda9b340a85eef30f572a8ceacc (patch) | |
tree | ec3f979605792b69c4c2fc7895f5dc917af39e7e /serd | |
parent | 704305ddadae5e8737cf775bcc7fb1db3e91a1ce (diff) | |
download | serd-a08759985ce25cda9b340a85eef30f572a8ceacc.tar.gz serd-a08759985ce25cda9b340a85eef30f572a8ceacc.tar.bz2 serd-a08759985ce25cda9b340a85eef30f572a8ceacc.zip |
Add extensible logging API
Diffstat (limited to 'serd')
-rw-r--r-- | serd/serd.h | 125 |
1 files changed, 102 insertions, 23 deletions
diff --git a/serd/serd.h b/serd/serd.h index fd7d77a4..7197f2c8 100644 --- a/serd/serd.h +++ b/serd/serd.h @@ -41,6 +41,12 @@ # define SERD_API #endif +#if defined(__GNUC__) +# define SERD_LOG_FUNC(fmt, arg1) __attribute__((format(printf, fmt, arg1))) +#else +# define SERD_LOG_FUNC(fmt, arg1) +#endif + #ifdef __cplusplus extern "C" { # if defined(__GNUC__) @@ -195,14 +201,6 @@ typedef struct { size_t len; ///< Size of buffer in bytes } SerdBuffer; -/// An error description -typedef struct { - SerdStatus status; /**< Error code */ - const SerdCursor* cursor; /**< Origin of error, or NULL */ - const char* fmt; /**< Message format string (printf style) */ - va_list* args; /**< Arguments for fmt */ -} SerdError; - /** A parsed URI @@ -760,15 +758,6 @@ serd_node_compare(const SerdNode* a, const SerdNode* b); */ /** - Sink (callback) for errors. - - @param handle Handle for user data. - @param error Error description. -*/ -typedef SerdStatus (*SerdErrorSink)(void* handle, - const SerdError* error); - -/** Sink (callback) for base URI changes Called whenever the base URI of the serialisation changes. @@ -845,16 +834,106 @@ const SerdNode* serd_world_get_blank(SerdWorld* world); /** - Set a function to be called when errors occur. + @} + @name Logging + @{ +*/ + +/// Log message level, compatible with syslog +typedef enum { + SERD_LOG_LEVEL_EMERG, ///< Emergency, system is unusable + SERD_LOG_LEVEL_ALERT, ///< Action must be taken immediately + SERD_LOG_LEVEL_CRIT, ///< Critical condition + SERD_LOG_LEVEL_ERR, ///< Error + SERD_LOG_LEVEL_WARNING, ///< Warning + SERD_LOG_LEVEL_NOTICE, ///< Normal but significant condition + SERD_LOG_LEVEL_INFO, ///< Informational message + SERD_LOG_LEVEL_DEBUG ///< Debug message +} SerdLogLevel; + +/** + A structured log field. + + This can be used to pass additional information along with log messages. + Syslog-compatible keys should be used where possible, otherwise, keys should + be namespaced to prevent clashes. + + Serd itself uses the following keys: + - ERRNO + - SERD_COL + - SERD_FILE + - SERD_LINE + - SERD_STATUS +*/ +typedef struct { + const char* key; ///< Field name + const char* value; ///< Field value +} SerdLogField; + +/** + A log entry (message). - The `error_sink` will be called with `handle` as its first argument. If - no error function is set, errors are printed to stderr. + This is the description of a log entry which is passed to log functions. + It is only valid in the stack frame it appears in, and may not be copied. +*/ +typedef struct { + const char* domain; ///< Message domain (library or program name) + const SerdLogField* fields; ///< Extra log fields + const char* fmt; ///< Format string (printf style) + va_list* args; ///< Arguments corresponding to fmt + SerdLogLevel level; ///< Log level + size_t n_fields; ///< Number of entries in `fields` +} SerdLogEntry; + +/** + Sink function for log messages. + + @param handle Handle for user data. + @param entry Pointer to log entry description. +*/ +typedef SerdStatus (*SerdLogFunc)(void* handle, const SerdLogEntry* entry); + +/// A SerdLogFunc that does nothing, for suppressing log output +SERD_API SerdStatus +serd_quiet_error_func(void* handle, const SerdLogEntry* entry); + +/// Return the value of the log field named `key`, or NULL if none exists +SERD_API const char* +serd_log_entry_get_field(const SerdLogEntry* entry, const char* key); + +/** + Set a function to be called with log messages (typically errors). + + The `log_func` will be called with `handle` as its first argument. If + no function is set, messages are printed to stderr. */ SERD_API void -serd_world_set_error_sink(SerdWorld* world, - SerdErrorSink error_sink, - void* handle); +serd_world_set_log_func(SerdWorld* world, SerdLogFunc log_func, void* handle); + +/// Write a message to the log +SERD_API +SERD_LOG_FUNC(6, 0) +SerdStatus +serd_world_vlogf(const SerdWorld* world, + const char* domain, + SerdLogLevel level, + size_t n_fields, + const SerdLogField* fields, + const char* fmt, + va_list args); + +/// Write a message to the log +SERD_API +SERD_LOG_FUNC(6, 7) +SerdStatus +serd_world_logf(const SerdWorld* world, + const char* domain, + SerdLogLevel level, + size_t n_fields, + const SerdLogField* fields, + const char* fmt, + ...); /** @} |