aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/osmocom/core/logging.h38
-rw-r--r--src/logging.c21
-rw-r--r--tests/logging/logging_test.c18
3 files changed, 48 insertions, 29 deletions
diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h
index e51487b5..3f58ddb3 100644
--- a/include/osmocom/core/logging.h
+++ b/include/osmocom/core/logging.h
@@ -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);
diff --git a/src/logging.c b/src/logging.c
index 7db7101e..c8a16f80 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -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;
}
diff --git a/tests/logging/logging_test.c b/tests/logging/logging_test.c
index 3c8bac4b..023a5264 100644
--- a/tests/logging/logging_test.c
+++ b/tests/logging/logging_test.c
@@ -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");