]> granicus.if.org Git - fcron/commitdiff
tweaked fcron logging to file
authorThibault Godouet <fcron@free.fr>
Tue, 1 Jan 2013 17:33:53 +0000 (17:33 +0000)
committerThibault Godouet <fcron@free.fr>
Tue, 1 Jan 2013 17:45:27 +0000 (17:45 +0000)
- only enabled for fcron via a command line option (rather than fcron.conf)
  I doubt people need this feature for command line tools, and we would need to manage the log file perms more closely to allow all tools to write to it
- reworked log.c/log.h: more sensible function names, better error checks
- changed the line format when logging to files/console
- added documentation on logging to file

14 files changed:
convert-fcrontab.c
doc/en/fcron.8.sgml
exe_list_test.c
fcron.c
fcron.h
fcronconf.c
fcronconf.h
fcrondyn.c
fcrondyn.h
fcronsighup.c
fcrontab.c
fcrontab.h
log.c
log.h

index c9414eaee5e7d6412d3d47871ba80311f4ab927d..f8acddf83d5eea1aeb5f36acba767e6048830e9d 100644 (file)
@@ -41,7 +41,6 @@ char foreground = 1;
 pid_t daemon_pid = 0;
 uid_t rootuid = 0;
 gid_t rootgid = 0;
-char dosyslog = 1;
 
 void
 info(void)
index deb181e3a0360e1de899ef5b20e2222815604d76..b57d364a71fb6d8ae94ce9f0bb5f3d992675074a 100644 (file)
@@ -39,6 +39,7 @@ A copy of the license is included in gfdl.sgml.
            <arg>-f</arg> 
            <arg>-o</arg>
            <arg>-y</arg>
+           <arg>-p <replaceable>file</replaceable></arg>
            <arg>-l <replaceable>time</replaceable></arg>
        </cmdsynopsis>
        <cmdsynopsis>
@@ -168,6 +169,16 @@ May be especially useful when used with options <option>-y</option> and
 in foreground.</para>
                </listitem>
            </varlistentry>
+           <varlistentry>
+               <term><option>-p</option> <replaceable>file</replaceable></term>
+               <term><option>--logfilepath</option>
+<replaceable>file</replaceable></term>
+               <listitem>
+                   <para>If set, log to the file given as argument. &fcron; will
+                    log to both that file and syslog in parallel unless
+                    <option>-y</option> is also set.</para>
+               </listitem>
+           </varlistentry>
            <varlistentry id="fcron.8.firstsleep">
                <term><option>-l</option> <replaceable>time</replaceable></term>
                <term><option>--firstsleep</option>
index a1210f03ec36afa6aba668482237dd4d5b45c7be..9fce0625b14142950539cd47e949bf349d62c6c0 100644 (file)
@@ -5,7 +5,6 @@
 /* required by log.c */
 char debug_opt = 1;
 char *prog_name = NULL;
-char dosyslog = 1;
 char foreground = 1;
 pid_t daemon_pid = 0;
 uid_t rootuid = 0;
diff --git a/fcron.c b/fcron.c
index 62edf3dd84f07978514996c89817334c15be77ff..1fbb84c2e41a0bcc179e95c35261006ec696a950 100644 (file)
--- a/fcron.c
+++ b/fcron.c
@@ -61,7 +61,6 @@ time_t first_sleep = FIRST_SLEEP;
 time_t save_time = SAVE;
 char once = 0;      /* set to 1 if fcron shall return immediately after running
                     * all jobs that are due at the time when fcron is started */
-char dosyslog = 1;  /* set to 1 when we log messages to syslog, else 0 */
 
 /* Get the default locale character set for the mail
  * "Content-Type: ...; charset=" header */
@@ -149,6 +148,7 @@ usage(void)
            "  -f     --foreground     Stay in foreground.\n"
            "  -b     --background     Go to background.\n"
            "  -y     --nosyslog       Don't log to syslog at all.\n"
+           "  -p     --logfilepath    If set, log to the file given as argument.\n"
            "  -o     --once           Execute all jobs that need to be run, wait for "
            "them,\n                          then return. Sets firstsleep to 0.\n"
            "                          Especially useful with -f and -y.\n"
@@ -312,6 +312,7 @@ parseopt(int argc, char *argv[])
        {"foreground", 0, NULL, 'f'},
        {"background", 0, NULL, 'b'},
        {"nosyslog", 0, NULL, 'y'},
+       {"logfilepath", 1, NULL, 'p'},
        {"help", 0, NULL, 'h'},
        {"version", 0, NULL, 'V'},
        {"once", 0, NULL, 'o'},
@@ -332,9 +333,9 @@ parseopt(int argc, char *argv[])
 
     while(1) {
 #ifdef HAVE_GETOPT_LONG
-       c = getopt_long(argc, argv, "dfbyhVos:l:m:c:n:q:", opt, NULL);
+       c = getopt_long(argc, argv, "dfbyp:hVos:l:m:c:n:q:", opt, NULL);
 #else
-       c = getopt(argc, argv, "dfbyhVos:l:m:c:n:q:");
+       c = getopt(argc, argv, "dfbyp:hVos:l:m:c:n:q:");
 #endif /* HAVE_GETOPT_LONG */
        if ( c == EOF ) break;
        switch ( (char)c ) {
@@ -356,6 +357,10 @@ parseopt(int argc, char *argv[])
 
        case 'y':
            dosyslog = 0; break;
+
+        case 'p':
+            logfile_path = strdup2(optarg);
+            break;
            
        case 'o':
            once = 1; first_sleep = 0; break;
@@ -539,6 +544,9 @@ main(int argc, char **argv)
     /* read fcron.conf and update global parameters */
     read_conf();
 
+    /* initialize the logs before we become a daemon */
+    xopenlog();
+
     /* change directory */
 
     if (chdir(fcrontabs) != 0)
diff --git a/fcron.h b/fcron.h
index e78fb9476db0120b1eafffdb7f7b066d9f220344..846d3e46f424ed5639d93c10b697fb7c2342f155 100644 (file)
--- a/fcron.h
+++ b/fcron.h
@@ -64,7 +64,6 @@
 /* global variables */
 extern time_t now;
 extern char foreground;
-extern char dosyslog;
 extern char default_mail_charset[TERM_LEN];
 extern time_t first_sleep;
 extern char *cdir;
index 1bf8c54b5f555fbfc8374cec809598d3a9e73b4c..cbfeb190f24322a8653becfb7ea1560a31c0fb0f 100644 (file)
@@ -40,7 +40,6 @@ char *pidfile = NULL;
 char *fifofile = NULL;
 char *fcronallow = NULL;
 char *fcrondeny = NULL;
-char *fcronlogfile = NULL;
 char *shell = NULL;
 char *sendmail = NULL;
 char *editor = NULL;
@@ -161,7 +160,6 @@ read_conf(void)
        else if ( strncmp(ptr1, "fifofile", namesize) == 0 ) { Set(fifofile , ptr2); }
        else if ( strncmp(ptr1, "fcronallow", namesize) == 0 ) { Set(fcronallow , ptr2); }
        else if ( strncmp(ptr1, "fcrondeny", namesize) == 0 ) { Set(fcrondeny , ptr2); }
-       else if ( strncmp(ptr1, "fcronlog", namesize) == 0 ) { Set(fcronlogfile, ptr2); }
        else if ( strncmp(ptr1, "shell", namesize) == 0 ) { Set(shell , ptr2); }
        else if ( strncmp(ptr1, "sendmail", namesize) == 0 ) { Set(sendmail , ptr2); }
        else if ( strncmp(ptr1, "editor", namesize) == 0 ) { Set(editor , ptr2); }
index fc06fe49c26218c79ac07add7e907563237ad83b..d211419a8f24f065269dbe72c9f49cc468dfe296 100644 (file)
@@ -33,7 +33,6 @@ extern char *fcronconf;
 extern char *fcronallow;
 extern char *fcrondeny;
 extern char *fcrontabs;
-extern char *fcronlogfile;
 extern char *pidfile;
 extern char *fifofile;
 extern char *editor;
index 84c3f33a1da2e2157b85e2318d231e1be4db9492..4d08f585570efd95a117db8e44927348c156054d 100644 (file)
@@ -57,7 +57,6 @@ char *cmd_str = NULL;
 /* needed by log part : */
 char *prog_name = NULL;
 char foreground = 1;
-char dosyslog = 1;
 pid_t daemon_pid = 0;
 
 /* uid/gid of user/group root 
index ca63136b61e6a29dcee3ca898f53251f177af1e0..d0bdf7212386cca16678032b7ed3b34206a4099b 100644 (file)
@@ -30,7 +30,6 @@
 #include "fcronconf.h"
 
 /* global variables */
-extern char dosyslog;
 extern pid_t daemon_pid;
 extern uid_t rootuid;
 extern gid_t rootgid;
index 7c6f603b519bd9afcbd4566130071cc848c497e9..aa4c80d79a2ae0a8284d11f862554a2ba76dc236 100644 (file)
@@ -40,7 +40,6 @@ gid_t rootgid = 0;
 /* needed by log part : */
 char *prog_name = NULL;
 char foreground = 1;
-char dosyslog = 1;
 pid_t daemon_pid = 0;
 
 
index bf84e1e71b2b790ac4291c052fe614359c33f7c1..63e681ae6b10a129414284f8c0d6c6bf172f2574 100644 (file)
@@ -85,7 +85,6 @@ char file[PATH_LEN];
 /* needed by log part : */
 char *prog_name = NULL;
 char foreground = 1;
-char dosyslog = 1;
 pid_t daemon_pid = 0;
 
 #ifdef HAVE_LIBPAM
index 08a9cdbd9a9c7f514cd3b062c57566a6a5aefd9b..37ae617e3442e54d25aa9472826c563e892d0259 100644 (file)
@@ -31,7 +31,6 @@
 
 /* global variables */
 extern pid_t daemon_pid;
-extern char dosyslog;
 extern struct cf_t *file_base;
 extern char *user;
 extern char *runas;
diff --git a/log.c b/log.c
index 69ee6919a0dab8d1e4aaa34025748be36f399e44..06e3c723f5453281a0ccf21265dfca6302cab7e5 100644 (file)
--- a/log.c
+++ b/log.c
@@ -22,7 +22,7 @@
  */
 
 
-/* This code is inspired by Anacron's sources of
+/* This code was originally inspired by Anacron's sources of
    Itai Tzur <itzur@actcom.co.il> */
 
 
@@ -38,16 +38,18 @@ char debug_opt = 1;       /* set to 1 if we are in debug mode */
 #else
 char debug_opt = 0;       /* set to 1 if we are in debug mode */
 #endif
+int dosyslog = 1;
+char *logfile_path = NULL;
 
 
-static void xopenlog(void);
 char* make_msg(const char *append, char *fmt, va_list args);
 void log_syslog_str(int priority, char *msg);
-void log_console_str(char *msg);
+void log_file_str(FILE *logfile, int priority, char *msg);
+void log_console_str(int priority, char *msg);
 void log_fd_str(int fd, char *msg);
-static void log_syslog(int priority, int fd, char *fmt, va_list args);
-static void log_e(int priority, char *fmt, va_list args);
-static void fcronlog(int priority, char *msg);
+static void print_line_prefix(FILE *logfile, int priority);
+static void xlog(int priority, int fd, char *fmt, va_list args);
+static void xlog_e(int priority, int fd, char *fmt, va_list args);
 #ifdef HAVE_LIBPAM
 static void log_pame(int priority, pam_handle_t *pamh, int pamerrno,
                     char *fmt, va_list args);
@@ -55,26 +57,46 @@ static void log_pame(int priority, pam_handle_t *pamh, int pamerrno,
 
 static char truncated[] = " (truncated)";
 static int log_open = 0;
-static FILE *logfd = NULL;
+static FILE *logfile = NULL;
 
 
 /* Initialise logging to either syslog or a file specified in fcron.conf,
  * or take no action if logging is suppressed.
+ * This function will be called automatically if you attempt to log something,
+ * however you may have to call it explicitely as it needs to run before the
+ * program becomes a daemon so as it can print any errors on the console.
  */
-static void
+void
 xopenlog(void)
 {
     if (log_open) 
        return;
 
-    // are we using syslog?
-    if (dosyslog && (fcronlogfile == NULL)) {
-       openlog(prog_name, LOG_PID, SYSLOG_FACILITY);
-    } else if (fcronlogfile != NULL) {
-       logfd = fopen(fcronlogfile, "a+");
+    /* we MUST set log_open to 1 before doing anything else. That way,
+     * if we call a function that logs something, which calls xopenlog,
+     * then we won't end up in a nasty loop */
+    log_open = 1;
+
+    // are we logging to a file or using syslog or not logging at all?
+    if (dosyslog) {
+        openlog(prog_name, LOG_PID, SYSLOG_FACILITY);
+    }
+
+    if (logfile_path != NULL) {
+        logfile = fopen(logfile_path, "a");
+        if (logfile == NULL) {
+            int saved_errno = errno;
+
+            if (dosyslog) {
+                /* we have already called openlog() which cannot fail */
+                syslog(COMPLAIN_LEVEL, "Could not fopen log file '%s': %s", logfile_path, strerror(saved_errno));
+            }
+
+            print_line_prefix(stderr, COMPLAIN_LEVEL);
+            fprintf(stderr, "Could not fopen log file '%s': %s\n", logfile_path, strerror(saved_errno));
+        }
     }
 
-    log_open = 1;
 }
 
 
@@ -85,10 +107,21 @@ xcloselog()
        return;
 
     // check whether we need to close syslog, or a file.
-    if (dosyslog && (fcronlogfile == NULL)) {
+    if (logfile != NULL) {
+       if (fclose(logfile)!= 0) {
+            int saved_errno = errno;
+
+            syslog(COMPLAIN_LEVEL, "Error while closing log file '%s': %s", logfile_path, strerror(saved_errno));
+
+            if (foreground == 1) {
+                print_line_prefix(stderr, COMPLAIN_LEVEL);
+                fprintf(stderr, "Error while closing log file '%s': %s\n", logfile_path, strerror(saved_errno));
+            }
+        }
+    }
+
+    if (dosyslog) {
        closelog();
-    } else if (fcronlogfile != NULL) {
-       fclose(logfd);
     }
 
     log_open = 0;
@@ -120,34 +153,38 @@ make_msg(const char *append, char *fmt, va_list args)
 }
 
 
-/* log a simple string to syslog/log file if needed */
+/* log a simple string to syslog if needed */
 void
 log_syslog_str(int priority, char *msg)
 {
     xopenlog();
 
-    if (dosyslog && (logfd == NULL)) {
+    if (dosyslog) {
        syslog(priority, "%s", msg);
-    } else if (logfd != NULL) {
-       fcronlog(priority, msg);
+    }
+}
+
+/* log a simple string to a log file if needed */
+void
+log_file_str(FILE *logfile, int priority, char *msg)
+{
+    xopenlog();
+
+    if (logfile != NULL) {
+       print_line_prefix(logfile, priority);
+        fprintf(logfile, "%s\n", msg);
+        fflush(logfile);
     }
 
 }
 
 /* log a simple string to console if needed */
 void
-log_console_str(char *msg)
+log_console_str(int priority, char *msg)
 {
     if (foreground == 1) {
-       time_t t = time(NULL);
-       struct tm *ft;
-       char date[30];
-
-       ft = localtime(&t);
-       date[0] = '\0';
-       strftime(date, sizeof(date), "%H:%M:%S", ft);
-       fprintf(stderr, "%s %s\n", date, msg);
-
+       print_line_prefix(stderr, priority);
+       fprintf(stderr, "%s\n", msg);
     }
 }
 
@@ -165,7 +202,7 @@ log_fd_str(int fd, char *msg)
  * "priority". */
 /* write it also to fd if positive, and to stderr if foreground==1 */
 static void
-log_syslog(int priority, int fd, char *fmt, va_list args)
+xlog(int priority, int fd, char *fmt, va_list args)
 {
     char *msg;
 
@@ -173,16 +210,17 @@ log_syslog(int priority, int fd, char *fmt, va_list args)
        return;
 
     log_syslog_str(priority, msg);
-    log_console_str(msg);
+    log_file_str(logfile, priority, msg);
+    log_console_str(priority, msg);
     log_fd_str(fd, msg);
 
     Free_safe(msg);
 }
 
-/* Same as log_syslog(), but also appends an error description corresponding
+/* Same as xlog(), but also appends an error description corresponding
  * to "errno". */
 static void
-log_e(int priority, char *fmt, va_list args)
+xlog_e(int priority, int fd, char *fmt, va_list args)
 {
     int saved_errno;
     char *msg;
@@ -193,14 +231,16 @@ log_e(int priority, char *fmt, va_list args)
        return ;
 
     log_syslog_str(priority, msg);
-    log_console_str(msg);
+    log_file_str(logfile, priority, msg);
+    log_console_str(priority, msg);
+    log_fd_str(fd, msg);
 
     Free_safe(msg);
 }
 
-/* write a message to the file specified by logfd. */
+/* write a message to the file specified by logfile. */
 static void
-fcronlog(int priority, char *msg)
+print_line_prefix(FILE *logfile, int priority)
 {
     time_t t = time(NULL);
     struct tm *ft;
@@ -210,25 +250,28 @@ fcronlog(int priority, char *msg)
     // print the current time as a string.
     ft = localtime(&t);
     date[0] = '\0';
-    strftime(date, sizeof(date), "%H:%M:%S", ft);
+    strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", ft);
 
     // is it an info/warning/error/debug message?
     switch(priority) {
-    case EXPLAIN_LEVEL:
-       type = "Information";
-       break;
-    case WARNING_LEVEL:
-       type = "Warning";
-       break;
-    case COMPLAIN_LEVEL:
-       type = "Error";
-       break;
-    case DEBUG_LEVEL:
-       type = "Debug";
+        case EXPLAIN_LEVEL:
+            type = " INFO";
+            break;
+        case WARNING_LEVEL:
+            type = " WARN";
+            break;
+        case COMPLAIN_LEVEL:
+            type = "ERROR";
+            break;
+        case DEBUG_LEVEL:
+            type = "DEBUG";
+            break;
+        default:
+            type = "UNKNOWN_SEVERITY";
     }
 
     // print the log message.
-    fprintf(logfd, "%s [ %s ]:\n%s\n\n", date, type, msg);
+    fprintf(logfile, "%s %s ", date, type);
 }
 
 
@@ -244,7 +287,7 @@ log_pame(int priority, pam_handle_t *pamh, int pamerrno, char *fmt, va_list args
         return ;
 
     log_syslog_str(priority, msg);
-    log_console_str(msg);
+    log_console_str(priority, msg);
 
     xcloselog();
 
@@ -260,7 +303,7 @@ explain(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(EXPLAIN_LEVEL, -1, fmt, args);
+    xlog(EXPLAIN_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
@@ -271,7 +314,7 @@ explain_fd(int fd, char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(EXPLAIN_LEVEL, fd, fmt, args);
+    xlog(EXPLAIN_LEVEL, fd, fmt, args);
     va_end(args);
 }
 
@@ -283,7 +326,7 @@ explain_e(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_e(EXPLAIN_LEVEL, fmt, args);
+    xlog_e(EXPLAIN_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
@@ -295,7 +338,7 @@ warn(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(WARNING_LEVEL, -1, fmt, args);
+    xlog(WARNING_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
@@ -306,7 +349,7 @@ warn_fd(int fd, char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(WARNING_LEVEL, fd, fmt, args);
+    xlog(WARNING_LEVEL, fd, fmt, args);
     va_end(args);
 }
 
@@ -318,7 +361,7 @@ warn_e(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_e(WARNING_LEVEL, fmt, args);
+    xlog_e(WARNING_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
@@ -330,7 +373,7 @@ error(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
+    xlog(COMPLAIN_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
@@ -341,7 +384,7 @@ error_fd(int fd, char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(COMPLAIN_LEVEL, fd, fmt, args);
+    xlog(COMPLAIN_LEVEL, fd, fmt, args);
     va_end(args);
 }
 
@@ -353,7 +396,7 @@ error_e(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_e(COMPLAIN_LEVEL, fmt, args);
+    xlog_e(COMPLAIN_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
@@ -380,7 +423,7 @@ die(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(COMPLAIN_LEVEL, -1, fmt, args);
+    xlog(COMPLAIN_LEVEL, -1, fmt, args);
     va_end(args);
     if (getpid() == daemon_pid) {
         error("Aborted");
@@ -405,7 +448,7 @@ die_e(char *fmt, ...)
    err_no = errno;
 
    va_start(args, fmt);
-   log_e(COMPLAIN_LEVEL, fmt, args);
+   xlog_e(COMPLAIN_LEVEL, -1, fmt, args);
    va_end(args);
    if (getpid() == daemon_pid) {
         error("Aborted");
@@ -447,7 +490,7 @@ Debug(char *fmt, ...)
     va_list args;
 
     va_start(args, fmt);
-    log_syslog(DEBUG_LEVEL, -1, fmt, args);
+    xlog(DEBUG_LEVEL, -1, fmt, args);
     va_end(args);
 }
 
diff --git a/log.h b/log.h
index 5bf643a1e04b88382ab4f163422ba9433649c675..d18e5c30796b24454a758d6f7b38ba4245e7598f 100644 (file)
--- a/log.h
+++ b/log.h
 #define __LOG_H__
 
 extern char debug_opt;
+extern char *logfile_path; /* path to a file to log to. Set to NULL to disable logging to a file */
+extern int dosyslog; /* set to 1 when we log messages to syslog, else 0 */
 
 /* functions prototypes */
+extern void xopenlog(void);
 extern void xcloselog(void);
 extern void explain(char *fmt, ...);
 extern void explain_fd(int fd, char *fmt, ...);