aboutsummaryrefslogtreecommitdiffstats
path: root/serd
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2018-11-26 22:14:39 +0100
committerDavid Robillard <d@drobilla.net>2020-06-21 18:12:04 +0200
commit73677f256510d97ff8a8daa1665fb120798975c5 (patch)
tree420e4cca6129825feca1cf49ead53b4bf62614d8 /serd
parent518e83b6d32683b44963437ae315a09152f593ae (diff)
downloadserd-73677f256510d97ff8a8daa1665fb120798975c5.tar.gz
serd-73677f256510d97ff8a8daa1665fb120798975c5.tar.bz2
serd-73677f256510d97ff8a8daa1665fb120798975c5.zip
Add extensible logging API
Diffstat (limited to 'serd')
-rw-r--r--serd/serd.h125
1 files changed, 102 insertions, 23 deletions
diff --git a/serd/serd.h b/serd/serd.h
index 86b738d9..5bda9fd0 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" {
#endif
@@ -191,14 +197,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
@@ -754,15 +752,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.
@@ -839,16 +828,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)
+ SerdLogLevel level; ///< Log level
+ unsigned n_fields; ///< Number of entries in `fields`
+ const SerdLogField* fields; ///< Extra log fields
+ const char* fmt; ///< Format string (printf style)
+ va_list* args; ///< Arguments corresponding to fmt
+} 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,
+ unsigned 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,
+ unsigned n_fields,
+ const SerdLogField* fields,
+ const char* fmt,
+ ...);
/**
@}