From: Wouter Wijngaards Date: Wed, 26 Sep 2007 10:19:28 +0000 (+0000) Subject: syslog feature. X-Git-Tag: release-0.6~100 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bc9f482b2a2ea60a118f96839ae5f435656f519c;p=thirdparty%2Funbound.git syslog feature. git-svn-id: file:///svn/unbound/trunk@644 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/Makefile.in b/Makefile.in index 64ed245c8..f43493fb2 100644 --- a/Makefile.in +++ b/Makefile.in @@ -46,7 +46,7 @@ endif BUILD=build/ LINT=splint -LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 +LINTFLAGS=+quiet -weak -warnposix -unrecog -Din_addr_t=uint32_t -Du_int=unsigned -Du_char=uint8_t -preproc -Drlimit=rlimit64 +posixlib # compat with openssl linux edition. LINTFLAGS+="-DBN_ULONG=unsigned long" -Dkrb5_int32=int "-Dkrb5_ui_4=unsigned int" -DPQ_64BIT=uint64_t diff --git a/configure.ac b/configure.ac index 2b57840b8..04f8fb12b 100644 --- a/configure.ac +++ b/configure.ac @@ -269,7 +269,7 @@ AC_PROG_LIBTOOL # Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h sys/param.h sys/socket.h sys/uio.h arpa/inet.h syslog.h],,, [AC_INCLUDES_DEFAULT]) # check for types AC_CHECK_TYPE(int8_t, char) @@ -538,7 +538,7 @@ AC_ARG_WITH(ldns, AC_CHECK_LIB(ldns, ldns_rr_new,, [AC_MSG_ERROR([Can't find ldns library])]) -AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [512], [Define to the maximum message length to pass to syslog.]) +AC_DEFINE_UNQUOTED([MAXSYSLOGMSGLEN], [5120], [Define to the maximum message length to pass to syslog.]) AH_BOTTOM([ #include diff --git a/daemon/unbound.c b/daemon/unbound.c index 601863cbf..b3f31f903 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -284,7 +284,7 @@ do_chroot(struct daemon* daemon, struct config_file* cfg, int debug_mode) } /* init logfile just before fork */ - log_init(cfg->logfile); + log_init(cfg->logfile, cfg->use_syslog); if(!debug_mode && cfg->do_daemonize) { detach(cfg); } @@ -329,7 +329,7 @@ run_daemon(const char* cfgfile, int cmdline_verbose, int debug_mode) if(!done_chroot) { do_chroot(daemon, cfg, debug_mode); done_chroot = 1; - } + } else log_init(cfg->logfile, cfg->use_syslog); /* work */ daemon_fork(daemon); @@ -366,7 +366,7 @@ main(int argc, char* argv[]) /* take debug snapshot of heap */ unbound_start_brk = sbrk(0); - log_init(NULL); + log_init(NULL, 0); /* parse the options */ while( (c=getopt(argc, argv, "c:dhv")) != -1) { switch(c) { @@ -396,6 +396,6 @@ main(int argc, char* argv[]) } run_daemon(cfgfile, cmdline_verbose, debug_mode); - log_init(NULL); /* close logfile */ + log_init(NULL, 0); /* close logfile */ return 0; } diff --git a/doc/Changelog b/doc/Changelog index 86a31dd30..5b063c4de 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +26 September 2007: Wouter + - SIGHUP will reopen the log file. + - Option to log to syslog. + 25 September 2007: Wouter - tests for NSEC3. Fixup bitmap checks for NSEC3. - positive ANY response needs to check if wildcard expansion, and diff --git a/doc/example.conf b/doc/example.conf index b721c286a..bbe06ba83 100644 --- a/doc/example.conf +++ b/doc/example.conf @@ -112,8 +112,13 @@ server: # the working directory. # directory: "/etc/unbound" - # the log file, "" means log to stderr. + # the log file, "" means log to stderr. + # Use of this option sets use-syslog to "no". # logfile: "" + + # Log to syslog(3) if yes. The log facility LOG_DAEMON is used to + # log to, with identity "unbound". If yes, it overrides the logfile. + # use-syslog: yes # the pid file. # pidfile: "unbound.pid" diff --git a/doc/unbound.conf.5 b/doc/unbound.conf.5 index 71c5300a8..631ee40ed 100644 --- a/doc/unbound.conf.5 +++ b/doc/unbound.conf.5 @@ -39,9 +39,9 @@ example.conf file with all the options. # unbound.conf(5) config file for unbound(8). server: directory: "/etc/unbound" - username: unbound # make sure it can write to pidfile, logfile. + username: unbound # make sure it can write to pidfile. chroot: "/etc/unbound" - logfile: "/etc/unbound/unbound.log" + # logfile: "/etc/unbound/unbound.log" #uncomment to use logfile. pidfile: "/etc/unbound/unbound.pid" # verbosity: 1 # uncomment and increase to get more logging. .fi @@ -144,6 +144,13 @@ Sets the working directory for the program. If "" is given, logging goes to stderr, or nowhere once daemonized. The logfile is appended to, in the following format: [seconds since 1970] unbound[pid:tid]: type: message. +If this option is given, the use-syslog is option is set to "no". +.It \fBuse-syslog:\fR +Sets unbound to send log messages to the syslogd, using +.Xr syslog 3 . +The log facility LOG_DAEMON is used, with identity "unbound". +The logfile setting is overridden when use-syslog is turned on. +The default is to log to syslog. .It \fBpidfile:\fR The process id is written to the file. Default is "unbound.pid". So, kill -HUP `cat /etc/unbound/unbound.pid` will trigger a reload, diff --git a/testcode/lock_verify.c b/testcode/lock_verify.c index b1801aaff..f997b349b 100644 --- a/testcode/lock_verify.c +++ b/testcode/lock_verify.c @@ -403,7 +403,7 @@ main(int argc, char* argv[]) usage(); return 1; } - log_init(NULL); + log_init(NULL, 0); log_ident_set("lock-verify"); /* init */ all_locks = rbtree_create(order_lock_cmp); diff --git a/testcode/signit.c b/testcode/signit.c index b9cee166b..717b4e2de 100644 --- a/testcode/signit.c +++ b/testcode/signit.c @@ -236,7 +236,7 @@ process_nsec3(int argc, char* argv[]) /** main program */ int main(int argc, char* argv[]) { - log_init(NULL); + log_init(NULL, 0); if(argc != 6) { usage(); } diff --git a/testcode/testbound.c b/testcode/testbound.c index ebb0136ed..f20e89c80 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -135,6 +135,7 @@ setup_config(FILE* in, char* configfile, int* lineno, if(!cfg) fatal_exit("could not open %s: %s", configfile, strerror(errno)); line[MAX_LINE_LEN-1] = 0; + fprintf(cfg, "server: use-syslog: no\n"); while(fgets(line, MAX_LINE_LEN-1, in)) { parse = line; (*lineno)++; @@ -204,7 +205,7 @@ main(int argc, char* argv[]) char* init_optarg = optarg; struct replay_scenario* scen = NULL; - log_init(NULL); + log_init(NULL, 0); log_info("Start of %s testbound program.", PACKAGE_STRING); /* determine commandline options for the daemon */ cfgfile[0] = 0; diff --git a/testcode/unitmain.c b/testcode/unitmain.c index 5b2b766f7..1e2e9e971 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -205,7 +205,7 @@ infra_test() int main(int argc, char* argv[]) { - log_init(NULL); + log_init(NULL, 0); if(argc != 1) { printf("usage: %s\n", argv[0]); printf("\tperforms unit tests.\n"); diff --git a/util/config_file.c b/util/config_file.c index 14396dab5..a85a86483 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -75,6 +75,7 @@ config_create() cfg->do_ip6 = 1; cfg->do_udp = 1; cfg->do_tcp = 1; + cfg->use_syslog = 1; cfg->outgoing_base_port = cfg->port + 2000; cfg->outgoing_num_ports = 16; cfg->outgoing_num_tcp = 10; diff --git a/util/config_file.h b/util/config_file.h index a997d6c49..8f08d67cf 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -131,6 +131,9 @@ struct config_file { /** pidfile to write pid to. */ char* pidfile; + /** should log messages be sent to syslogd */ + int use_syslog; + /** do not report identity (id.server, hostname.bind) */ int hide_identity; /** do not report version (version.server, version.bind) */ diff --git a/util/configlexer.lex b/util/configlexer.lex index 124079505..5e537fd99 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -154,6 +154,7 @@ val-permissive-mode{COLON} { YDOUT; return VAR_VAL_PERMISSIVE_MODE;} key-cache-size{COLON} { YDOUT; return VAR_KEY_CACHE_SIZE;} key-cache-slabs{COLON} { YDOUT; return VAR_KEY_CACHE_SLABS;} val-nsec3-keysize-iterations{COLON} { YDOUT; return VAR_VAL_NSEC3_KEYSIZE_ITERATIONS;} +use-syslog{COLON} { YDOUT; return VAR_USE_SYSLOG;} {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++;} /* Quoted strings. Strip leading and ending quotes */ diff --git a/util/configparser.y b/util/configparser.y index 69beb445b..56ebe4d4f 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -84,7 +84,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_BOGUS_TTL VAR_VAL_CLEAN_ADDITIONAL VAR_VAL_PERMISSIVE_MODE %token VAR_INCOMING_NUM_TCP VAR_MSG_BUFFER_SIZE VAR_KEY_CACHE_SIZE %token VAR_KEY_CACHE_SLABS VAR_TRUSTED_KEYS_FILE -%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS +%token VAR_VAL_NSEC3_KEYSIZE_ITERATIONS VAR_USE_SYSLOG %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -122,7 +122,8 @@ content_server: server_num_threads | server_verbosity | server_port | server_val_clean_additional | server_val_permissive_mode | server_incoming_num_tcp | server_msg_buffer_size | server_key_cache_size | server_key_cache_slabs | - server_trusted_keys_file | server_val_nsec3_keysize_iterations + server_trusted_keys_file | server_val_nsec3_keysize_iterations | + server_use_syslog ; stubstart: VAR_STUB_ZONE { @@ -268,6 +269,20 @@ server_do_tcp: VAR_DO_TCP STRING free($2); } ; +server_use_syslog: VAR_USE_SYSLOG STRING + { + OUTYY(("P(server_use_syslog:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->use_syslog = (strcmp($2, "yes")==0); +#ifndef HAVE_SYSLOG_H + if(strcmp($2, "yes") == 0) + yyerror("no syslog services are available. " + "(reconfigure and compile to add)"); +#endif + free($2); + } + ; server_chroot: VAR_CHROOT STRING { OUTYY(("P(server_chroot:%s)\n", $2)); @@ -294,6 +309,7 @@ server_logfile: VAR_LOGFILE STRING OUTYY(("P(server_logfile:%s)\n", $2)); free(cfg_parser->cfg->logfile); cfg_parser->cfg->logfile = $2; + cfg_parser->cfg->use_syslog = 0; } ; server_pidfile: VAR_PIDFILE STRING diff --git a/util/log.c b/util/log.c index 9ee324cc0..26912bc01 100644 --- a/util/log.c +++ b/util/log.c @@ -43,7 +43,19 @@ #ifdef HAVE_TIME_H #include #endif +#ifdef HAVE_SYSLOG_H +# include +#else +/**define LOG_ constants */ +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 +#endif +/* default verbosity */ enum verbosity_value verbosity = 4; /** the file logged to. */ static FILE* logfile = 0; @@ -53,19 +65,36 @@ static int key_created = 0; static ub_thread_key_t logkey; /** the identity of this executable/process */ static const char* ident="unbound"; +#ifdef HAVE_SYSLOG_H +/** are we using syslog(3) to log to */ +static int log_to_syslog = 0; +#endif /* HAVE_SYSLOG_H */ void -log_init(const char* filename) +log_init(const char* filename, int use_syslog) { FILE *f; if(!key_created) { key_created = 1; ub_thread_key_create(&logkey, NULL); } - + if(logfile || log_to_syslog) + verbose(VERB_DETAIL, "switching log to %s", + use_syslog?"syslog":(filename&&filename[0]?filename:"stderr")); + if(logfile && logfile != stderr) + fclose(logfile); +#ifdef HAVE_SYSLOG_H + if(log_to_syslog) { + closelog(); + log_to_syslog = 0; + } + if(use_syslog) { + openlog(ident, 0, LOG_DAEMON); + log_to_syslog = 1; + return; + } +#endif /* HAVE_SYSLOG_H */ if(!filename || !filename[0]) { - if(logfile && logfile != stderr) - fclose(logfile); logfile = stderr; return; } @@ -76,9 +105,6 @@ log_init(const char* filename) strerror(errno)); return; } - verbose(VERB_DETAIL, "switching to logfile %s", filename); - if(logfile && logfile != stderr) - fclose(logfile); logfile = f; } @@ -93,14 +119,22 @@ void log_ident_set(const char* id) } void -log_vmsg(const char* type, const char *format, va_list args) +log_vmsg(int pri, const char* type, + const char *format, va_list args) { - char message[MAXSYSLOGMSGLEN * 10]; + char message[MAXSYSLOGMSGLEN]; unsigned int* tid = (unsigned int*)ub_thread_key_get(logkey); + (void)pri; vsnprintf(message, sizeof(message), format, args); - fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n", - (int)time(NULL), ident, (int)getpid(), - tid?*tid:0, type, message); +#ifdef HAVE_SYSLOG_H + if(log_to_syslog) { + syslog(pri, "[%d:%x] %s: %s", + (int)getpid(), tid?*tid:0, type, message); + return; + } +#endif /* HAVE_SYSLOG_H */ + fprintf(logfile, "[%d] %s[%d:%x] %s: %s\n", (int)time(NULL), + ident, (int)getpid(), tid?*tid:0, type, message); fflush(logfile); } @@ -113,7 +147,7 @@ log_info(const char *format, ...) { va_list args; va_start(args, format); - log_vmsg("info", format, args); + log_vmsg(LOG_INFO, "info", format, args); va_end(args); } @@ -126,7 +160,7 @@ log_err(const char *format, ...) { va_list args; va_start(args, format); - log_vmsg("error", format, args); + log_vmsg(LOG_ERR, "error", format, args); va_end(args); } @@ -139,7 +173,7 @@ log_warn(const char *format, ...) { va_list args; va_start(args, format); - log_vmsg("warning", format, args); + log_vmsg(LOG_WARNING, "warning", format, args); va_end(args); } @@ -152,7 +186,7 @@ fatal_exit(const char *format, ...) { va_list args; va_start(args, format); - log_vmsg("fatal error", format, args); + log_vmsg(LOG_CRIT, "fatal error", format, args); va_end(args); exit(1); } @@ -167,8 +201,13 @@ verbose(enum verbosity_value level, const char* format, ...) { va_list args; va_start(args, format); - if(verbosity >= level) - log_vmsg("note", format, args); + if(verbosity >= level) { + if(level == VERB_OPS) + log_vmsg(LOG_NOTICE, "notice", format, args); + else if(level == VERB_DETAIL) + log_vmsg(LOG_INFO, "info", format, args); + else log_vmsg(LOG_DEBUG, "debug", format, args); + } va_end(args); } diff --git a/util/log.h b/util/log.h index dd126a5e0..12dc6bfe5 100644 --- a/util/log.h +++ b/util/log.h @@ -77,8 +77,9 @@ void verbose(enum verbosity_value level, /** * call this to initialize logging services. * @param filename: if NULL stderr is used. + * @param use_syslog: set to true to ignore filename and use syslog(3). */ -void log_init(const char* filename); +void log_init(const char* filename, int use_syslog); /** * Init a thread (will print this number for the thread log entries). @@ -133,11 +134,12 @@ void fatal_exit(const char* format, ...) ATTR_FORMAT(printf, 1, 2); /** * va_list argument version of log_info. + * @param pri: priority type, for example 5 (INFO). * @param type: string to designate type of message (info, error). * @param format: the printf style format to print. no newline. * @param args: arguments for format string. */ -void log_vmsg(const char* type, const char* format, va_list args); +void log_vmsg(int pri, const char* type, const char* format, va_list args); /** always assert for now. */ #define UNBOUND_ASSERT 1