log: abstract the auxiliary information into a log message context

This makes the logger API both simpler and more future-proof since we
can easily shove extra information into the context now.
This commit is contained in:
Peter Hutterer 2022-08-03 10:09:59 +10:00
parent 37467881e6
commit f7dc4af6e8
5 changed files with 119 additions and 29 deletions

View file

@ -32,11 +32,24 @@
#include "util-strings.h"
#include "libei-private.h"
struct ei_log_context {
const char *file;
const char *func;
int line;
};
_public_
OBJECT_IMPLEMENT_GETTER(ei_log_context, file, const char *);
_public_
OBJECT_IMPLEMENT_GETTER(ei_log_context, func, const char *);
_public_
OBJECT_IMPLEMENT_GETTER(ei_log_context, line, unsigned int);
static void
ei_default_log_handler(struct ei *ei,
enum ei_log_priority priority,
const char *file, int lineno, const char *func,
const char *message)
enum ei_log_priority priority,
const char *message,
struct ei_log_context *ctx)
{
struct lut {
const char *color;
@ -129,7 +142,12 @@ ei_log_msg_va(struct ei *ei,
return;
_cleanup_free_ char *message = xvasprintf(format, ap);
ei->log.handler(ei, priority, file, lineno, func, message);
struct ei_log_context ctx = {
.file = file,
.line = lineno,
.func = func,
};
ei->log.handler(ei, priority, message, &ctx);
}
#ifdef _enable_tests_
@ -142,14 +160,19 @@ struct log_handler_check {
static void
test_loghandler(struct ei *ei,
enum ei_log_priority priority,
const char *file, int lineno, const char *func,
const char *message)
enum ei_log_priority priority,
const char *message,
struct ei_log_context *ctx)
{
struct log_handler_check *check = ei_get_user_data(ei);
munit_assert_int(priority, >=, check->min_priority);
munit_assert_string_equal(message, check->expected_message);
/* Second arg is the line number, if this code ever moves further up,
* this test may fail */
munit_assert_int(ei_log_context_get_line(ctx), >, 170);
munit_assert_true(strendswith(ei_log_context_get_file(ctx), "libei-log.c"));
munit_assert_string_equal(ei_log_context_get_func(ctx), "test_log_handler");
}
MUNIT_TEST(test_log_handler)

View file

@ -412,22 +412,45 @@ enum ei_log_priority {
EI_LOG_PRIORITY_ERROR = 40,
};
struct ei_log_context;
/**
* @return the line number (``__LINE__``) for a given log message context.
*/
unsigned int
ei_log_context_get_line(struct ei_log_context *ctx);
/**
* @return the file name (``__FILE__``) for a given log message context.
*/
const char *
ei_log_context_get_file(struct ei_log_context *ctx);
/**
* @return the function name (``__func__``) for a given log message context.
*/
const char *
ei_log_context_get_func(struct ei_log_context *ctx);
/**
* The log handler for library logging. This handler is only called for
* messages with a log level equal or greater than than the one set in
* ei_log_set_priority().
*
* The context passed to this function contains auxilary information about
* this log message such as the line number, file name and function name
* this message occured in. The log context is valid only within the current
* invocation of the log handler.
*
* @param ei The EI context
* @param priority The log priority
* @param file The filename where this log message was triggered
* @param lineno The line number in @a file where this log message was triggered
* @param func The function name where this log message was triggered
* @param message The log message as a null-terminated string
* @param context A log message context for this message
*/
typedef void (*ei_log_handler)(struct ei *ei,
enum ei_log_priority priority,
const char *file, int lineno, const char *func,
const char *message);
const char *message,
struct ei_log_context *context);
/**
* Change the log handler for this context. If the log handler is NULL, the
* built-in default log function is used.

View file

@ -29,14 +29,28 @@
#include "util-macros.h"
#include "util-color.h"
#include "util-object.h"
#include "util-strings.h"
#include "libeis-private.h"
struct eis_log_context {
const char *file;
const char *func;
int line;
};
_public_
OBJECT_IMPLEMENT_GETTER(eis_log_context, file, const char *);
_public_
OBJECT_IMPLEMENT_GETTER(eis_log_context, func, const char *);
_public_
OBJECT_IMPLEMENT_GETTER(eis_log_context, line, unsigned int);
static void
eis_default_log_handler(struct eis *eis,
enum eis_log_priority priority,
const char *file, int lineno, const char *func,
const char *message)
enum eis_log_priority priority,
const char *message,
struct eis_log_context *ctx)
{
struct lut {
const char *color;
@ -129,7 +143,12 @@ eis_log_msg_va(struct eis *eis,
return;
_cleanup_free_ char *message = xvasprintf(format, ap);
eis->log.handler(eis, priority, file, lineno, func, message);
struct eis_log_context ctx = {
.file = file,
.line = lineno,
.func = func,
};
eis->log.handler(eis, priority, message, &ctx);
}
#ifdef _enable_tests_
@ -142,14 +161,20 @@ struct log_handler_check {
static void
test_loghandler(struct eis *eis,
enum eis_log_priority priority,
const char *file, int lineno, const char *func,
const char *message)
enum eis_log_priority priority,
const char *message,
struct eis_log_context *ctx)
{
struct log_handler_check *check = eis_get_user_data(eis);
munit_assert_int(priority, >=, check->min_priority);
munit_assert_string_equal(message, check->expected_message);
munit_assert_ptr_not_null(ctx);
/* Second arg is the line number, if this code ever moves further up,
* this test may fail */
munit_assert_int(eis_log_context_get_line(ctx), >, 170);
munit_assert_true(strendswith(eis_log_context_get_file(ctx), "libeis-log.c"));
munit_assert_string_equal(eis_log_context_get_func(ctx), "test_log_handler");
}
MUNIT_TEST(test_log_handler)

View file

@ -283,6 +283,26 @@ enum eis_log_priority {
EIS_LOG_PRIORITY_ERROR = 40,
};
struct eis_log_context;
/**
* @return the line number (``__LINE__``) for a given log message context.
*/
unsigned int
eis_log_context_get_line(struct eis_log_context *ctx);
/**
* @return the file name (``__FILE__``) for a given log message context.
*/
const char *
eis_log_context_get_file(struct eis_log_context *ctx);
/**
* @return the function name (``__func__``) for a given log message context.
*/
const char *
eis_log_context_get_func(struct eis_log_context *ctx);
/**
* The log handler for library logging. This handler is only called for
* messages with a log level equal or greater than than the one set in
@ -290,15 +310,13 @@ enum eis_log_priority {
*
* @param eis The EIs context
* @param priority The log priority
* @param file The filename where this log message was triggered
* @param lineno The line number in @a file where this log message was triggered
* @param func The function name where this log message was triggered
* @param message The log message as a null-terminated string
* @param context A log message context for this message
*/
typedef void (*eis_log_handler)(struct eis *eis,
enum eis_log_priority priority,
const char *file, int lineno, const char *func,
const char *message);
const char *message,
struct eis_log_context *ctx);
/**
* Change the log handler for this context. If the log handler is NULL, the
* built-in default log function is used.

View file

@ -247,11 +247,12 @@ peck_eis_now(struct peck *peck)
return peck->now;
}
static void
peck_ei_log_handler(struct ei *ei,
enum ei_log_priority priority,
const char *file, int lineno, const char *func,
const char *message)
const char *message,
struct ei_log_context *ctx)
{
bool use_color = true;
run_only_once {
@ -276,9 +277,9 @@ peck_ei_log_handler(struct ei *ei,
static void
peck_eis_log_handler(struct eis *eis,
enum eis_log_priority priority,
const char *file, int lineno, const char *func,
const char *message)
enum eis_log_priority priority,
const char *message,
struct eis_log_context *ctx)
{
bool use_color = true;
run_only_once {