aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2015-11-17 11:52:24 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2015-12-21 13:12:13 +0100
commit5fcc4f6ff75a3b3e2027ceceb6bcdaac6c9c0ba2 (patch)
tree68336d08613fd9ec1e97c99b56663c1fdaf06a0d
parent9e57a5a6974e92a2df73f9009f793c1a1f6206d9 (diff)
log: Add log_check_level function
This commit adds this predicate function which can be used to avoid the execution of code if a certain log level is not enabled. The function will only return 0 (false), if it is sure that a logging call for the same facility and level will not produce any output. This safety criterion shall ensure, that no logging output is lost due to the use of this predicate as a guard. On the other hand, even if the predicate returns != 0 (true), no logging output might get generated by a similar logging command. Note that the current implementation is not focussed on performance, which could be improved by using a lookup table instead of iterating through every target. Sponsored-by: On-Waves ehf
-rw-r--r--include/osmocom/core/logging.h1
-rw-r--r--src/logging.c39
2 files changed, 40 insertions, 0 deletions
diff --git a/include/osmocom/core/logging.h b/include/osmocom/core/logging.h
index 1c159d0b..290b33df 100644
--- a/include/osmocom/core/logging.h
+++ b/include/osmocom/core/logging.h
@@ -198,6 +198,7 @@ void logp2(int subsys, unsigned int level, const char *file,
int line, int cont, const char *format, ...)
__attribute__ ((format (printf, 6, 7)));
int log_init(const struct log_info *inf, void *talloc_ctx);
+int log_check_level(int subsys, unsigned int level);
/* context management */
void log_reset_context(void);
diff --git a/src/logging.c b/src/logging.c
index 876964ae..c7b19999 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -865,4 +865,43 @@ int log_init(const struct log_info *inf, void *ctx)
return 0;
}
+/*! \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)
+{
+ struct log_target *tar;
+
+ if (subsys < 0)
+ subsys = subsys_lib2index(subsys);
+
+ if (subsys > osmo_log_info->num_cat)
+ subsys = DLGLOBAL;
+
+ /* TODO: The following could/should be cached (update on config) */
+
+ llist_for_each_entry(tar, &osmo_log_target_list, entry) {
+ struct log_category *category;
+
+ category = &tar->categories[subsys];
+ /* subsystem is not supposed to be logged */
+ if (!category->enabled)
+ continue;
+
+ /* Check the global log level */
+ if (tar->loglevel != 0 && level < tar->loglevel)
+ continue;
+
+ /* Check the category log level */
+ if (tar->loglevel == 0 && category->loglevel != 0 &&
+ level < category->loglevel)
+ continue;
+
+ /* This might get logged (ignoring filters) */
+ return 1;
+ }
+
+ /* We are sure, that this will not be logged. */
+ return 0;
+}
+
/*! @} */