cli: Introduce a logfile command to log errors to a file
The evolution would be to introduce libosmocore and start using the logging framework. But even then we can map this option to the file target. Fixes: SYS#263
This commit is contained in:
parent
1c4d9e6d87
commit
9c0ff4fafe
|
@ -52,6 +52,7 @@ const char *gengetopt_args_info_help[] = {
|
|||
" --timelimit=INT Exit after timelimit seconds (default=`0')",
|
||||
" -a, --apn=STRING Access point name (default=`internet')",
|
||||
" -q, --qos=INT Requested quality of service (default=`0x0b921f')",
|
||||
" --logfile=STRING Logfile for errors",
|
||||
0
|
||||
};
|
||||
|
||||
|
@ -119,6 +120,7 @@ void clear_given (struct gengetopt_args_info *args_info)
|
|||
args_info->timelimit_given = 0 ;
|
||||
args_info->apn_given = 0 ;
|
||||
args_info->qos_given = 0 ;
|
||||
args_info->logfile_given = 0 ;
|
||||
}
|
||||
|
||||
static
|
||||
|
@ -155,6 +157,8 @@ void clear_args (struct gengetopt_args_info *args_info)
|
|||
args_info->apn_orig = NULL;
|
||||
args_info->qos_arg = 0x0b921f;
|
||||
args_info->qos_orig = NULL;
|
||||
args_info->logfile_arg = NULL;
|
||||
args_info->logfile_orig = NULL;
|
||||
|
||||
}
|
||||
|
||||
|
@ -181,6 +185,7 @@ void init_args_info(struct gengetopt_args_info *args_info)
|
|||
args_info->timelimit_help = gengetopt_args_info_help[15] ;
|
||||
args_info->apn_help = gengetopt_args_info_help[16] ;
|
||||
args_info->qos_help = gengetopt_args_info_help[17] ;
|
||||
args_info->logfile_help = gengetopt_args_info_help[18] ;
|
||||
|
||||
}
|
||||
|
||||
|
@ -290,6 +295,8 @@ cmdline_parser_release (struct gengetopt_args_info *args_info)
|
|||
free_string_field (&(args_info->apn_arg));
|
||||
free_string_field (&(args_info->apn_orig));
|
||||
free_string_field (&(args_info->qos_orig));
|
||||
free_string_field (&(args_info->logfile_arg));
|
||||
free_string_field (&(args_info->logfile_orig));
|
||||
|
||||
|
||||
|
||||
|
@ -356,6 +363,8 @@ cmdline_parser_dump(FILE *outfile, struct gengetopt_args_info *args_info)
|
|||
write_into_file(outfile, "apn", args_info->apn_orig, 0);
|
||||
if (args_info->qos_given)
|
||||
write_into_file(outfile, "qos", args_info->qos_orig, 0);
|
||||
if (args_info->logfile_given)
|
||||
write_into_file(outfile, "logfile", args_info->logfile_orig, 0);
|
||||
|
||||
|
||||
i = EXIT_SUCCESS;
|
||||
|
@ -626,6 +635,7 @@ cmdline_parser_internal (
|
|||
{ "timelimit", 1, NULL, 0 },
|
||||
{ "apn", 1, NULL, 'a' },
|
||||
{ "qos", 1, NULL, 'q' },
|
||||
{ "logfile", 1, NULL, 0 },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
|
@ -852,6 +862,20 @@ cmdline_parser_internal (
|
|||
additional_error))
|
||||
goto failure;
|
||||
|
||||
}
|
||||
/* Logfile for errors. */
|
||||
else if (strcmp (long_options[option_index].name, "logfile") == 0)
|
||||
{
|
||||
|
||||
|
||||
if (update_arg( (void *)&(args_info->logfile_arg),
|
||||
&(args_info->logfile_orig), &(args_info->logfile_given),
|
||||
&(local_args_info.logfile_given), optarg, 0, 0, ARG_STRING,
|
||||
check_ambiguity, override, 0, 0,
|
||||
"logfile", '-',
|
||||
additional_error))
|
||||
goto failure;
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
|
@ -31,5 +31,5 @@ option "timelimit" - "Exit after timelimit seconds" int default="0" no
|
|||
|
||||
option "apn" a "Access point name" string default="internet" no
|
||||
option "qos" q "Requested quality of service" int default="0x0b921f" no
|
||||
|
||||
option "logfile" - "Logfile for errors" string no
|
||||
|
||||
|
|
|
@ -89,6 +89,9 @@ struct gengetopt_args_info
|
|||
int qos_arg; /**< @brief Requested quality of service (default='0x0b921f'). */
|
||||
char * qos_orig; /**< @brief Requested quality of service original value given at command line. */
|
||||
const char *qos_help; /**< @brief Requested quality of service help description. */
|
||||
char * logfile_arg; /**< @brief Logfile for errors. */
|
||||
char * logfile_orig; /**< @brief Logfile for errors original value given at command line. */
|
||||
const char *logfile_help; /**< @brief Logfile for errors help description. */
|
||||
|
||||
unsigned int help_given ; /**< @brief Whether help was given. */
|
||||
unsigned int version_given ; /**< @brief Whether version was given. */
|
||||
|
@ -108,6 +111,7 @@ struct gengetopt_args_info
|
|||
unsigned int timelimit_given ; /**< @brief Whether timelimit was given. */
|
||||
unsigned int apn_given ; /**< @brief Whether apn was given. */
|
||||
unsigned int qos_given ; /**< @brief Whether qos was given. */
|
||||
unsigned int logfile_given ; /**< @brief Whether logfile was given. */
|
||||
|
||||
} ;
|
||||
|
||||
|
|
12
ggsn/ggsn.c
12
ggsn/ggsn.c
|
@ -283,6 +283,18 @@ int main(int argc, char **argv)
|
|||
if (cmdline_parser_configfile(args_info.conf_arg, &args_info, 0, 0, 0)
|
||||
!= 0)
|
||||
exit(1);
|
||||
|
||||
/* Open a log file */
|
||||
if (args_info.logfile_arg) {
|
||||
FILE* log_file = fopen(args_info.logfile_arg, "a");
|
||||
if (!log_file) {
|
||||
printf("Failed to open logfile: '%s'\n",
|
||||
args_info.logfile_arg);
|
||||
exit(1);
|
||||
}
|
||||
sys_err_setlogfile(log_file);
|
||||
}
|
||||
|
||||
if (args_info.debug_flag) {
|
||||
printf("cmdline_parser_configfile\n");
|
||||
printf("listen: %s\n", args_info.listen_arg);
|
||||
|
|
27
lib/syserr.c
27
lib/syserr.c
|
@ -20,6 +20,13 @@
|
|||
|
||||
#include "syserr.h"
|
||||
|
||||
static FILE* err_log;
|
||||
|
||||
void sys_err_setlogfile(FILE* log)
|
||||
{
|
||||
err_log = log;
|
||||
}
|
||||
|
||||
void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
@ -29,11 +36,17 @@ void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...)
|
|||
vsnprintf(buf, SYSERR_MSGSIZE, fmt, args);
|
||||
va_end(args);
|
||||
buf[SYSERR_MSGSIZE - 1] = 0; /* Make sure it is null terminated */
|
||||
if (en)
|
||||
if (en) {
|
||||
if (err_log)
|
||||
fprintf(err_log, "%s: %d: %d (%s) %s\n",
|
||||
fn, ln, en, strerror(en), buf);
|
||||
syslog(pri, "%s: %d: %d (%s) %s", fn, ln, en, strerror(en),
|
||||
buf);
|
||||
else
|
||||
} else {
|
||||
if (err_log)
|
||||
fprintf(err_log, "%s: %d: %s\n", fn, ln, buf);
|
||||
syslog(pri, "%s: %d: %s", fn, ln, buf);
|
||||
}
|
||||
}
|
||||
|
||||
void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer,
|
||||
|
@ -65,10 +78,16 @@ void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer,
|
|||
}
|
||||
buf2[pos] = 0;
|
||||
|
||||
if (en)
|
||||
if (en) {
|
||||
if (err_log)
|
||||
fprintf(err_log, "%s: %d: %d (%s) %s. %s\n",
|
||||
fn, ln, en, strerror(en), buf, buf2);
|
||||
syslog(pri, "%s: %d: %d (%s) %s. %s", fn, ln, en, strerror(en),
|
||||
buf, buf2);
|
||||
else
|
||||
} else {
|
||||
if (err_log)
|
||||
fprintf(err_log, "%s: %d: %s. %s\n", fn, ln, buf, buf2);
|
||||
syslog(pri, "%s: %d: %s. %s", fn, ln, buf, buf2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
#define SYSERR_MSGSIZE 256
|
||||
|
||||
void sys_err_setlogfile(FILE*);
|
||||
|
||||
void sys_err(int pri, char *filename, int en, int line, char *fmt, ...);
|
||||
void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer,
|
||||
void *pack, unsigned len, char *fmt, ...);
|
||||
|
|
Reference in New Issue