logging: Remember the target we found

log_check_level and osmo_vlogp share the responsibility for the
output of a log message. Once check_level has identified the first
target that might have an output osmo_vlogp will continue from this
place.

In practice we have one (stderr/syslog) or two (stderr+VTY) log
outputs so avoiding to re-iterate is not that important but as
we have found the right place we can just use it.
This commit is contained in:
Holger Hans Peter Freyther 2015-12-21 14:45:33 +01:00
parent 87215d5bd9
commit 95d04650ab
3 changed files with 48 additions and 29 deletions

View File

@ -11,6 +11,8 @@
#include <stdarg.h>
#include <osmocom/core/linuxlist.h>
struct log_target;
/*! \brief Maximum number of logging contexts */
#define LOG_MAX_CTX 8
/*! \brief Maximum number of logging filters */
@ -18,17 +20,21 @@
#define DEBUG
#ifdef DEBUG
#define DEBUGP(ss, fmt, args...) \
do { \
if (log_check_level(ss, LOGL_DEBUG)) \
logp(ss, __FILE__, __LINE__, 0, fmt, ## args); \
struct log_target *osmo_log_tgt; \
if (log_check_level(ss, LOGL_DEBUG, &osmo_log_tgt)) \
logp(ss, __FILE__, __LINE__, 0, osmo_log_tgt, fmt, ## args); \
} while(0)
#define DEBUGPC(ss, fmt, args...) \
do { \
if (log_check_level(ss, LOGL_DEBUG)) \
logp(ss, __FILE__, __LINE__, 1, fmt, ## args); \
struct log_target *osmo_log_tgt; \
if (log_check_level(ss, LOGL_DEBUG, &osmo_log_tgt)) \
logp(ss, __FILE__, __LINE__, 1, osmo_log_tgt, fmt, ## args); \
} while(0)
#else
@ -38,9 +44,10 @@
void osmo_vlogp(int subsys, int level, const char *file, int line,
int cont, const char *format, va_list ap);
int cont, struct log_target *initial_target,
const char *format, va_list ap);
void logp(int subsys, const char *file, int line, int cont, const char *format, ...) __attribute__ ((format (printf, 5, 6)));
void logp(int subsys, const char *file, int line, int cont, struct log_target *initial_target, const char *format, ...) __attribute__ ((format (printf, 6, 7)));
/*! \brief Log a new message through the Osmocom logging framework
* \param[in] ss logging subsystem (e.g. \ref DLGLOBAL)
@ -50,8 +57,9 @@ void logp(int subsys, const char *file, int line, int cont, const char *format,
*/
#define LOGP(ss, level, fmt, args...) \
do { \
if (log_check_level(ss, level)) \
logp2(ss, level, __FILE__, __LINE__, 0, fmt, ##args); \
struct log_target *osmo_log_tgt; \
if (log_check_level(ss, level, &osmo_log_tgt)) \
logp2(ss, level, __FILE__, __LINE__, 0, osmo_log_tgt, fmt, ##args); \
} while(0)
/*! \brief Continue a log message through the Osmocom logging framework
@ -62,8 +70,9 @@ void logp(int subsys, const char *file, int line, int cont, const char *format,
*/
#define LOGPC(ss, level, fmt, args...) \
do { \
if (log_check_level(ss, level)) \
logp2(ss, level, __FILE__, __LINE__, 1, fmt, ##args); \
struct log_target *osmo_log_tgt; \
if (log_check_level(ss, level, &osmo_log_tgt)) \
logp2(ss, level, __FILE__, __LINE__, 1, osmo_log_tgt, fmt, ##args); \
} while(0)
/*! \brief different log levels */
@ -107,8 +116,6 @@ struct log_context {
void *ctx[LOG_MAX_CTX+1];
};
struct log_target;
/*! \brief Log filter function */
typedef int log_filter(const struct log_context *ctx,
struct log_target *target);
@ -211,10 +218,11 @@ struct log_target {
/* use the above macros */
void logp2(int subsys, unsigned int level, const char *file,
int line, int cont, const char *format, ...)
__attribute__ ((format (printf, 6, 7)));
int line, int cont, struct log_target *iniial_target,
const char *format, ...)
__attribute__ ((format (printf, 7, 8)));
int log_init(const struct log_info *inf, void *talloc_ctx);
int log_check_level(int subsys, unsigned int level);
int log_check_level(int subsys, unsigned int level, struct log_target **out_tar);
/* context management */
void log_reset_context(void);

View File

@ -345,13 +345,13 @@ static inline int check_log_to_target(struct log_target *tar, int subsys, int le
/*! \brief vararg version of logging function */
void osmo_vlogp(int subsys, int level, const char *file, int line,
int cont, const char *format, va_list ap)
int cont, struct log_target *ini_tar, const char *format, va_list ap)
{
struct log_target *tar;
struct log_target *tar = ini_tar;
subsys = map_subsys(subsys);
llist_for_each_entry(tar, &osmo_log_target_list, entry) {
do {
int output = 0;
va_list bp;
@ -375,27 +375,28 @@ void osmo_vlogp(int subsys, int level, const char *file, int line,
va_copy(bp, ap);
_output(tar, subsys, level, file, line, cont, format, bp);
va_end(bp);
}
} while (tar->entry.next != &osmo_log_target_list && (tar = llist_entry(tar->entry.next, typeof(*tar), entry)));
}
/*! \brief logging function used by DEBUGP() macro */
void logp(int subsys, const char *file, int line, int cont,
const char *format, ...)
struct log_target *ini_tar, const char *format, ...)
{
va_list ap;
va_start(ap, format);
osmo_vlogp(subsys, LOGL_DEBUG, file, line, cont, format, ap);
osmo_vlogp(subsys, LOGL_DEBUG, file, line, cont, ini_tar, format, ap);
va_end(ap);
}
/*! \brief logging function used by LOGP() macro */
void logp2(int subsys, unsigned int level, const char *file, int line, int cont, const char *format, ...)
void logp2(int subsys, unsigned int level, const char *file, int line, int cont,
struct log_target *ini_tar, const char *format, ...)
{
va_list ap;
va_start(ap, format);
osmo_vlogp(subsys, level, file, line, cont, format, ap);
osmo_vlogp(subsys, level, file, line, cont, ini_tar, format, ap);
va_end(ap);
}
@ -884,7 +885,7 @@ int log_init(const struct log_info *inf, void *ctx)
/*! \brief Check whether a log entry will be generated.
* \returns != 0 if a log entry might get generated by at least one target */
int log_check_level(int subsys, unsigned int level)
int log_check_level(int subsys, unsigned int level, struct log_target **out_tar)
{
struct log_target *tar;
@ -897,10 +898,12 @@ int log_check_level(int subsys, unsigned int level)
continue;
/* This might get logged (ignoring filters) */
*out_tar = tar;
return 1;
}
/* We are sure, that this will not be logged. */
*out_tar = NULL;
return 0;
}

View File

@ -68,6 +68,7 @@ const struct log_info log_info = {
int main(int argc, char **argv)
{
struct log_target *stderr_target;
struct log_target *select_target;
log_init(&log_info, NULL);
stderr_target = log_target_create_stderr();
@ -78,24 +79,31 @@ int main(int argc, char **argv)
log_parse_category_mask(stderr_target, "DRLL:DCC");
log_parse_category_mask(stderr_target, "DRLL");
DEBUGP(DCC, "You should not see this\n");
if (log_check_level(DMM, LOGL_DEBUG) != 0)
if (log_check_level(DMM, LOGL_DEBUG, &select_target) != 0)
fprintf(stderr, "log_check_level did not catch this case\n");
OSMO_ASSERT(select_target == NULL);
log_parse_category_mask(stderr_target, "DRLL:DCC");
DEBUGP(DRLL, "You should see this\n");
OSMO_ASSERT(log_check_level(DRLL, LOGL_DEBUG) != 0);
select_target = NULL;
OSMO_ASSERT(log_check_level(DRLL, LOGL_DEBUG, &select_target) != 0);
OSMO_ASSERT(select_target == stderr_target);
DEBUGP(DCC, "You should see this\n");
OSMO_ASSERT(log_check_level(DCC, LOGL_DEBUG) != 0);
select_target = NULL;
OSMO_ASSERT(log_check_level(DCC, LOGL_DEBUG, &select_target) != 0);
OSMO_ASSERT(select_target == stderr_target);
DEBUGP(DMM, "You should not see this\n");
if (log_check_level(DMM, LOGL_DEBUG) != 0)
select_target = NULL;
if (log_check_level(DMM, LOGL_DEBUG, &select_target) != 0)
fprintf(stderr, "log_check_level did not catch this case\n");
OSMO_ASSERT(select_target == NULL);
OSMO_ASSERT(filter_called == 0);
log_set_all_filter(stderr_target, 0);
DEBUGP(DRLL, "You should not see this and filter is called\n");
OSMO_ASSERT(filter_called == 1);
if (log_check_level(DRLL, LOGL_DEBUG) != 0)
if (log_check_level(DRLL, LOGL_DEBUG, &select_target) != 0)
fprintf(stderr,
"log_check_level did not catch this case (filter)\n");