Added CLICON_LOG_DESTINATION and CLICON_LOG_FILE for al applications
This commit is contained in:
parent
26062d7003
commit
0234ed94bc
22 changed files with 498 additions and 163 deletions
|
|
@ -29,7 +29,9 @@ Expected: June 2024
|
|||
* CLI support for multiple inline commands separated by semi-colon
|
||||
* New `clixon-config@2024-04-01.yang` revision
|
||||
* Added options:
|
||||
- `CLICON_DEBUG`: Debug flags, partly implemented.
|
||||
- `CLICON_LOG_DESTINATION`: Default log destination
|
||||
- `CLICON_LOG_FILE`: Which file to log to if file logging
|
||||
- `CLICON_DEBUG`: Debug flags
|
||||
- `CLICON_YANG_SCHEMA_MOUNT_SHARE`: Share same YANGs of several moint-points
|
||||
- `CLICON_SOCK_PRIO`: Enable socket event priority
|
||||
- `CLICON_XMLDB_MULTI`: Split datastore into multiple sub files
|
||||
|
|
|
|||
|
|
@ -537,6 +537,7 @@ main(int argc,
|
|||
int config_dump;
|
||||
enum format_enum config_dump_format = FORMAT_XML;
|
||||
int print_version = 0;
|
||||
int32_t d;
|
||||
|
||||
/* Initiate CLICON handle */
|
||||
if ((h = backend_handle_init()) == NULL)
|
||||
|
|
@ -572,16 +573,15 @@ main(int argc,
|
|||
cligen_output(stdout, "Clixon version: %s\n", CLIXON_GITHASH);
|
||||
print_version++; /* plugins may also print versions w ca-version callback */
|
||||
break;
|
||||
case 'D' : { /* debug */
|
||||
int d = 0;
|
||||
/* Try first symbolic, then numeric match */
|
||||
case 'D' : /* debug */
|
||||
/* Try first symbolic, then numeric match
|
||||
* Cant use yang_bits_map, too early in bootstrap, there is no yang */
|
||||
if ((d = clixon_debug_str2key(optarg)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
sscanf(optarg, "%u", &d) != 1){
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
dbg |= d;
|
||||
break;
|
||||
}
|
||||
case 'f': /* config file */
|
||||
if (!strlen(optarg))
|
||||
usage(h, argv[0]);
|
||||
|
|
@ -592,13 +592,18 @@ main(int argc,
|
|||
usage(h, argv[0]);
|
||||
clicon_option_str_set(h, "CLICON_CONFIGDIR", optarg);
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o */
|
||||
if ((logdst = clixon_log_opt(optarg[0])) < 0)
|
||||
usage(h, argv[0]);
|
||||
if (logdst == CLIXON_LOG_FILE &&
|
||||
strlen(optarg)>1 &&
|
||||
case 'l': /* Log destination: s|e|o|f<file> */
|
||||
if ((d = clixon_logdst_str2key(optarg)) < 0){
|
||||
if (optarg[0] == 'f'){ /* Check for special -lf<file> syntax */
|
||||
d = CLIXON_LOG_FILE;
|
||||
if (strlen(optarg) > 1 &&
|
||||
clixon_log_file(optarg+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
logdst = d;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
|
|
@ -618,7 +623,9 @@ main(int argc,
|
|||
usage(h, argv[0]);
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read debug and log options from config file if not given by command-line */
|
||||
if (clixon_options_main_helper(h, dbg, logdst, __PROGRAM__) < 0)
|
||||
goto done;
|
||||
/* Initialize plugin module by creating a handle holding plugin and callback lists */
|
||||
if (clixon_plugin_module_init(h) < 0)
|
||||
goto done;
|
||||
|
|
|
|||
|
|
@ -562,7 +562,7 @@ main(int argc,
|
|||
clixon_handle h;
|
||||
int logclisyntax = 0;
|
||||
int help = 0;
|
||||
int logdst = CLIXON_LOG_STDERR;
|
||||
uint32_t logdst = 0;
|
||||
char *restarg = NULL; /* what remains after options */
|
||||
yang_stmt *yspec;
|
||||
struct passwd *pw;
|
||||
|
|
@ -571,11 +571,12 @@ main(int argc,
|
|||
cvec *nsctx_global = NULL; /* Global namespace context */
|
||||
size_t cligen_buflen;
|
||||
size_t cligen_bufthreshold;
|
||||
int dbg=0;
|
||||
uint32_t dbg=0;
|
||||
int nr;
|
||||
int config_dump;
|
||||
enum format_enum config_dump_format = FORMAT_XML;
|
||||
int print_version = 0;
|
||||
int32_t d;
|
||||
|
||||
/* Defaults */
|
||||
once = 0;
|
||||
|
|
@ -608,7 +609,7 @@ main(int argc,
|
|||
*/
|
||||
optind = 1;
|
||||
opterr = 0;
|
||||
while ((c = getopt(argc, argv, CLI_OPTS)) != -1)
|
||||
while ((c = getopt(argc, argv, CLI_OPTS)) != -1) {
|
||||
switch (c) {
|
||||
case 'h':
|
||||
/* Defer the call to usage() to later. Reason is that for helpful
|
||||
|
|
@ -622,16 +623,15 @@ main(int argc,
|
|||
cligen_output(stdout, "Clixon version: %s\n", CLIXON_GITHASH);
|
||||
print_version++; /* plugins may also print versions w ca-version callback */
|
||||
break;
|
||||
case 'D' : { /* debug */
|
||||
int d = 0;
|
||||
/* Try first symbolic, then numeric match */
|
||||
case 'D' : /* debug, if set here overrides option CLICON_DEBUG */
|
||||
/* Try first symbolic, then numeric match
|
||||
* Cant use yang_bits_map, too early in bootstrap, there is no yang */
|
||||
if ((d = clixon_debug_str2key(optarg)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
dbg |= d;
|
||||
break;
|
||||
}
|
||||
case 'f': /* config file */
|
||||
if (!strlen(optarg))
|
||||
usage(h, argv[0]);
|
||||
|
|
@ -642,19 +642,25 @@ main(int argc,
|
|||
usage(h, argv[0]);
|
||||
clicon_option_str_set(h, "CLICON_CONFIGDIR", optarg);
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o|f */
|
||||
if ((logdst = clixon_log_opt(optarg[0])) < 0)
|
||||
usage(h, argv[0]);
|
||||
if (logdst == CLIXON_LOG_FILE &&
|
||||
strlen(optarg)>1 &&
|
||||
case 'l': /* Log destination: s|e|o|f<file> */
|
||||
if ((d = clixon_logdst_str2key(optarg)) < 0){
|
||||
if (optarg[0] == 'f'){ /* Check for special -lf<file> syntax */
|
||||
d = CLIXON_LOG_FILE;
|
||||
if (strlen(optarg) > 1 &&
|
||||
clixon_log_file(optarg+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
logdst = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Logs, error and debug to stderr or syslog, set debug level
|
||||
*/
|
||||
clixon_log_init(h, __PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst);
|
||||
clixon_log_init(h, __PROGRAM__, dbg?LOG_DEBUG:LOG_INFO, logdst?logdst:CLIXON_LOG_STDERR);
|
||||
clixon_debug_init(h, dbg);
|
||||
yang_init(h);
|
||||
|
||||
|
|
@ -763,25 +769,10 @@ main(int argc,
|
|||
/* Defer: Wait to the last minute to print help message */
|
||||
if (help)
|
||||
usage(h, argv[0]);
|
||||
/* Unless -D, set debug level to CLICON_DEBUG set
|
||||
* Only works for one value.
|
||||
*/
|
||||
{
|
||||
char *dstr;
|
||||
int d = 0;
|
||||
|
||||
dstr = clicon_option_str(h, "CLICON_DEBUG");
|
||||
if (dbg == 0 && dstr && strlen(dstr)){
|
||||
if ((d = clixon_debug_str2key(dstr)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
clixon_err(OE_CFG, 0, "Parsing CLICON_DEBUG: %s", dstr);
|
||||
/* Read debug and log options from config file if not given by command-line */
|
||||
if (clixon_options_main_helper(h, dbg, logdst, __PROGRAM__) < 0)
|
||||
goto done;
|
||||
}
|
||||
clixon_debug_init(h, d);
|
||||
clixon_log_init(h, __PROGRAM__, d?LOG_DEBUG:LOG_INFO, logdst);
|
||||
}
|
||||
}
|
||||
|
||||
/* Split remaining argv/argc into <cmd> and <extra-options> */
|
||||
if (options_split(h, argv0, argc, argv, &restarg) < 0)
|
||||
goto done;
|
||||
|
|
@ -983,8 +974,9 @@ main(int argc,
|
|||
done:
|
||||
if (restarg)
|
||||
free(restarg);
|
||||
// Gets in your face if we log on stderr
|
||||
clixon_log_init(h, __PROGRAM__, LOG_INFO, 0); /* Log on syslog no stderr */
|
||||
/* Dont log terminate on stderr or stdout */
|
||||
clixon_log_init(h, __PROGRAM__, LOG_INFO,
|
||||
clixon_get_logflags() & ~(CLIXON_LOG_STDERR|CLIXON_LOG_STDOUT));
|
||||
clixon_log(h, LOG_NOTICE, "%s: %u Terminated", __PROGRAM__, getpid());
|
||||
if (h)
|
||||
cli_terminate(h);
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ netconf_add_request_attr(cxobj *xrpc,
|
|||
if (xml_find_type(xrep, NULL, xml_name(xa), CX_ATTR) != NULL)
|
||||
continue; /* Skip already present (dont overwrite) */
|
||||
/* Filter all clixon-lib attributes and namespace declaration
|
||||
* to acvoid leaking internal attributes to external NETCONF
|
||||
* to avoid leaking internal attributes to external NETCONF
|
||||
* note this is only done on top-level.
|
||||
*/
|
||||
if (xml_prefix(xa) && strcmp(xml_prefix(xa), CLIXON_LIB_PREFIX) == 0)
|
||||
|
|
@ -687,6 +687,7 @@ main(int argc,
|
|||
int config_dump = 0;
|
||||
enum format_enum config_dump_format = FORMAT_XML;
|
||||
int print_version = 0;
|
||||
int32_t d;
|
||||
|
||||
/* Create handle */
|
||||
if ((h = clixon_handle_init()) == NULL)
|
||||
|
|
@ -703,7 +704,7 @@ main(int argc,
|
|||
}
|
||||
if (clicon_username_set(h, pw->pw_name) < 0)
|
||||
goto done;
|
||||
while ((c = getopt(argc, argv, NETCONF_OPTS)) != -1)
|
||||
while ((c = getopt(argc, argv, NETCONF_OPTS)) != -1) {
|
||||
switch (c) {
|
||||
case 'h' : /* help */
|
||||
usage(h, argv[0]);
|
||||
|
|
@ -712,16 +713,14 @@ main(int argc,
|
|||
cligen_output(stdout, "Clixon version: %s\n", CLIXON_GITHASH);
|
||||
print_version++; /* plugins may also print versions w ca-version callback */
|
||||
break;
|
||||
case 'D' : { /* debug */
|
||||
int d = 0;
|
||||
case 'D' : /* debug */
|
||||
/* Try first symbolic, then numeric match */
|
||||
if ((d = clixon_debug_str2key(optarg)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
sscanf(optarg, "%u", &d) != 1){
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
dbg |= d;
|
||||
break;
|
||||
}
|
||||
case 'f': /* override config file */
|
||||
if (!strlen(optarg))
|
||||
usage(h, argv[0]);
|
||||
|
|
@ -733,14 +732,22 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_CONFIGDIR", optarg);
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o */
|
||||
if ((logdst = clixon_log_opt(optarg[0])) < 0)
|
||||
usage(h, argv[0]);
|
||||
if (logdst == CLIXON_LOG_FILE &&
|
||||
strlen(optarg)>1 &&
|
||||
int32_t d;
|
||||
d = 0;
|
||||
if ((d = clixon_logdst_str2key(optarg)) < 0){
|
||||
if (optarg[0] == 'f'){ /* Check for special -lf<file> syntax */
|
||||
d = CLIXON_LOG_FILE;
|
||||
if (strlen(optarg) > 1 &&
|
||||
clixon_log_file(optarg+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
logdst = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Logs, error and debug to stderr or syslog, set debug level
|
||||
|
|
@ -833,6 +840,9 @@ main(int argc,
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Read debug and log options from config file if not given by command-line */
|
||||
if (clixon_options_main_helper(h, dbg, logdst, __PROGRAM__) < 0)
|
||||
goto done;
|
||||
/* Access the remaining argv/argc options (after --) w clicon-argv_get() */
|
||||
clicon_argv_set(h, argv0, argc, argv);
|
||||
|
||||
|
|
|
|||
|
|
@ -329,6 +329,7 @@ main(int argc,
|
|||
enum format_enum config_dump_format = FORMAT_XML;
|
||||
int print_version = 0;
|
||||
int stream_timeout = 0;
|
||||
int32_t d;
|
||||
|
||||
/* Create handle */
|
||||
if ((h = restconf_handle_init()) == NULL)
|
||||
|
|
@ -351,7 +352,6 @@ main(int argc,
|
|||
print_version++; /* plugins may also print versions w ca-version callback */
|
||||
break;
|
||||
case 'D' : { /* debug */
|
||||
int d = 0;
|
||||
/* Try first symbolic, then numeric match */
|
||||
if ((d = clixon_debug_str2key(optarg)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
|
|
@ -371,12 +371,17 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_CONFIGDIR", optarg);
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o */
|
||||
if ((logdst = clixon_log_opt(optarg[0])) < 0)
|
||||
usage(h, argv[0]);
|
||||
if (logdst == CLIXON_LOG_FILE &&
|
||||
strlen(optarg)>1 &&
|
||||
if ((d = clixon_logdst_str2key(optarg)) < 0){
|
||||
if (optarg[0] == 'f'){ /* Check for special -lf<file> syntax */
|
||||
d = CLIXON_LOG_FILE;
|
||||
if (strlen(optarg) > 1 &&
|
||||
clixon_log_file(optarg+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
logdst = d;
|
||||
break;
|
||||
} /* switch getopt */
|
||||
|
||||
|
|
@ -466,6 +471,9 @@ main(int argc,
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Read debug and log options from config file if not given by command-line */
|
||||
if (clixon_options_main_helper(h, dbg, logdst, __PROGRAM__) < 0)
|
||||
goto done;
|
||||
/* Access the remaining argv/argc options (after --) w clicon-argv_get() */
|
||||
clicon_argv_set(h, argv0, argc, argv);
|
||||
|
||||
|
|
|
|||
|
|
@ -1168,6 +1168,7 @@ main(int argc,
|
|||
enum format_enum config_dump_format = FORMAT_XML;
|
||||
int print_version = 0;
|
||||
int stream_timeout = 0;
|
||||
int32_t d;
|
||||
|
||||
/* Create handle */
|
||||
if ((h = restconf_handle_init()) == NULL)
|
||||
|
|
@ -1187,17 +1188,13 @@ main(int argc,
|
|||
cligen_output(stdout, "Clixon version: %s\n", CLIXON_GITHASH);
|
||||
print_version++; /* plugins may also print versions w ca-version callback */
|
||||
break;
|
||||
case 'D' : { /* debug. Note this overrides any setting in the config */
|
||||
int d = 0;
|
||||
case 'D' : /* debug. Note this overrides any setting in the config */
|
||||
/* Try first symbolic, then numeric match */
|
||||
if ((d = clixon_debug_str2key(optarg)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
dbg |= d;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 'f': /* override config file */
|
||||
if (!strlen(optarg))
|
||||
|
|
@ -1210,12 +1207,17 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_CONFIGDIR", optarg);
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o */
|
||||
if ((logdst = clixon_log_opt(optarg[0])) < 0)
|
||||
usage(h, argv0);
|
||||
if (logdst == CLIXON_LOG_FILE &&
|
||||
strlen(optarg)>1 &&
|
||||
if ((d = clixon_logdst_str2key(optarg)) < 0){
|
||||
if (optarg[0] == 'f'){ /* Check for special -lf<file> syntax */
|
||||
d = CLIXON_LOG_FILE;
|
||||
if (strlen(optarg) > 1 &&
|
||||
clixon_log_file(optarg+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
logdst = d;
|
||||
break;
|
||||
} /* switch getopt */
|
||||
|
||||
|
|
@ -1324,6 +1326,10 @@ main(int argc,
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Read debug and log options from config file if not given by command-line */
|
||||
if (clixon_options_main_helper(h, dbg, logdst, __PROGRAM__) < 0)
|
||||
goto done;
|
||||
|
||||
/* Access the remaining argv/argc options (after --) w clicon-argv_get() */
|
||||
clicon_argv_set(h, argv0, argc, argv);
|
||||
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ main(int argc,
|
|||
int config_dump = 0;
|
||||
enum format_enum config_dump_format = FORMAT_XML;
|
||||
int print_version = 0;
|
||||
int32_t d;
|
||||
|
||||
/* Create handle */
|
||||
if ((h = clixon_handle_init()) == NULL)
|
||||
|
|
@ -386,7 +387,7 @@ main(int argc,
|
|||
print_version++; /* plugins may also print versions w ca-version callback */
|
||||
break;
|
||||
case 'D' : { /* debug */
|
||||
int d = 0;
|
||||
int32_t d = 0;
|
||||
/* Try first symbolic, then numeric match */
|
||||
if ((d = clixon_debug_str2key(optarg)) < 0 &&
|
||||
sscanf(optarg, "%d", &d) != 1){
|
||||
|
|
@ -401,12 +402,17 @@ main(int argc,
|
|||
clicon_option_str_set(h, "CLICON_CONFIGFILE", optarg);
|
||||
break;
|
||||
case 'l': /* Log destination: s|e|o */
|
||||
if ((logdst = clixon_log_opt(optarg[0])) < 0)
|
||||
usage(h, argv[0]);
|
||||
if (logdst == CLIXON_LOG_FILE &&
|
||||
strlen(optarg)>1 &&
|
||||
if ((d = clixon_logdst_str2key(optarg)) < 0){
|
||||
if (optarg[0] == 'f'){ /* Check for special -lf<file> syntax */
|
||||
d = CLIXON_LOG_FILE;
|
||||
if (strlen(optarg) > 1 &&
|
||||
clixon_log_file(optarg+1) < 0)
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
usage(h, argv[0]);
|
||||
}
|
||||
logdst = d;
|
||||
break;
|
||||
}
|
||||
if (print_version)
|
||||
|
|
@ -467,6 +473,9 @@ main(int argc,
|
|||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
/* Read debug and log options from config file if not given by command-line */
|
||||
if (clixon_options_main_helper(h, dbg, logdst, __PROGRAM__) < 0)
|
||||
goto done;
|
||||
/* Access the remaining argv/argc options (after --) w clicon-argv_get() */
|
||||
clicon_argv_set(h, argv0, argc, argv);
|
||||
|
||||
|
|
|
|||
|
|
@ -46,9 +46,10 @@
|
|||
* Constants
|
||||
*/
|
||||
|
||||
/* Debug flags are seperated into subject areas and detail
|
||||
/*! Debug flags are separated into subject areas and detail
|
||||
*
|
||||
* @see dbgmap Symbolic mapping (if you change here you may need to change dbgmap)
|
||||
* @see clixon_debug in clixon-lib.yang
|
||||
* @see also clixon_debug_t in clixon-lib.yang
|
||||
*/
|
||||
/* Detail level */
|
||||
#define CLIXON_DBG_ALWAYS 0x00000000 /* Unconditionally logged */
|
||||
|
|
|
|||
|
|
@ -45,11 +45,15 @@
|
|||
/*
|
||||
* Constants
|
||||
*/
|
||||
/* Where to log (masks) */
|
||||
#define CLIXON_LOG_SYSLOG 1 /* print logs on syslog */
|
||||
#define CLIXON_LOG_STDERR 2 /* print logs on stderr */
|
||||
#define CLIXON_LOG_STDOUT 4 /* print logs on stdout */
|
||||
#define CLIXON_LOG_FILE 8 /* print logs on clicon_log_filename */
|
||||
/*! Log destination as bitfields (masks)
|
||||
*
|
||||
* @see logdstmap Symbolic mapping (if you change here you may need to change logdstmap)
|
||||
* @see also log_desination_t in clixon-config.yang
|
||||
*/
|
||||
#define CLIXON_LOG_SYSLOG 0x01 /* print logs on syslog */
|
||||
#define CLIXON_LOG_STDERR 0x02 /* print logs on stderr */
|
||||
#define CLIXON_LOG_STDOUT 0x04 /* print logs on stdout */
|
||||
#define CLIXON_LOG_FILE 0x08 /* print logs on clixon_log_filename */
|
||||
|
||||
/* What kind of log (only for customizable error/logs) */
|
||||
enum clixon_log_type{
|
||||
|
|
@ -67,6 +71,8 @@ enum clixon_log_type{
|
|||
/*
|
||||
* Prototypes
|
||||
*/
|
||||
char *clixon_logdst_key2str(int keyword);
|
||||
int clixon_logdst_str2key(char *str);
|
||||
int clixon_log_init(clixon_handle h, char *ident, int upto, int flags);
|
||||
int clixon_log_exit(void);
|
||||
int clixon_log_opt(char c);
|
||||
|
|
|
|||
|
|
@ -112,6 +112,9 @@ int clicon_option_add(clixon_handle h, const char *name, char *value);
|
|||
/* Initialize options: set defaults, read config-file, etc */
|
||||
int clicon_options_main(clixon_handle h);
|
||||
|
||||
/* Options debug and log helper function */
|
||||
int clixon_options_main_helper(clixon_handle h, uint32_t dbg, uint32_t logdst, char *ident);
|
||||
|
||||
/*! Check if a clicon option has a value */
|
||||
int clicon_option_exists(clixon_handle h, const char *name);
|
||||
|
||||
|
|
|
|||
|
|
@ -77,8 +77,10 @@ int assign_namespace_element(cxobj *x0, cxobj *x1, cxobj *x1p);
|
|||
int assign_namespace_body(cxobj *x0, cxobj *x1);
|
||||
int xml_merge(cxobj *x0, cxobj *x1, yang_stmt *yspec, char **reason);
|
||||
int yang_valstr2enum(yang_stmt *ytype, char *valstr, char **enumstr);
|
||||
int yang_bitsstr2val(clixon_handle h, yang_stmt *ytype, char *bitsstr, unsigned char **snmpval, size_t *snmplen);
|
||||
int yang_val2bitsstr(clixon_handle h, yang_stmt *ytype, unsigned char *snmpval, size_t snmplen, cbuf *cb);
|
||||
int yang_bitsstr2val(clixon_handle h, yang_stmt *ytype, char *bitsstr, unsigned char **outval, size_t *outlen);
|
||||
int yang_bitsstr2flags(yang_stmt *ytype, char *bitsstr, uint32_t *flags);
|
||||
int yang_val2bitsstr(clixon_handle h, yang_stmt *ytype, unsigned char *outval, size_t snmplen, cbuf *cb);
|
||||
int yang_bits_map(yang_stmt *yt, char *str, char *nodeid, uint32_t *flags);
|
||||
int yang_enum2valstr(yang_stmt *ytype, char *enumstr, char **valstr);
|
||||
int yang_enum2int(yang_stmt *ytype, char *enumstr, int32_t *val);
|
||||
int yang_enum_int_value(cxobj *node, int32_t *val);
|
||||
|
|
|
|||
|
|
@ -79,9 +79,20 @@
|
|||
/* Cache handle since debug calls do not have handle parameter */
|
||||
static clixon_handle _debug_clixon_h = NULL;
|
||||
|
||||
/*! The global debug level. 0 means no debug
|
||||
*
|
||||
* @note There are pros and cons in having the debug state as a global variable. The
|
||||
* alternative to bind it to the clicon handle (h) was considered but it limits its
|
||||
* usefulness, since not all functions have access to a handle.
|
||||
* A compromise solution is now in place where h can be provided in the function call, but
|
||||
* tolerates NULL, in which case a cached handle is used.
|
||||
*/
|
||||
static int _debug_level = 0;
|
||||
|
||||
/*! Mapping between Clixon debug symbolic names <--> bitfields
|
||||
*
|
||||
* Mapping between specific bitfields and symbolic names, note only perfect matches
|
||||
* @note yang_bits_map can be used as alternative but this still neeeded in bootstrapping
|
||||
*/
|
||||
static const map_str2int dbgmap[] = {
|
||||
{"default", CLIXON_DBG_DEFAULT},
|
||||
|
|
@ -152,16 +163,6 @@ clixon_debug_key_dump(FILE *f)
|
|||
return -1;
|
||||
}
|
||||
|
||||
/*! The global debug level. 0 means no debug
|
||||
*
|
||||
* @note There are pros and cons in having the debug state as a global variable. The
|
||||
* alternative to bind it to the clicon handle (h) was considered but it limits its
|
||||
* usefulness, since not all functions have access to a handle.
|
||||
* A compromise solution is now in place where h can be provided in the function call, but
|
||||
* tolerates NULL, in which case a cached handle is used.
|
||||
*/
|
||||
static int _debug_level = 0;
|
||||
|
||||
/*! Initialize debug messages. Set debug level.
|
||||
*
|
||||
* Initialize debug module. The level is used together with clixon_debug(dbglevel) calls as follows:
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@
|
|||
/* clixon */
|
||||
#include "clixon_queue.h"
|
||||
#include "clixon_hash.h"
|
||||
#include "clixon_string.h"
|
||||
#include "clixon_handle.h"
|
||||
#include "clixon_yang.h"
|
||||
#include "clixon_xml.h"
|
||||
|
|
@ -87,6 +88,47 @@ static FILE *_log_file = NULL;
|
|||
/* Truncate debug strings to this length. 0 means unlimited */
|
||||
static int _log_trunc = 0;
|
||||
|
||||
/*! Mapping between Clixon debug symbolic names <--> bitfields
|
||||
*
|
||||
* Also inclode shorthands: s|e|o|f|n
|
||||
* Mapping between specific bitfields and symbolic names, note only perfect matches
|
||||
* @see typedef log_destination_t in clixon-config.yang
|
||||
*/
|
||||
static const map_str2int logdstmap[] = {
|
||||
{"syslog", CLIXON_LOG_SYSLOG},
|
||||
{"s", CLIXON_LOG_SYSLOG},
|
||||
{"stderr", CLIXON_LOG_STDERR},
|
||||
{"e", CLIXON_LOG_STDERR},
|
||||
{"stdout", CLIXON_LOG_STDOUT},
|
||||
{"o", CLIXON_LOG_STDOUT},
|
||||
{"file", CLIXON_LOG_FILE},
|
||||
{"f", CLIXON_LOG_FILE},
|
||||
{"n", 0x0},
|
||||
{NULL, -1}
|
||||
};
|
||||
|
||||
/*! Map from clixon debug (specific) bitmask to string
|
||||
*
|
||||
* @param[in] int Bitfield, see CLIXON_LOG_SYSLOG and others
|
||||
* @retval str String representation of bitfield
|
||||
*/
|
||||
char *
|
||||
clixon_logdst_key2str(int keyword)
|
||||
{
|
||||
return (char*)clicon_int2str(logdstmap, keyword);
|
||||
}
|
||||
|
||||
/*! Map from clixon log destination symbolic string to bitfield
|
||||
*
|
||||
* @param[in] str String representation of Clixon log destination bit
|
||||
* @retval int Bit representation of bitfield
|
||||
*/
|
||||
int
|
||||
clixon_logdst_str2key(char *str)
|
||||
{
|
||||
return clicon_str2int(logdstmap, str);
|
||||
}
|
||||
|
||||
/*! Initialize system logger.
|
||||
*
|
||||
* Make syslog(3) calls with specified ident and gates calls of level upto specified level (upto).
|
||||
|
|
@ -96,9 +138,7 @@ static int _log_trunc = 0;
|
|||
* @param[in] h Clixon handle
|
||||
* @param[in] ident prefix that appears on syslog (eg 'cli')
|
||||
* @param[in] upto log priority, eg LOG_DEBUG,LOG_INFO,...,LOG_EMERG (see syslog(3)).
|
||||
* @param[in] flags bitmask: if CLIXON_LOG_STDERR, then print logs to stderr
|
||||
* if CLIXON_LOG_SYSLOG, then print logs to syslog
|
||||
* You can do a combination of both
|
||||
* @param[in] flags Log destination bitmask
|
||||
* @retval 0 OK
|
||||
* @code
|
||||
* clixon_log_init(__PROGRAM__, LOG_INFO, CLIXON_LOG_STDERR);
|
||||
|
|
|
|||
|
|
@ -73,7 +73,6 @@
|
|||
#include "clixon_debug.h"
|
||||
#include "clixon_string.h"
|
||||
#include "clixon_file.h"
|
||||
#include "clixon_xml_sort.h"
|
||||
#include "clixon_json.h"
|
||||
#include "clixon_text_syntax.h"
|
||||
#include "clixon_proto.h"
|
||||
|
|
@ -83,8 +82,10 @@
|
|||
#include "clixon_xpath.h"
|
||||
#include "clixon_yang_parse_lib.h"
|
||||
#include "clixon_netconf_lib.h"
|
||||
#include "clixon_xml_sort.h"
|
||||
#include "clixon_xml_nsctx.h"
|
||||
#include "clixon_xml_io.h"
|
||||
#include "clixon_xml_map.h"
|
||||
#include "clixon_validate.h"
|
||||
#include "clixon_xml_default.h"
|
||||
|
||||
|
|
@ -725,6 +726,59 @@ clicon_options_main(clixon_handle h)
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*! Options debug and log helper function
|
||||
*
|
||||
* If no debug or log option set in command-line, read debug or log options from
|
||||
* configure file.
|
||||
* Also set log file if CLICON_LOG_FILE is set
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] dbg Debug bitmask
|
||||
* @param[in] logdst Log destination bitmask
|
||||
* @param[in] ident prefix that appears on syslog
|
||||
* @retval 0 OK
|
||||
* @retval -1 Error
|
||||
*/
|
||||
int
|
||||
clixon_options_main_helper(clixon_handle h,
|
||||
uint32_t dbg,
|
||||
uint32_t logdst,
|
||||
char *ident)
|
||||
{
|
||||
int retval = -1;
|
||||
int relog = 0;
|
||||
char *dstr;
|
||||
|
||||
relog = 0;
|
||||
dstr = clicon_option_str(h, "CLICON_DEBUG");
|
||||
if (dbg == 0 && dstr && strlen(dstr)){
|
||||
if (yang_bits_map(clicon_config_yang(h),
|
||||
dstr,
|
||||
"/cc:clixon-config/cc:CLICON_DEBUG",
|
||||
&dbg) < 0)
|
||||
goto done;
|
||||
relog++;
|
||||
}
|
||||
dstr = clicon_option_str(h, "CLICON_LOG_DESTINATION");
|
||||
if (logdst == 0 && dstr && strlen(dstr)){
|
||||
logdst = 0;
|
||||
if (yang_bits_map(clicon_config_yang(h),
|
||||
dstr,
|
||||
"/cc:clixon-config/cc:CLICON_LOG_DESTINATION",
|
||||
&logdst) < 0)
|
||||
goto done;
|
||||
relog++;
|
||||
}
|
||||
if (relog){
|
||||
clixon_debug_init(h, dbg);
|
||||
clixon_log_init(h, ident, dbg?LOG_DEBUG:LOG_INFO, logdst?logdst:CLIXON_LOG_STDERR);
|
||||
}
|
||||
if ((dstr = clicon_option_str(h, "CLICON_LOG_FILE")) != NULL)
|
||||
clixon_log_file(dstr);
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Check if a clicon option has a value
|
||||
*
|
||||
* @param[in] h clixon_handle
|
||||
|
|
|
|||
|
|
@ -1669,25 +1669,25 @@ yang_bits_pos(yang_stmt *ytype,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Given a YANG (bits) type node and string value, return SNMP value for bits set.
|
||||
/*! Given a YANG (bits) type node and string value, return value for bits set.
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] ytype YANG type noden
|
||||
* @param[in] bitsstr Value of bits as space separated string
|
||||
* @param[out] snmpval SNMP value with all bits set for given bitsstr
|
||||
* @param[out] snmplen length of snmpval
|
||||
* @retval 1 OK, result in snmpval
|
||||
* @param[out] outval Value with all bits set for given bitsstr (free with free)
|
||||
* @param[out] outlen Length of outval
|
||||
* @retval 1 OK, result in outval
|
||||
* @retval 0 Invalid, not found
|
||||
* @retval -1 Error
|
||||
* @see yang_val2bitsstr
|
||||
* XXX de-snmp:ize
|
||||
* @note that the output is a vector of bits originally made for SNMP bitvectors (not integers)
|
||||
*/
|
||||
int
|
||||
yang_bitsstr2val(clixon_handle h,
|
||||
yang_stmt *ytype,
|
||||
char *bitsstr,
|
||||
unsigned char **snmpval,
|
||||
size_t *snmplen)
|
||||
unsigned char **outval,
|
||||
size_t *outlen)
|
||||
{
|
||||
int retval = -1;
|
||||
int i = 0;
|
||||
|
|
@ -1699,7 +1699,7 @@ yang_bitsstr2val(clixon_handle h,
|
|||
int ret = 0;
|
||||
uint32_t bitpos;
|
||||
|
||||
*snmplen = 0;
|
||||
*outlen = 0;
|
||||
if ((buffer = calloc(CLIXON_BITS_POS_MAX / 8, sizeof(unsigned char))) == NULL){
|
||||
clixon_err(OE_UNIX, errno, "calloc");
|
||||
goto done;
|
||||
|
|
@ -1719,19 +1719,19 @@ yang_bitsstr2val(clixon_handle h,
|
|||
/* Set bit at correct byte and bit position */
|
||||
byte = bitpos / 8;
|
||||
buffer[byte] = buffer[byte] | (1 << (7 - (bitpos % 8)));
|
||||
*snmplen = byte + 1;
|
||||
if (*snmplen >= CLIXON_BITS_POS_MAX) {
|
||||
*outlen = byte + 1;
|
||||
if (*outlen >= CLIXON_BITS_POS_MAX) {
|
||||
clixon_err(OE_UNIX, EINVAL, "bit position %zu out of range. (max. allowed %d)",
|
||||
*snmplen, CLIXON_BITS_POS_MAX);
|
||||
*outlen, CLIXON_BITS_POS_MAX);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ((*snmpval = malloc(*snmplen)) == NULL){
|
||||
if ((*outval = malloc(*outlen)) == NULL){
|
||||
clixon_err(OE_UNIX, errno, "calloc");
|
||||
goto done;
|
||||
}
|
||||
memcpy(*snmpval, buffer, *snmplen);
|
||||
memcpy(*outval, buffer, *outlen);
|
||||
retval = 1;
|
||||
done:
|
||||
if (buffer)
|
||||
|
|
@ -1744,24 +1744,81 @@ yang_bitsstr2val(clixon_handle h,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Given a YANG (bits) type node and SNMP value, return the string value for all bits (flags) that are set.
|
||||
/*! Given a YANG (bits) type node and string value, return bit values in a uint64
|
||||
*
|
||||
* @param[in] ytype YANG type noden
|
||||
* @param[in] bitsstr Value of bits as space separated string
|
||||
* @param[out] flags Pointer to integer with bit values set according to C type
|
||||
* @retval 1 OK, result in u64
|
||||
* @retval 0 Invalid, not found
|
||||
* @retval -1 Error
|
||||
* @see yang_bitsstr2val for bit vector (snmp-like)
|
||||
*/
|
||||
int
|
||||
yang_bitsstr2flags(yang_stmt *ytype,
|
||||
char *bitsstr,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int retval = -1;
|
||||
int i = 0;
|
||||
char **vec = NULL;
|
||||
char *v;
|
||||
int nvec;
|
||||
int ret = 0;
|
||||
uint32_t bitpos;
|
||||
|
||||
if (flags == NULL){
|
||||
clixon_err(OE_UNIX, EINVAL, "flags is NULL");
|
||||
goto done;
|
||||
}
|
||||
if ((vec = clicon_strsep(bitsstr, " ", &nvec)) == NULL){
|
||||
clixon_err(OE_UNIX, EINVAL, "split string failed");
|
||||
goto done;
|
||||
}
|
||||
/* Go over all set flags in given bitstring */
|
||||
for (i=0; i<nvec; i++){
|
||||
v = clixon_trim(vec[i]);
|
||||
if (strlen(v) > 0) {
|
||||
if ((ret = yang_bits_pos(ytype, v, &bitpos)) < 0)
|
||||
goto done;
|
||||
if (ret == 0)
|
||||
goto fail;
|
||||
if (bitpos >= 32) {
|
||||
clixon_err(OE_UNIX, EINVAL, "bit position %u out of range. (max. allowed %d)",
|
||||
bitpos, 32);
|
||||
goto done;
|
||||
}
|
||||
*flags |= (1 << bitpos);
|
||||
}
|
||||
}
|
||||
retval = 1;
|
||||
done:
|
||||
if (vec)
|
||||
free(vec);
|
||||
return retval;
|
||||
fail:
|
||||
retval = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
/*! Given a YANG (bits) type node and value, return the string value for all bits (flags) that are set.
|
||||
*
|
||||
* @param[in] h Clixon handle
|
||||
* @param[in] ytype YANG type noden
|
||||
* @param[in] snmpval SNMP value
|
||||
* @param[in] snmplen length of snmpval
|
||||
* @param[out] cb space separated string with bit labes for all bits that are set in snmpval
|
||||
* @param[in] inval Input string
|
||||
* @param[in] inlen Length of inval
|
||||
* @param[out] cb space separated string with bit labels for all bits that are set in inval
|
||||
* @retval 1 OK, result in cb
|
||||
* @retval 0 Invalid, not found
|
||||
* @retval -1 Error
|
||||
* @see yang_bitsstr2val
|
||||
* XXX de-snmp:ize
|
||||
* @note that the output is a vector of bits originally made for SNMP bitvectors (not integers)
|
||||
*/
|
||||
int
|
||||
yang_val2bitsstr(clixon_handle h,
|
||||
yang_stmt *ytype,
|
||||
unsigned char *snmpval,
|
||||
size_t snmplen,
|
||||
unsigned char *inval,
|
||||
size_t inlen,
|
||||
cbuf *cb)
|
||||
{
|
||||
int retval = -1;
|
||||
|
|
@ -1778,7 +1835,7 @@ yang_val2bitsstr(clixon_handle h,
|
|||
goto done;
|
||||
}
|
||||
/* Go over all defined bits and check if it is seet in intval */
|
||||
while ((yprev = yn_each(ytype, yprev)) != NULL && byte < snmplen){
|
||||
while ((yprev = yn_each(ytype, yprev)) != NULL && byte < inlen){
|
||||
if (yang_keyword_get(yprev) == Y_BIT) {
|
||||
/* Use position from Y_POSITION statement if defined */
|
||||
if ((ypos = yang_find(yprev, Y_POSITION, NULL)) != NULL){
|
||||
|
|
@ -1793,7 +1850,7 @@ yang_val2bitsstr(clixon_handle h,
|
|||
if (is_first == 0) bitpos++;
|
||||
}
|
||||
byte = bitpos / 8;
|
||||
if (snmpval[byte] & (1 << (7 - (bitpos % 8)))){
|
||||
if (inval[byte] & (1 << (7 - (bitpos % 8)))){
|
||||
if (is_first == 0) cbuf_append_str(cb, " ");
|
||||
cbuf_append_str(cb, yang_argument_get(yprev));
|
||||
}
|
||||
|
|
@ -1813,6 +1870,47 @@ yang_val2bitsstr(clixon_handle h,
|
|||
goto done;
|
||||
}
|
||||
|
||||
/*! Map from bit string to integer bitfield given YANG mapping
|
||||
*
|
||||
* Given YANG node, schema-nodeid and a bits string, return a bitmap as u64
|
||||
* Example: "default app2" --> CLIXON_DBG_DEFAULT | CLIXON_DBG_APP2
|
||||
* @param[in] yt YANG node in tree (eg yspec)
|
||||
* @param[in] str String representation of Clixon debug bits, such as "msg app2"
|
||||
* @param[in] nodeid Absolute schema node identifier to leaf of option
|
||||
* @param[out] u64 Bit representation
|
||||
*/
|
||||
int
|
||||
yang_bits_map(yang_stmt *yt,
|
||||
char *str,
|
||||
char *nodeid,
|
||||
uint32_t *flags)
|
||||
{
|
||||
int retval = -1;
|
||||
yang_stmt *yn = NULL;
|
||||
yang_stmt *yrestype;
|
||||
int ret;
|
||||
|
||||
if (yang_abs_schema_nodeid(yt, nodeid, &yn) < 0)
|
||||
goto done;
|
||||
if (yn == NULL){
|
||||
clixon_err(OE_YANG, 0, "yang node not found: %s", nodeid);
|
||||
goto done;
|
||||
}
|
||||
if (yang_type_get(yn, NULL, &yrestype, NULL, NULL, NULL, NULL, NULL) < 0)
|
||||
goto done;
|
||||
if (yrestype != NULL) {
|
||||
if ((ret = yang_bitsstr2flags(yrestype, str, flags)) < 0)
|
||||
goto done;
|
||||
if (ret == 0){
|
||||
clixon_err(OE_YANG, 0, "Bit string invalid: %s", str);
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
retval = 0;
|
||||
done:
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*! Get integer value from xml node from yang enumeration
|
||||
*
|
||||
* @param[in] node XML node in a tree
|
||||
|
|
|
|||
|
|
@ -120,10 +120,10 @@ expectpart "$($clixon_cli -1 -f $cfg show conf x)" 0 "x m1 a (null) b 22/22 c 44
|
|||
|
||||
# Negative tests
|
||||
new "err x"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l n err x)" 255 "Config error: api-path syntax error \"/example2:x\": application unknown-element No such yang module prefix <bad-element>example2</bad-element>: Invalid argument"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o err x)" 255 "Config error: api-path syntax error \"/example2:x\": application unknown-element No such yang module prefix <bad-element>example2</bad-element>: Invalid argument"
|
||||
|
||||
new "err x a"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l n err x a 99)" 255 "Config error: api-path syntax error \"/example:x/m1=%s\": rpc malformed-message List key m1 length mismatch : Invalid argument"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o err x a 99)" 255 "Config error: api-path syntax error \"/example:x/m1=%s\": rpc malformed-message List key m1 length mismatch : Invalid argument"
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
new "Kill backend"
|
||||
|
|
|
|||
|
|
@ -89,11 +89,11 @@ new "wait backend"
|
|||
wait_backend
|
||||
|
||||
new "orig error"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l n example error orig)" 255 "Config error: api-path syntax error " ": application invalid-value Invalid api-path: (must start with '/')"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o example error orig)" 255 "Config error: api-path syntax error " ": application invalid-value Invalid api-path: (must start with '/')"
|
||||
|
||||
if [ ${LINKAGE} = dynamic ]; then
|
||||
new "customized error"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l n example error custom)" 255 "My new err-string"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o example error custom)" 255 "My new err-string"
|
||||
fi
|
||||
|
||||
if [ $BE -ne 0 ]; then
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#!/usr/bin/env bash
|
||||
# Turn on debug on backend/cli/netconf
|
||||
# Note, restconf debug used to be tested but is no longer tested here,
|
||||
# maybe in test_restconf_internal?
|
||||
# Also some log destination tests
|
||||
# Note no restconf debug test
|
||||
|
||||
# Magic line must be first in script (see README.md)
|
||||
s="$_" ; . ./lib.sh || if [ "$s" = $0 ]; then exit 0; else return 0; fi
|
||||
|
|
@ -84,15 +84,57 @@ wait_restconf
|
|||
new "Set backend debug using netconf"
|
||||
expecteof_netconf "$clixon_netconf -qf $cfg" 0 "$DEFAULTHELLO" "<rpc $DEFAULTNS><debug $LIBNS><level>1</level></debug></rpc>" "" "<rpc-reply $DEFAULTNS><ok/></rpc-reply>"
|
||||
|
||||
new "Set cli debug using cli"
|
||||
# Debug
|
||||
new "cli debug cli"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o debug cli 1)" 0 "^$"
|
||||
|
||||
# Run cli debug
|
||||
new "get cli debug, expect 0"
|
||||
new "cli debug, expect 0"
|
||||
expectpart "$($clixon_cli -1 -f $cfg show debug cli)" 0 "CLI debug:0x0"
|
||||
|
||||
new "get cli debug expect 2"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -o CLICON_DEBUG=msg show debug cli)" 0 "CLI debug:0x2"
|
||||
new "cli debug -o single"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -o CLICON_DEBUG=msg show debug cli)" 0 "CLI debug:0x2" --not-- "CLI debug:0x20"
|
||||
|
||||
new "cli debug -o multi"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -o CLICON_DEBUG="msg app2" show debug cli)" 0 "CLI debug:0x200002"
|
||||
|
||||
new "cli debug -D multi"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -D msg -D app2 show debug cli)" 0
|
||||
|
||||
# Log destination
|
||||
new "cli log -lf<file>"
|
||||
rm -f $dir/clixon.log
|
||||
expectpart "$($clixon_cli -1 -lf$dir/clixon.log -f $cfg show version)" 0
|
||||
if [ ! -f "$dir/clixon.log" ]; then
|
||||
err "$dir/clixon.log" "No file"
|
||||
fi
|
||||
|
||||
new "cli log -lfile"
|
||||
rm -f $dir/clixon.log
|
||||
expectpart "$($clixon_cli -1 -lfile -f $cfg show version)" 0
|
||||
if [ -f "$dir/clixon.log" ]; then
|
||||
err "No file" "$dir/clixon.log"
|
||||
fi
|
||||
|
||||
new "cli log -lfile + CLICON_LOG_FILE"
|
||||
rm -f $dir/clixon.log
|
||||
expectpart "$($clixon_cli -1 -lfile -o CLICON_LOG_FILE=$dir/clixon.log -f $cfg show version)" 0
|
||||
if [ ! -f "$dir/clixon.log" ]; then
|
||||
err "$dir/clixon.log" "No file"
|
||||
fi
|
||||
|
||||
rm -f $dir/clixon.log
|
||||
new "cli log -o CLICON_LOG_DESTINATION + CLICON_LOG_FILE"
|
||||
expectpart "$($clixon_cli -1 -o CLICON_LOG_DESTINATION=file -o CLICON_LOG_FILE=$dir/clixon.log -f $cfg show version)" 0
|
||||
if [ ! -f "$dir/clixon.log" ]; then
|
||||
err "$dir/clixon.log" "No file"
|
||||
fi
|
||||
|
||||
rm -f $dir/clixon.log
|
||||
new "cli log -o CLICON_LOG_DESTINATION + CLICON_LOG_FILE multi"
|
||||
expectpart "$($clixon_cli -1 -o CLICON_LOG_DESTINATION="stdout file" -o CLICON_LOG_FILE=$dir/clixon.log -f $cfg show version)" 0
|
||||
if [ ! -f "$dir/clixon.log" ]; then
|
||||
err "$dir/clixon.log" "No file"
|
||||
fi
|
||||
|
||||
new "Set backend debug using cli"
|
||||
expectpart "$($clixon_cli -1 -f $cfg -l o debug backend 1)" 0 "^$"
|
||||
|
|
|
|||
|
|
@ -52,6 +52,8 @@ module clixon-config {
|
|||
revision 2024-04-01 {
|
||||
description
|
||||
"Added options:
|
||||
CLICON_LOG_DESTINATION: Default log destination
|
||||
CLICON_LOG_FILE: Which file to log to if file logging
|
||||
CLICON_DEBUG: Debug flags.
|
||||
CLICON_YANG_SCHEMA_MOUNT_SHARE: Share same YANGs of equal moint-points.
|
||||
CLICON_SOCK_PRIO: Enable socket event priority
|
||||
|
|
@ -426,6 +428,33 @@ module clixon-config {
|
|||
}
|
||||
}
|
||||
}
|
||||
typedef log_destination_t {
|
||||
description
|
||||
"Log destination flags
|
||||
Can also be given directly as -l <flag> to clixon commands
|
||||
Note there are also constants in the code (logdstmap) that need to be
|
||||
in sync with these values.
|
||||
The duplication is because of bootstrapping, logging is needed before YANG
|
||||
loaded";
|
||||
type bits {
|
||||
bit syslog {
|
||||
position 0;
|
||||
description "Syslog";
|
||||
}
|
||||
bit stderr {
|
||||
position 1;
|
||||
description "Standard I/O Error";
|
||||
}
|
||||
bit stdout {
|
||||
position 2;
|
||||
description "Standard I/O Output";
|
||||
}
|
||||
bit file {
|
||||
position 3;
|
||||
description "Log to file. By default clixon.log int current directory";
|
||||
}
|
||||
}
|
||||
}
|
||||
container clixon-config {
|
||||
container restconf {
|
||||
uses clrc:clixon-restconf;
|
||||
|
|
@ -456,14 +485,7 @@ module clixon-config {
|
|||
Ensure that YANG_INSTALLDIR (default
|
||||
/usr/local/share/clixon) is present in the path";
|
||||
}
|
||||
leaf CLICON_DEBUG{
|
||||
type cl:clixon_debug_t;
|
||||
description
|
||||
"Debug flags as bitfields.
|
||||
Can also be given directly as -D <flag> to clixon commands (which overrides this)
|
||||
Note only partly implemented;
|
||||
- Only CLI, only single value, cannot be combined with -D, not in RPC";
|
||||
}
|
||||
/* Configuration */
|
||||
leaf CLICON_CONFIGFILE{
|
||||
type string;
|
||||
description
|
||||
|
|
@ -497,6 +519,7 @@ module clixon-config {
|
|||
This field is a 'bootstrap' field.
|
||||
";
|
||||
}
|
||||
/* YANG */
|
||||
leaf CLICON_YANG_MAIN_FILE {
|
||||
type string;
|
||||
description
|
||||
|
|
@ -599,6 +622,7 @@ module clixon-config {
|
|||
See also CLICON_XMLDB_MODSTATE where the module state info is used to tag datastores
|
||||
with module information.";
|
||||
}
|
||||
/* Backend */
|
||||
leaf CLICON_BACKEND_DIR {
|
||||
type string;
|
||||
description
|
||||
|
|
@ -653,6 +677,7 @@ module clixon-config {
|
|||
- on enable change, make the state as configured
|
||||
Disable if you start the restconf daemon by other means.";
|
||||
}
|
||||
/* Netconf */
|
||||
leaf CLICON_NETCONF_DIR{
|
||||
type string;
|
||||
description "Location of netconf (frontend) .so plugins";
|
||||
|
|
@ -725,6 +750,7 @@ module clixon-config {
|
|||
apart from NETCONF.
|
||||
Only if CLICON_NETCONF_MONITORING";
|
||||
}
|
||||
/* HTTP and Restconf */
|
||||
leaf CLICON_RESTCONF_API_ROOT {
|
||||
type string;
|
||||
default "/restconf";
|
||||
|
|
@ -840,6 +866,7 @@ module clixon-config {
|
|||
Both feature clixon-restconf:http-data and restconf/enable-http-data
|
||||
must be enabled for this match to occur.";
|
||||
}
|
||||
/* Clixon CLI */
|
||||
leaf CLICON_CLI_DIR {
|
||||
type string;
|
||||
description
|
||||
|
|
@ -987,6 +1014,7 @@ module clixon-config {
|
|||
description
|
||||
"Default CLI output format.";
|
||||
}
|
||||
/* Internal socket */
|
||||
leaf CLICON_SOCK_FAMILY {
|
||||
type socket_address_family;
|
||||
default UNIX;
|
||||
|
|
@ -1056,6 +1084,7 @@ module clixon-config {
|
|||
Also, any edits in candidate are discarded if the client closes the connection.
|
||||
This effectively disables shared candidate";
|
||||
}
|
||||
/* Datastore XMLDB */
|
||||
leaf CLICON_DATASTORE_CACHE {
|
||||
type datastore_cache;
|
||||
default cache;
|
||||
|
|
@ -1201,6 +1230,7 @@ module clixon-config {
|
|||
The current only case where such a user is used is in RESTCONF authentication when
|
||||
auth-type=none and no known user is known.";
|
||||
}
|
||||
/* Network Configuration Access Control Model (NACM) */
|
||||
leaf CLICON_NACM_MODE {
|
||||
type nacm_mode;
|
||||
default disabled;
|
||||
|
|
@ -1255,6 +1285,7 @@ module clixon-config {
|
|||
If CLICON_MODULE_LIBRARY_RFC7895 is enabled, it sets the modules-state/module-set-id
|
||||
instead";
|
||||
}
|
||||
/* Notification streams */
|
||||
leaf CLICON_STREAM_DISCOVERY_RFC5277 {
|
||||
type boolean;
|
||||
default false;
|
||||
|
|
@ -1311,6 +1342,27 @@ module clixon-config {
|
|||
description "Retention for stream replay buffers in seconds, ie how much
|
||||
data to store before dropping. 0 means no retention";
|
||||
}
|
||||
/* Log and debug */
|
||||
leaf CLICON_DEBUG{
|
||||
type cl:clixon_debug_t;
|
||||
description
|
||||
"Debug flags as bitfields.
|
||||
Can also be given directly as -D <flag> to clixon commands (which overrides this).";
|
||||
}
|
||||
leaf CLICON_LOG_DESTINATION {
|
||||
type log_destination_t;
|
||||
description
|
||||
"Log destination.
|
||||
If not given, default log destination is syslog for all applications,
|
||||
except clixon_cli where default is stderr.
|
||||
See also command-line option -l <s|e|o|n|f>";
|
||||
}
|
||||
leaf CLICON_LOG_FILE {
|
||||
type string;
|
||||
description
|
||||
"Which file to log to if log destination is file
|
||||
That is CLIXON_LOG_DESTINATION is FILE or command started with -l f";
|
||||
}
|
||||
leaf CLICON_LOG_STRING_LIMIT {
|
||||
type uint32;
|
||||
default 0;
|
||||
|
|
@ -1318,8 +1370,8 @@ module clixon-config {
|
|||
"Length limitation of debug and log strings.
|
||||
Especially useful for dynamic debug strings, such as packet dumps.
|
||||
0 means no limit";
|
||||
|
||||
}
|
||||
/* SNMP */
|
||||
leaf-list CLICON_SNMP_MIB {
|
||||
description
|
||||
"Names of MIBs that are used by clixon_snmp.
|
||||
|
|
|
|||
|
|
@ -193,7 +193,7 @@ module clixon-lib {
|
|||
"Debug flags.
|
||||
Flags are seperated into subject areas and detail
|
||||
Can also be given directly as -D <flag> to clixon commands
|
||||
Note there are also constants in the code thaht need to be in sync with these values";
|
||||
Note there are also constants in the code that need to be in sync with these values";
|
||||
type bits {
|
||||
/* Subjects: */
|
||||
bit default {
|
||||
|
|
@ -345,7 +345,9 @@ module clixon-lib {
|
|||
A sub-object will not be noted";
|
||||
}
|
||||
rpc debug {
|
||||
description "Set debug level of backend.";
|
||||
description
|
||||
"Set debug flags of backend.
|
||||
Note only numerical values";
|
||||
input {
|
||||
leaf level {
|
||||
type uint32;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue