Re: [Exim] Syslog lovers please test

Pàgina inicial
Delete this message
Reply to this message
Autor: Dave C.
Data:  
A: Philip Hazel
CC: exim-users
Assumpte: Re: [Exim] Syslog lovers please test

Interesting timing. One of our programmers just mailed me his work on
this. His rewrites it to do syslog ONLY. I'm forwading it in case it
has any good ideas you want to borrow.

I haven't had a chance to test either the official syslogging or this
one, but intend to do so as soon as I can find a few moments free at my
desk. I actually have been VERY busy the past month or two, and wasn't
even aware of the syslog discussion going on the list until today.


On Thu, 16 Sep 1999, Philip Hazel wrote:

> I have done the work to allow Exim to log to syslog instead of, or as
> well as, to local files. I have taken a minimalist approach - no
> options, no messing with contents of log lines. The results can be
> found in a testing release:
>
> ftp://ftp.cus.cam.ac.uk/pub/software/programs/exim/Testing/exim-3.036.tar.gz
>
> Details of the syslog facility are in doc/NewStuff. Please could those
> who are interested in syslog try out the new facility and give me some
> feedback.
>
> Philip
>
> -- 
> Philip Hazel            University of Cambridge Computing Service,
> ph10@???      Cambridge, England. Phone: +44 1223 334714.

>
>
>
> --
> ## List details at http://www.exim.org/mailman/listinfo/exim-users Exim details at http://www.exim.org/ ##
>

/*************************************************
*     Exim - an Internet mail transport agent    *
*************************************************/

/* Copyright (c) University of Cambridge 1995 - 1999 */
/* See the file NOTICE for conditions of use and distribution. */

/* Functions for writing log files. */

/* Changed to use only syslog by Peter Eisentraut
   (peter@???) on 1999-08-27. */

#include "exim.h"

#define LOG_NAME_SIZE 256



/*************************************************
*            Write message to log file           *
*************************************************/

/* This now uses the syslog and makes everything much less cluttered.

   The flags determine what priority the message will be written with,
   and in the case of the panic log, whether the process should die afterwards.

   The variable really_exim is TRUE only when exim is running in privileged state
   (i.e. not with a changed configuration or with testing options such as -brw).
   If it is not, don't try to write to the log (permission will probably be
   denied) - just write to log_stderr instead.

   Avoid actually writing to the logs when exim is called with -bv or -bt to
   test an address, but take other actions, such as panicking.

   If a message_id exists, we include it.

   Arguments:
   flags     each bit indicates some independent action:
   LOG_SENDER      add raw sender to the message
   LOG_RECIPIENTS  add raw recipients list to message
   LOG_MAIN        write to main log
   LOG_PROCESS     write to process log
   LOG_REJECT      write to reject log
   LOG_PANIC       write to panic log
   LOG_PANIC_DIE   write to panic log and then crash
   LOG_CONFIG      add "Exim configuration error:\n  "
   LOG_CONFIG2     add "Exim configuration error for "

   level     write to main long only if log_level is >= this value
   format    a printf() format
   ...       arguments for format

   Returns:    nothing
 */

void log_write(int level, int flags, char *format,...)
{
    char *ptr;
    BOOL testing = verify_only || address_test_mode || host_checking;
    va_list ap;
    char buffer[LOG_NAME_SIZE];


/* If debugging, show all log entries, but don't show headers. Do it all
   in one go so that it doesn't get split when multi-processing. */

    DEBUG(1) {
    ptr = buffer;
    sprintf(ptr, "LOG: %d%s%s%s%s\n  ", level,
        ((flags & LOG_MAIN) != 0) ? " MAIN" : "",
        ((flags & LOG_PANIC) != 0) ? " PANIC" : "",
        ((flags & LOG_PROCESS) != 0) ? " PROCESS" : "",
        ((flags & LOG_REJECT) != 0) ? " REJECT" : "");
    if ((flags & LOG_CONFIG) != 0)
        strcat(ptr, "Exim configuration error\n  ");
    else if ((flags & LOG_CONFIG2) != 0)
        strcat(ptr, "Exim configuration error for ");
    while (*ptr)
        ptr++;

    va_start(ap, format);
    if (!string_vformat(ptr, LOG_BUFFER_SIZE - (ptr - buffer) - 1, format, ap))
        strcpy(ptr, "**** log string overflowed log buffer ****\n");
    va_end(ap);

    while (*ptr)
        ptr++;
    strcat(ptr, "\n");
    fprintf(debug_file, "%s", buffer);
    fflush(debug_file);
    }

/* If no log file (i.e. main, panic, etc.) is specified, we are in a mess. */

    if (flags == 0)
    log_write(0, LOG_PANIC_DIE, "log_write called with no flags set");

/* Create the main message in the log buffer, including the message
   id except for the process log and when called by a utility.
   syslog already takes care of the time of day. */

    ptr = buffer;
    if (really_exim && (flags & LOG_PROCESS) == 0 && message_id[0] != 0)
    sprintf(ptr, "%s ", message_id);

    if ((flags & LOG_CONFIG) != 0)
    strcat(ptr, "Exim configuration error\n  ");
    else if ((flags & LOG_CONFIG2) != 0)
    strcat(ptr, "Exim configuration error for ");

    while (*ptr)
    ptr++;

    va_start(ap, format);
    if (!string_vformat(ptr, LOG_BUFFER_SIZE - (ptr - buffer) - 1, format, ap))
    strcpy(ptr, "**** log string overflowed log buffer ****\n");
    while (*ptr)
    ptr++;
    va_end(ap);

/* Add the raw, unrewritten, sender to the message if required. This is done
   this way because it kind of fits with LOG_RECIPIENTS. */

    if ((flags & LOG_SENDER) != 0 &&
    ptr < buffer + LOG_BUFFER_SIZE - 8 - (int) strlen(raw_sender)) {
    sprintf(ptr, " from <%s>", raw_sender);
    while (*ptr)
        ptr++;
    }
/* Add list of recipients to the message if required; the raw list,
   before rewriting, was saved in raw_recipients. */

    if ((flags & LOG_RECIPIENTS) != 0 && ptr < buffer + LOG_BUFFER_SIZE - 6) {
    int i;

    sprintf(ptr, " for");
    while (*ptr)
        ptr++;
    for (i = 0; i < recipients_count; i++) {
        char *s = raw_recipients[i];

        if (buffer + LOG_BUFFER_SIZE - ptr < (int) strlen(s) + 3)
        break;
        sprintf(ptr, " %s", s);
        while (*ptr)
        ptr++;
    }
    }
    sprintf(ptr, "\n");
    while (*ptr)
    ptr++;

/* Handle loggable errors when running a utility, or when address testing.
   Write to stderr unless debugging (when it will already have been written). */

    if (!really_exim || testing) {
    if (debug_level <= 0)
        fprintf(stderr, "LOG: %s", buffer);

    if ((flags & LOG_PANIC_DIE) == LOG_PANIC_DIE)
        exit(EXIT_FAILURE);
    return;
    }
/* Handle the main log. This will be logged as "mail" facility wiht priority
   of "info". */

    if ((flags & LOG_MAIN) != 0 && log_level >= level) {
#ifndef NO_OPENLOG
    openlog("exim", LOG_PID | LOG_CONS, LOG_MAIL);
#endif
    syslog(LOG_INFO, buffer);
    closelog();
    }
/* Handle the log for rejected messages: log recipients and the headers if any,
   but watch out for overflowing the buffer. Stick a separator between messages. */

    if ((flags & LOG_REJECT) != 0) {
    header_line *h;

    if (recipients_count > 0) {
        int i;

        /* The first recipient */

        string_format(ptr, LOG_BUFFER_SIZE - (ptr - buffer), "Recipients: %s\n",
              recipients_list[0].address);
        while (*ptr)
        ptr++;

        /* And up to 2 additional recipients */

        for (i = 1; i < recipients_count && i < 3; i++) {
        string_format(ptr, LOG_BUFFER_SIZE - (ptr - buffer), "    %s\n",
                  recipients_list[i].address);
        while (*ptr)
            ptr++;
        }

        if (i < recipients_count) {
        (void) string_format(ptr, LOG_BUFFER_SIZE - (ptr - buffer), "    ...\n");
        while (*ptr)
            ptr++;
        }
    }
    for (h = header_list; h != NULL; h = h->next) {
        if (!string_format(ptr, LOG_BUFFER_SIZE - (ptr - buffer), "%c %s",
                   h->type, h->text))
        break;
        while (*ptr)
        ptr++;
    }

    while (*ptr)
        ptr++;
    (void) string_format(ptr, LOG_BUFFER_SIZE - (ptr - buffer),
                 "----------------------------------------"
                 "--------------------------------------\n");
    while (*ptr)
        ptr++;

#ifndef NO_OPENLOG
    openlog("exim", LOG_PID | LOG_CONS, LOG_MAIL);
#endif
    syslog(LOG_INFO, buffer);
    closelog();
    }
/* Handle the process log file, where exim processes can be made to dump
   details of what they are doing by sending them a USR1 signal. Note that
   a message id is not automatically added above.
   This will be logged with a priority of notice to distinguish it from
   the main and reject logs. */

    if ((flags & LOG_PROCESS) != 0) {
#ifndef NO_OPENLOG
    openlog("exim", LOG_PID | LOG_CONS, LOG_MAIL);
#endif
    syslog(LOG_NOTICE, buffer);
    closelog();
    }
/* Handle the panic log. This will be logged as priority "emerg" (a.k.a. "panic").
   Also, try to write to log_stderr and/or debug_file. */

    if ((flags & LOG_PANIC) != 0) {
    if (log_stderr != NULL && log_stderr != debug_file)
        fprintf(log_stderr, "%s", buffer);

#ifndef NO_OPENLOG
    openlog("exim", LOG_PID | LOG_CONS, LOG_MAIL);
#endif
    syslog(LOG_EMERG, buffer);
    closelog();


    /* Give up if the DIE flag is set, but get rid of a partial message or try
       to close down an incoming SMTP call gracefully first. */

    if ((flags & LOG_PANIC_DIE) != LOG_PANIC) {
        if (accept_call_bombout)    /* No return from accept_bomb_out() */
        accept_bomb_out("Unexpected failure, please try later");
        if (smtp_input)
        smtp_closedown("Unexpected failure, please try later");
        exit(EXIT_FAILURE);
    }
    }
}



/*************************************************
*            Close any open log files            *
*************************************************/

void log_close_all(void)
{
    /* This is no longer used but is called by external functions. */
}


/* End of log.c */