[PATCH 2/2] logging: Remember the target we found

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Holger Hans Peter Freyther holger at freyther.de
Mon Dec 21 14:39:40 UTC 2015


From: Holger Hans Peter Freyther <holger at moiji-mobile.com>

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.
---
 include/osmocom/core/logging.h | 38 +++++++++++++++++++++++---------------
 src/logging.c                  | 21 ++++++++++++---------
 tests/logging/logging_test.c   | 18 +++++++++++++-----
 3 files changed, 48 insertions(+), 29 deletions(-)

diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h
index e51487b..3f58ddb 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 7db7101..c8a16f8 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 3c8bac4..023a526 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");
 
-- 
2.6.3




More information about the OpenBSC mailing list