spa: implement the new topic logging for the provided loggers

Both simple log implementation now support the new topic-based
functions, and so does the journal logger too.
This commit is contained in:
Peter Hutterer 2021-09-14 14:49:03 +10:00 committed by Wim Taymans
parent 0e60e9c063
commit 59a5791d41
7 changed files with 366 additions and 27 deletions

View file

@ -43,17 +43,22 @@
#define DEFAULT_LOG_LEVEL SPA_LOG_LEVEL_INFO
#include "log-patterns.c"
struct impl {
struct spa_handle handle;
struct spa_log log;
/* if non-null, we'll additionally forward all logging to there */
struct spa_log *chain_log;
struct spa_list patterns;
};
static SPA_PRINTF_FUNC(6,0) void
impl_log_logv(void *object,
static SPA_PRINTF_FUNC(7,0) void
impl_log_logtv(void *object,
enum spa_log_level level,
const struct spa_log_topic *topic,
const char *file,
int line,
const char *func,
@ -65,12 +70,14 @@ impl_log_logv(void *object,
char file_buffer[strlen("CODE_FILE=") + strlen(file) + 1];
char message_buffer[LINE_MAX];
int priority;
size_t sz = 0;
if (impl->chain_log != NULL) {
va_list args_copy;
va_copy(args_copy, args);
spa_log_logv(impl->chain_log,
level, file, line, func, fmt, args_copy);
spa_log_logtv(impl->chain_log,
level, topic,
file, line, func, fmt, args_copy);
va_end(args_copy);
}
@ -92,13 +99,17 @@ impl_log_logv(void *object,
break;
}
if (topic)
sz = spa_scnprintf(message_buffer, sizeof(message_buffer),
"%s: ", topic->topic);
/* we'll be using the low-level journal API, which expects us to provide
* the location explicitly. line and file are to be passed as preformatted
* entries, whereas the function name is passed as-is, and converted into
* a field inside sd_journal_send_with_location(). */
snprintf(line_buffer, sizeof(line_buffer), "CODE_LINE=%d", line);
snprintf(file_buffer, sizeof(file_buffer), "CODE_FILE=%s", file);
vsnprintf(message_buffer, sizeof(message_buffer), fmt, args);
vsnprintf(message_buffer + sz, sizeof(message_buffer) - sz, fmt, args);
sd_journal_send_with_location(file_buffer, line_buffer, func,
"MESSAGE=%s", message_buffer,
@ -116,14 +127,53 @@ impl_log_log(void *object,
{
va_list args;
va_start(args, fmt);
impl_log_logv(object, level, file, line, func, fmt, args);
impl_log_logtv(object, level, NULL, file, line, func, fmt, args);
va_end(args);
}
static SPA_PRINTF_FUNC(6,0) void
impl_log_logv(void *object,
enum spa_log_level level,
const char *file,
int line,
const char *func,
const char *fmt,
va_list args)
{
impl_log_logtv(object, level, NULL, file, line, func, fmt, args);
}
static SPA_PRINTF_FUNC(7,8) void
impl_log_logt(void *object,
enum spa_log_level level,
const struct spa_log_topic *topic,
const char *file,
int line,
const char *func,
const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
impl_log_logtv(object, level, topic, file, line, func, fmt, args);
va_end(args);
}
static void
impl_log_topic_init(void *object, struct spa_log_topic *t)
{
struct impl *impl = object;
enum spa_log_level level = impl->log.level;
support_log_topic_init(&impl->patterns, level, t);
}
static const struct spa_log_methods impl_log = {
SPA_VERSION_LOG_METHODS,
SPA_VERSION_LOG_METHODS_LOGT,
.log = impl_log_log,
.logv = impl_log_logv,
.logt = impl_log_logt,
.logtv = impl_log_logtv,
.topic_init = impl_log_topic_init,
};
static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
@ -145,8 +195,13 @@ static int impl_get_interface(struct spa_handle *handle, const char *type, void
static int impl_clear(struct spa_handle *handle)
{
struct impl *this;
spa_return_val_if_fail(handle != NULL, -EINVAL);
this = (struct impl *) handle;
support_log_free_patterns(&this->patterns);
return 0;
}
@ -211,9 +266,13 @@ impl_init(const struct spa_handle_factory *factory,
&impl_log, impl);
impl->log.level = DEFAULT_LOG_LEVEL;
spa_list_init(&impl->patterns);
if (info) {
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_LEVEL)) != NULL)
impl->log.level = atoi(str);
if ((str = spa_dict_lookup(info, SPA_KEY_LOG_PATTERNS)) != NULL)
support_log_parse_patterns(&impl->patterns, str);
}
/* if our stderr goes to the journal, there's no point in logging both