aboutsummaryrefslogtreecommitdiffstats
path: root/src/logging.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@gnumonks.org>2011-03-09 13:05:08 +0100
committerHarald Welte <laforge@gnumonks.org>2011-03-19 18:33:48 -0300
commit04139f14b6197e3ec996133a945af3fa8a68fb7a (patch)
treed619d440751694cede8aee7e1c8dec6181d23aa0 /src/logging.c
parent63196de6d899d01c4e1899e3aab2e700a47a196d (diff)
vty: integration with logging framework0.1.31
The logging categories are registered by the applications, like osmo-nitb, during startup. Thus, the VTY have to provide the logging commands according to the logging categories that the application has registered. Before this patch, the VTY contained the logging categories hardcoded. Thus, any change in the logging categories by the application would not be shown by the VTY. So far, this was not a problem because all applications used the same logging categories. However, according to what Harald told me, this may be a problem in the future. This patch resolve the lack of integration between the logging framework and the VTY by generating the VTY logging commands from the logging categories registered. Since this patch changes one function of the libosmocore API, it follows another patch for the openbsc application to get in sync with the new function layout. I have reworked and renamed the functions: * log_vty_category_string() * log_vty_level_string() to provide the new ones that generate the exact output that VTY requires. This patch does not release the memory allocated by talloc_zero_size() to store the VTY strings for the commands and the description. I found no exit function that can clean up resources that were allocated.
Diffstat (limited to 'src/logging.c')
-rw-r--r--src/logging.c138
1 files changed, 115 insertions, 23 deletions
diff --git a/src/logging.c b/src/logging.c
index 876a3526..89ca6ced 100644
--- a/src/logging.c
+++ b/src/logging.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#include <ctype.h>
#ifdef HAVE_STRINGS_H
#include <strings.h>
@@ -37,13 +38,17 @@
#include <osmocore/utils.h>
#include <osmocore/logging.h>
+#include <osmocom/vty/logging.h> /* for LOGGING_STR. */
+
const struct log_info *osmo_log_info;
static struct log_context log_context;
static void *tall_log_ctx = NULL;
LLIST_HEAD(osmo_log_target_list);
-static const struct value_string loglevel_strs[] = {
+#define LOGLEVEL_DEFS 6 /* Number of loglevels.*/
+
+static const struct value_string loglevel_strs[LOGLEVEL_DEFS+1] = {
{ 0, "EVERYTHING" },
{ LOGL_DEBUG, "DEBUG" },
{ LOGL_INFO, "INFO" },
@@ -53,6 +58,17 @@ static const struct value_string loglevel_strs[] = {
{ 0, NULL },
};
+/* You have to keep this in sync with the structure loglevel_strs. */
+const char *loglevel_descriptions[LOGLEVEL_DEFS+1] = {
+ "Log simply everything",
+ "Log debug messages and higher levels",
+ "Log informational messages and higher levels",
+ "Log noticable messages and higher levels",
+ "Log error messages and higher levels",
+ "Log only fatal messages",
+ NULL,
+};
+
int log_parse_level(const char *lvl)
{
return get_string_value(loglevel_strs, lvl);
@@ -418,49 +434,125 @@ int log_target_file_reopen(struct log_target *target)
return 0;
}
-const char *log_vty_level_string(struct log_info *info)
+/* This can go into some header file so others can benefit from it. */
+#define SNPRINTF_FAILURE(ret, rem, offset, len) \
+do { \
+ len += ret; \
+ if (ret > rem) \
+ ret = rem; \
+ offset += ret; \
+ rem -= ret; \
+} while (0)
+
+/* This generates the logging command string for VTY. */
+const char *log_vty_command_string(const struct log_info *info)
{
- const struct value_string *vs;
- unsigned int len = 3; /* ()\0 */
+ int len = 0, offset = 0, ret, i, rem;
+ int size = strlen("logging level () ()") + 1;
char *str;
- for (vs = loglevel_strs; vs->value || vs->str; vs++)
- len += strlen(vs->str) + 1;
+ for (i = 0; i < info->num_cat; i++)
+ size += strlen(info->cat[i].name) + 1;
- str = talloc_zero_size(NULL, len);
+ for (i = 0; i < LOGLEVEL_DEFS; i++)
+ size += strlen(loglevel_strs[i].str) + 1;
+
+ rem = size;
+ str = talloc_zero_size(NULL, size);
if (!str)
return NULL;
- str[0] = '(';
- for (vs = loglevel_strs; vs->value || vs->str; vs++) {
- strcat(str, vs->str);
- strcat(str, "|");
- }
- str[strlen(str)-1] = ')';
+ ret = snprintf(str + offset, rem, "logging level (");
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+
+ for (i = 0; i < info->num_cat; i++) {
+ int j, name_len = strlen(info->cat[i].name)+1;
+ char name[name_len];
+ for (j = 0; j < name_len; j++)
+ name[j] = tolower(info->cat[i].name[j]);
+
+ name[name_len-1] = '\0';
+ ret = snprintf(str + offset, rem, "%s|", name+1);
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+ }
+ offset--; /* to remove the trailing | */
+ rem++;
+
+ ret = snprintf(str + offset, rem, ") (");
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+
+ for (i = 0; i < LOGLEVEL_DEFS; i++) {
+ int j, loglevel_str_len = strlen(loglevel_strs[i].str)+1;
+ char loglevel_str[loglevel_str_len];
+
+ for (j = 0; j < loglevel_str_len; j++)
+ loglevel_str[j] = tolower(loglevel_strs[i].str[j]);
+
+ loglevel_str[loglevel_str_len-1] = '\0';
+ ret = snprintf(str + offset, rem, "%s|", loglevel_str);
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+ }
+ offset--; /* to remove the trailing | */
+ rem++;
+
+ ret = snprintf(str + offset, rem, ")");
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+err:
return str;
}
-const char *log_vty_category_string(struct log_info *info)
+/* This generates the logging command description for VTY. */
+const char *log_vty_command_description(const struct log_info *info)
{
- unsigned int len = 3; /* "()\0" */
- unsigned int i;
char *str;
+ int i, ret, len = 0, offset = 0, rem;
+ unsigned int size =
+ strlen(LOGGING_STR
+ "Set the log level for a specified category\n") + 1;
for (i = 0; i < info->num_cat; i++)
- len += strlen(info->cat[i].name) + 1;
+ size += strlen(info->cat[i].description) + 1;
- str = talloc_zero_size(NULL, len);
+ for (i = 0; i < LOGLEVEL_DEFS; i++)
+ size += strlen(loglevel_descriptions[i]) + 1;
+
+ rem = size;
+ str = talloc_zero_size(NULL, size);
if (!str)
return NULL;
- str[0] = '(';
+ ret = snprintf(str + offset, rem, LOGGING_STR
+ "Set the log level for a specified category\n");
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+
for (i = 0; i < info->num_cat; i++) {
- strcat(str, info->cat[i].name+1);
- strcat(str, "|");
+ ret = snprintf(str + offset, rem, "%s\n",
+ info->cat[i].description);
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
}
- str[strlen(str)-1] = ')';
-
+ for (i = 0; i < LOGLEVEL_DEFS; i++) {
+ ret = snprintf(str + offset, rem, "%s\n",
+ loglevel_descriptions[i]);
+ if (ret < 0)
+ goto err;
+ SNPRINTF_FAILURE(ret, rem, offset, len);
+ }
+err:
return str;
}