mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
reworked new logging facilities and added a unit test for it
This commit is contained in:
parent
0b06a77c15
commit
aa62c8af99
3 changed files with 126 additions and 46 deletions
|
@ -35,23 +35,27 @@ enum log_facilities {
|
|||
LOG_CONFIG = (1L << 10),
|
||||
LOG_HOOK = (1L << 11),
|
||||
LOG_PATH = (1L << 12),
|
||||
LOG_MEM = (1L << 13),
|
||||
LOG_WEB = (1L << 14),
|
||||
LOG_API = (1L << 15),
|
||||
LOG_LOG = (1L << 16),
|
||||
LOG_KERNEL = (1L << 17),
|
||||
LOG_NODE = (1L << 13),
|
||||
LOG_MEM = (1L << 14),
|
||||
LOG_WEB = (1L << 15),
|
||||
LOG_API = (1L << 16),
|
||||
LOG_LOG = (1L << 17),
|
||||
LOG_VFIO = (1L << 18),
|
||||
LOG_PCI = (1L << 19),
|
||||
LOG_XIL = (1L << 20),
|
||||
|
||||
/* Node-types */
|
||||
LOG_SOCKET = (1L << 32),
|
||||
LOG_FILE = (1L << 33),
|
||||
LOG_FPGA = (1L << 34),
|
||||
LOG_NGSI = (1L << 35),
|
||||
LOG_WEBSOCKET = (1L << 36),
|
||||
LOG_OPAL = (1L << 37),
|
||||
LOG_SOCKET = (1L << 21),
|
||||
LOG_FILE = (1L << 22),
|
||||
LOG_FPGA = (1L << 23),
|
||||
LOG_NGSI = (1L << 24),
|
||||
LOG_WEBSOCKET = (1L << 25),
|
||||
LOG_OPAL = (1L << 26),
|
||||
|
||||
/* Classes */
|
||||
LOG_NODE = (0xFFL << 32),
|
||||
LOG_ALL = ~0xFF
|
||||
LOG_NODES = LOG_NODE | LOG_SOCKET | LOG_FILE | LOG_FPGA | LOG_NGSI | LOG_WEBSOCKET | LOG_OPAL,
|
||||
LOG_KERNEL = LOG_VFIO | LOG_PCI,
|
||||
LOG_ALL = ~0xFF
|
||||
};
|
||||
|
||||
struct log {
|
||||
|
@ -104,8 +108,6 @@ int log_set_facility_expression(struct log *l, const char *expression);
|
|||
/** Parse logging configuration. */
|
||||
int log_parse(struct log *l, config_setting_t *cfg);
|
||||
|
||||
int log_lookup_facility(const char *facility_name);
|
||||
|
||||
/** Logs variadic messages to stdout.
|
||||
*
|
||||
* @param lvl The log level
|
||||
|
|
90
lib/log.c
90
lib/log.c
|
@ -5,6 +5,7 @@
|
|||
*********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
|
@ -31,9 +32,14 @@ static const char *facilities_strs[] = {
|
|||
"config", /* LOG_CONFIG */
|
||||
"hook", /* LOG_HOOK */
|
||||
"path", /* LOG_PATH */
|
||||
"node", /* LOG_NODE */
|
||||
"mem", /* LOG_MEM */
|
||||
"web", /* LOG_WEB */
|
||||
"api", /* LOG_API */
|
||||
"log", /* LOG_LOG */
|
||||
"vfio", /* LOG_VFIO */
|
||||
"pci", /* LOG_PCI */
|
||||
"xil", /* LOG_XIL */
|
||||
|
||||
/* Node-types */
|
||||
"socket", /* LOG_SOCKET */
|
||||
|
@ -41,7 +47,7 @@ static const char *facilities_strs[] = {
|
|||
"fpga", /* LOG_FPGA */
|
||||
"ngsi", /* LOG_NGSI */
|
||||
"websocket", /* LOG_WEBSOCKET */
|
||||
"opal" /* LOG_OPAL */
|
||||
"opal", /* LOG_OPAL */
|
||||
};
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
@ -63,41 +69,49 @@ void log_outdent(int *old)
|
|||
|
||||
int log_set_facility_expression(struct log *l, const char *expression)
|
||||
{
|
||||
char *copy, *facility_str;
|
||||
bool negate;
|
||||
char *copy, *token;
|
||||
long mask = 0, facilities = 0;
|
||||
|
||||
enum {
|
||||
NORMAL,
|
||||
NEGATE
|
||||
} mode;
|
||||
|
||||
if (strlen(expression) <= 0)
|
||||
return -1;
|
||||
|
||||
if (expression[0] == '!') {
|
||||
mode = NEGATE;
|
||||
l->facilities = ~0xFF;
|
||||
}
|
||||
else {
|
||||
mode = NORMAL;
|
||||
l->facilities = 0;
|
||||
}
|
||||
|
||||
copy = strdup(expression);
|
||||
facility_str = strtok(copy, ",");
|
||||
token = strtok(copy, ",");
|
||||
|
||||
while (facility_str != NULL) {
|
||||
for (int i = 0; i < ARRAY_LEN(facilities_strs); i++) {
|
||||
if (strcmp(facilities_strs[i], facility_str)) {
|
||||
switch (mode) {
|
||||
case NORMAL: l->facilities |= (1 << (i+8));
|
||||
case NEGATE: l->facilities &= ~(1 << (i+8));
|
||||
while (token != NULL) {
|
||||
if (token[0] == '!') {
|
||||
token++;
|
||||
negate = true;
|
||||
}
|
||||
else
|
||||
negate = false;
|
||||
|
||||
/* Check for some classes */
|
||||
if (!strcmp(token, "all"))
|
||||
mask = LOG_ALL;
|
||||
else if (!strcmp(token, "nodes"))
|
||||
mask = LOG_NODES;
|
||||
else if (!strcmp(token, "kernel"))
|
||||
mask = LOG_KERNEL;
|
||||
else {
|
||||
for (int ind = 0; ind < ARRAY_LEN(facilities_strs); ind++) {
|
||||
if (!strcmp(token, facilities_strs[ind])) {
|
||||
mask = (1 << (ind+8));
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
|
||||
error("Invalid log class '%s'", token);
|
||||
}
|
||||
|
||||
facility_str = strtok(NULL, ",");
|
||||
|
||||
found: if (negate)
|
||||
facilities &= ~mask;
|
||||
else
|
||||
facilities |= mask;
|
||||
|
||||
token = strtok(NULL, ",");
|
||||
}
|
||||
|
||||
l->facilities = facilities;
|
||||
|
||||
free(copy);
|
||||
|
||||
return l->facilities;
|
||||
|
@ -112,7 +126,7 @@ int log_init(struct log *l, int level, long facilitites)
|
|||
/* Register this log instance globally */
|
||||
log = l;
|
||||
|
||||
debug(LOG_LOG, "Log sub-system intialized: level=%d, faciltities=%#lx", level, facilitites);
|
||||
debug(LOG_LOG | 5, "Log sub-system intialized: level=%d, faciltities=%#lx", level, facilitites);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,11 +185,11 @@ int log_parse(struct log *l, config_setting_t *cfg)
|
|||
const char *facilities;
|
||||
|
||||
if (!config_setting_is_group(cfg))
|
||||
cerror(cfg, "Setting 'logging' must be a group.");
|
||||
cerror(cfg, "Setting 'log' must be a group.");
|
||||
|
||||
config_setting_lookup_int(cfg, "level", &l->level);
|
||||
|
||||
if (config_setting_lookup_string(cfg, "facilties", &facilities))
|
||||
if (config_setting_lookup_string(cfg, "facilities", &facilities))
|
||||
log_set_facility_expression(l, facilities);
|
||||
|
||||
return 0;
|
||||
|
@ -195,6 +209,8 @@ void debug(long class, const char *fmt, ...)
|
|||
|
||||
int lvl = class & 0xFF;
|
||||
int fac = class & ~0xFF;
|
||||
|
||||
assert(log);
|
||||
|
||||
if (((fac == 0) || (fac & log->facilities)) && (lvl <= log->level)) {
|
||||
va_start(ap, fmt);
|
||||
|
@ -206,6 +222,8 @@ void debug(long class, const char *fmt, ...)
|
|||
void info(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
assert(log);
|
||||
|
||||
va_start(ap, fmt);
|
||||
log_vprint(log, LOG_LVL_INFO, fmt, ap);
|
||||
|
@ -215,6 +233,8 @@ void info(const char *fmt, ...)
|
|||
void warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
assert(log);
|
||||
|
||||
va_start(ap, fmt);
|
||||
log_vprint(log, LOG_LVL_WARN, fmt, ap);
|
||||
|
@ -225,6 +245,8 @@ void stats(const char *fmt, ...)
|
|||
{
|
||||
va_list ap;
|
||||
|
||||
assert(log);
|
||||
|
||||
va_start(ap, fmt);
|
||||
log_vprint(log, LOG_LVL_STATS, fmt, ap);
|
||||
va_end(ap);
|
||||
|
@ -233,6 +255,8 @@ void stats(const char *fmt, ...)
|
|||
void error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
assert(log);
|
||||
|
||||
va_start(ap, fmt);
|
||||
log_vprint(log, LOG_LVL_ERROR, fmt, ap);
|
||||
|
@ -246,6 +270,8 @@ void serror(const char *fmt, ...)
|
|||
va_list ap;
|
||||
char *buf = NULL;
|
||||
|
||||
assert(log);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
@ -261,6 +287,8 @@ void cerror(config_setting_t *cfg, const char *fmt, ...)
|
|||
va_list ap;
|
||||
char *buf = NULL;
|
||||
|
||||
assert(log);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vstrcatf(&buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
|
50
tests/log.c
Normal file
50
tests/log.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/** Unit tests for log functions
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <criterion/criterion.h>
|
||||
#include <criterion/parameterized.h>
|
||||
|
||||
#include "log.h"
|
||||
|
||||
struct param {
|
||||
char *expression;
|
||||
long expected;
|
||||
};
|
||||
|
||||
static struct log l;
|
||||
|
||||
static void init()
|
||||
{
|
||||
log_init(&l, V, LOG_ALL);
|
||||
}
|
||||
|
||||
static void fini()
|
||||
{
|
||||
log_destroy(&l);
|
||||
}
|
||||
|
||||
ParameterizedTestParameters(log, facility_expression)
|
||||
{
|
||||
static struct param params[] = {
|
||||
{ "all,!pool", LOG_ALL & ~LOG_POOL },
|
||||
{ "pool,!pool", LOG_POOL & ~LOG_POOL },
|
||||
{ "pool,nodes,!socket", (LOG_POOL | LOG_NODES) & ~LOG_SOCKET },
|
||||
{ "kernel", LOG_KERNEL },
|
||||
{ "ngsi", LOG_NGSI },
|
||||
{ "all", LOG_ALL },
|
||||
{ "!all", 0 },
|
||||
{ "", 0 }
|
||||
};
|
||||
|
||||
return cr_make_param_array(struct param, params, ARRAY_LEN(params));
|
||||
}
|
||||
|
||||
ParameterizedTest(struct param *p, log, facility_expression, .init = init, .fini = fini)
|
||||
{
|
||||
log_set_facility_expression(&l, p->expression);
|
||||
|
||||
cr_assert_eq(l.facilities, p->expected, "log.faciltities is %#lx not %#lx", l.facilities, p->expected);
|
||||
}
|
Loading…
Add table
Reference in a new issue