From 5164db36033de71834ceee4e7f9eb1a74afd64df Mon Sep 17 00:00:00 2001 From: Olof Hagsand Date: Thu, 26 Jul 2018 20:13:02 +0200 Subject: [PATCH] Added clicon_log_init(.., CLICON_LOG_FILE) option and clicon_log_file() for c\ ases where neither syslog or stderr is useful. --- CHANGELOG.md | 3 ++- apps/backend/backend_main.c | 1 + apps/cli/cli_main.c | 1 + apps/netconf/netconf_main.c | 1 + apps/restconf/Makefile.in | 4 ++-- apps/restconf/restconf_main.c | 29 ++++++++++++++++++++----- configure | 20 ++++++----------- configure.ac | 2 ++ lib/clixon/clixon_log.h | 4 +++- lib/src/clixon_log.c | 41 +++++++++++++++++++++++++++-------- 10 files changed, 75 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23ad263a..45ba4a4f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,11 +7,12 @@ ### API changes on existing features (you may need to change your code) ### Minor changes +* Added clicon_log_init(.., CLICON_LOG_FILE) option and clicon_log_file() for cases where neither syslog or stderr is useful. * Obsoleted COMPAT_CLIV and COMPAT_XSL that were optional in 3.7 * Added -l option for clixon_backend for directing syslog to stderr or stdout if running in foreground ### Corrected Bugs -* Setting /www-data with www-data as owner, see https://github.com/clicon/clixon/issues/37 +* Set dir /www-data with www-data as owner, see https://github.com/clicon/clixon/issues/37 ### Known issues * Namespace name relabeling is not supported. diff --git a/apps/backend/backend_main.c b/apps/backend/backend_main.c index 7a273294..0785adf5 100644 --- a/apps/backend/backend_main.c +++ b/apps/backend/backend_main.c @@ -98,6 +98,7 @@ backend_terminate(clicon_handle h) event_exit(); clicon_log_register_callback(NULL, NULL); clicon_debug(1, "%s done", __FUNCTION__); + clicon_log_exit(); return 0; } diff --git a/apps/cli/cli_main.c b/apps/cli/cli_main.c index e9cdc424..e2e2bb8f 100644 --- a/apps/cli/cli_main.c +++ b/apps/cli/cli_main.c @@ -84,6 +84,7 @@ cli_terminate(clicon_handle h) yspec_free(yspec); cli_plugin_finish(h); cli_handle_exit(h); + clicon_log_exit(); return 0; } diff --git a/apps/netconf/netconf_main.c b/apps/netconf/netconf_main.c index 1c203fff..543f015e 100644 --- a/apps/netconf/netconf_main.c +++ b/apps/netconf/netconf_main.c @@ -278,6 +278,7 @@ netconf_terminate(clicon_handle h) yspec_free(yspec); event_exit(); clicon_handle_exit(h); + clicon_log_exit(); return 0; } diff --git a/apps/restconf/Makefile.in b/apps/restconf/Makefile.in index 431d64cb..79a47104 100644 --- a/apps/restconf/Makefile.in +++ b/apps/restconf/Makefile.in @@ -50,8 +50,8 @@ sysconfdir = @sysconfdir@ includedir = @includedir@ HOST_VENDOR = @host_vendor@ -wwwdir = /www-data -wwwuser = www-data +wwwdir = @wwwdir@ +wwwuser = @wwwuser@ SH_SUFFIX = @SH_SUFFIX@ CLIXON_MAJOR = @CLIXON_VERSION_MAJOR@ diff --git a/apps/restconf/restconf_main.c b/apps/restconf/restconf_main.c index e43f6c96..b4390016 100644 --- a/apps/restconf/restconf_main.c +++ b/apps/restconf/restconf_main.c @@ -74,7 +74,7 @@ #include "restconf_methods.h" /* Command line options to be passed to getopt(3) */ -#define RESTCONF_OPTS "hDf:p:y:a:u:" +#define RESTCONF_OPTS "hDf:p:y:a:u:l:" /* RESTCONF enables deployments to specify where the RESTCONF API is located. The client discovers this by getting the "/.well-known/host-meta" @@ -85,6 +85,8 @@ #define RESTCONF_API "restconf" #define RESTCONF_API_ROOT "/restconf" +#define RESTCONF_LOGFILE "/www-data/clixon_restconf.log" + /*! Generic REST method, GET, PUT, DELETE, etc * @param[in] h CLIXON handle * @param[in] r Fastcgi request handle @@ -449,6 +451,7 @@ restconf_terminate(clicon_handle h) if ((yspec = clicon_dbspec_yang(h)) != NULL) yspec_free(yspec); clicon_handle_exit(h); + clicon_log_exit(); return 0; } @@ -490,7 +493,8 @@ usage(clicon_handle h, "\t-d \tSpecify restconf plugin directory dir (default: %s)\n" "\t-y \tOverride yang spec file (dont include .yang suffix)\n" "\t-a UNIX|IPv4|IPv6\tInternal backend socket family\n" - "\t-u \tInternal socket domain path or IP addr (see -a)\n", + "\t-u \tInternal socket domain path or IP addr (see -a)\n" + "\t-l \tLog on (s)yslog, (f)ile (syslog is default)\n", argv0, clicon_restconf_dir(h) ); @@ -515,9 +519,10 @@ main(int argc, char *yangspec=NULL; char *dir; char *tmp; + int logdst = CLICON_LOG_SYSLOG; /* In the startup, logs to stderr & debug flag set later */ - clicon_log_init(__PROGRAM__, LOG_INFO, CLICON_LOG_SYSLOG); + clicon_log_init(__PROGRAM__, LOG_INFO, logdst); /* Create handle */ if ((h = clicon_handle_init()) == NULL) goto done; @@ -551,14 +556,28 @@ main(int argc, usage(h, argv[0]); clicon_option_str_set(h, "CLICON_SOCK", optarg); break; + case 'l': /* Log destination: s|e|o */ + switch (optarg[0]){ + case 's': + logdst = CLICON_LOG_SYSLOG; + break; + case 'f': + logdst = CLICON_LOG_FILE; + if (clicon_log_file(RESTCONF_LOGFILE) < 0) + goto done; + break; + default: + usage(h, argv[0]); + } + break; default: usage(h, argv[0]); break; - } + } /* switch getopt */ argc -= optind; argv += optind; - clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, CLICON_LOG_SYSLOG); + clicon_log_init(__PROGRAM__, debug?LOG_DEBUG:LOG_INFO, logdst); clicon_debug_init(debug, NULL); clicon_log(LOG_NOTICE, "%s: %u Started", __PROGRAM__, getpid()); if (set_signal(SIGTERM, restconf_sig_term, NULL) < 0){ diff --git a/configure b/configure index 3eaead6b..c7d2bd1c 100755 --- a/configure +++ b/configure @@ -633,6 +633,8 @@ CPP OBJEXT EXEEXT ac_ct_CC +wwwuser +wwwdir with_restconf RANLIB SH_SUFFIX @@ -683,7 +685,6 @@ infodir docdir oldincludedir includedir -runstatedir localstatedir sharedstatedir sysconfdir @@ -760,7 +761,6 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' -runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1013,15 +1013,6 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; - -runstatedir | --runstatedir | --runstatedi | --runstated \ - | --runstate | --runstat | --runsta | --runst | --runs \ - | --run | --ru | --r) - ac_prev=runstatedir ;; - -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ - | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ - | --run=* | --ru=* | --r=*) - runstatedir=$ac_optarg ;; - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1159,7 +1150,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir runstatedir + libdir localedir mandir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1312,7 +1303,6 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -2449,6 +2439,10 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # If yes, compile apps/restconf +wwwdir=/www-data + +wwwuser=www-data + # ac_ext=c ac_cpp='$CPP $CPPFLAGS' diff --git a/configure.ac b/configure.ac index 03943911..7161ff62 100644 --- a/configure.ac +++ b/configure.ac @@ -89,6 +89,8 @@ AC_SUBST(LIBS) AC_SUBST(SH_SUFFIX) AC_SUBST(RANLIB) AC_SUBST(with_restconf) # If yes, compile apps/restconf +AC_SUBST(wwwdir,/www-data) +AC_SUBST(wwwuser,www-data) # AC_PROG_CC() AC_PROG_CPP diff --git a/lib/clixon/clixon_log.h b/lib/clixon/clixon_log.h index 7b833427..026d9ba4 100644 --- a/lib/clixon/clixon_log.h +++ b/lib/clixon/clixon_log.h @@ -44,6 +44,7 @@ #define CLICON_LOG_SYSLOG 1 /* print logs on syslog */ #define CLICON_LOG_STDERR 2 /* print logs on stderr */ #define CLICON_LOG_STDOUT 4 /* print logs on stdout */ +#define CLICON_LOG_FILE 8 /* print logs on clicon_log_filename */ /* * Types @@ -55,11 +56,12 @@ typedef int (clicon_log_notify_t)(int level, char *msg, void *arg); */ extern int debug; - /* * Prototypes */ int clicon_log_init(char *ident, int upto, int flags); +int clicon_log_exit(void); +int clicon_log_file(char *filename); int clicon_get_logflags(void); int clicon_log_str(int level, char *msg); #if defined(__GNUC__) && __GNUC__ >= 3 diff --git a/lib/src/clixon_log.c b/lib/src/clixon_log.c index 21d24bcc..7b3d2b75 100644 --- a/lib/src/clixon_log.c +++ b/lib/src/clixon_log.c @@ -66,8 +66,8 @@ static int _logflags = 0x0; static clicon_log_notify_t *_log_notify_cb = NULL; static void *_log_notify_arg = NULL; -/* Set to open file to bypass logging and write debug messages directly to file */ -static FILE *_debugfile = NULL; +/* Set to open file to write debug messages directly to file */ +static FILE *_logfile = NULL; /*! Initialize system logger. * @@ -97,6 +97,31 @@ clicon_log_init(char *ident, return 0; } +int +clicon_log_exit(void) +{ + if (_logfile) + fclose(_logfile); + return 0; +} + +/* If log flags include CLICON_LOG_FILE, set the file + * @param[in] filename File to log to + * @retval 0 OK + * @retval -1 Error + */ +int +clicon_log_file(char *filename) +{ + if (_logfile) + fclose(_logfile); + if ((_logfile = fopen(filename, "a")) == NULL){ + fprintf(stderr, "fopen: %s\n", strerror(errno)); /* dont use clicon_err here due to recursion */ + return -1; + } + return 0; +} + int clicon_get_logflags(void) { @@ -183,6 +208,10 @@ clicon_log_str(int level, flogtime(stdout); fprintf(stdout, "%s\n", msg); } + if ((_logflags & CLICON_LOG_FILE) && _logfile){ + flogtime(_logfile); + fprintf(_logfile, "%s\n", msg); + } if (_log_notify_cb){ static int cb = 0; char *d, *msg2; @@ -326,13 +355,7 @@ clicon_debug(int dbglevel, goto done; } va_end(args); - if (_debugfile != NULL){ /* Bypass syslog altogether */ - /* XXX: Here use date sub-routine as found in err_print1 */ - flogtime(_debugfile); - fprintf(_debugfile, "%s\n", msg); - } - else - clicon_log_str(LOG_DEBUG, msg); + clicon_log_str(LOG_DEBUG, msg); retval = 0; done: if (msg)