mirror of https://gerrit.osmocom.org/libosmocore
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:
parent
87215d5bd9
commit
95d04650ab
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
Loading…
Reference in New Issue