Logo Search packages:      
Sourcecode: rapple version File versions  Download package

logger.c

Go to the documentation of this file.
/*
   Name: $RCSfile: logger.c,v $
   Author: Alan Moran
   $Date: 2005/09/20 18:57:28 $
   $Revision: 1.14 $
   $Id: logger.c,v 1.14 2005/09/20 18:57:28 a_j_moran Exp $

   Legal Notice:

   This program is free software; you can redistribute it and/or
   modify it under the terms of the license contained in the
   COPYING file that comes with this distribution.

 */

/**
   @file

   @brief Application logging functionality.

   The logger module is concerned with all aspects of application logging and
   presents a simple interface with which to record messages of varying
   severity.  Log levels include DEBUG, INFO, WARN, ERROR and FATAL.  The
   choice of which log level to use and the location of the logfile are
   determined in the rapple configuration file.

*/

#include "globals.h"

static int llevel = 0;
static FILE *lp;

/**
   Opens the log file (if not already open) reporting errors to stderr.
 */
static void
00038 open_logfile() {
    rpl_str_t msg, logfile;
    /* only perform open if necessary */
    if(lp == NULL) {
        rpl_str_t lf = rpl_cfg_get_logfile();
            if(lf == NULL)
            {
                  fprintf(stderr, "%s\n", "Error! No logfile defined! See configuration file.\n");
                  exit(-1);
            }
        logfile = (strcmp(lf,RPL_STR_NUL) == 0) ? RPL_DEFAULT_LOGFILE : lf;
        errno = 0;
        if((lp = fopen(logfile, "a")) == NULL) {
            msg = rpl_message_get("LOGFILE_NOT_FOUND", RPL_EOM);
            fprintf(stderr, "Fatal: %s: %s (%s)\n", msg, logfile, strerror(errno));
            exit(EXIT_FAILURE);
        }
        llevel = rpl_cfg_get_loglevel();
        rpl_me_free (lf);
    }
}

/**
   Closes the log file (if not already closed) reporting errors to stderr.
 */
void
00064 rpl_log_close_logfile() {
    rpl_str_t msg;

    /* only perform close if necessary */
    if(lp != NULL) {
        errno = 0;
        if(fclose(lp) == EOF) {
            msg = rpl_message_get("LOGFILE_CLOSE_FAILURE",RPL_EOM);
            fprintf(stderr, "Fatal: %s: %s (%s)\n", msg, rpl_cfg_get_logfile(), strerror(errno));

            exit(EXIT_FAILURE);
        }
    }
}

/**
   Returns the current date/stamp (for marking log entries).

   @return  the current date/stamp as char.
 */
static rpl_str_t
00085 now() {
    time_t t;
    rpl_str_t dt_stmp;
    static size_t ctime_fmt_len = 25;

    t = time(NULL);
    /* according to POSIX ctime() returns time_t in a 25 character format (incl. \n and \0) */
    dt_stmp = (rpl_str_t)rpl_me_malloc(ctime_fmt_len);
    strncpy(dt_stmp, ctime(&t), ctime_fmt_len);
    /* remove the \n character that ctime() returns */
    dt_stmp[ctime_fmt_len - 1] = '\0';

    return dt_stmp;
}

/**
   Logs the message associated with msg under the log level indicated by RPL_LOG_LEVEL.

   @param RPL_LOG_LEVEL
   @param msg
 */
static void
00107 log_msg(rpl_c_str_t RPL_LOG_LEVEL, rpl_c_str_t msg) {
    rpl_str_t dts;

    assert((RPL_LOG_LEVEL != NULL) && (msg != NULL));

    open_logfile();
    dts = now();
    fprintf(lp, "[%-5s] %-24s : %s\n", RPL_LOG_LEVEL, dts, msg);
    (void)fflush(lp);
    rpl_me_free (dts);
}

/**
   EXPERIMENTAL
   logs the message associated with msg along with the file and line number where it was
   raised

   @param file
   @param line
   @param RPL_LOG_LEVEL
   @param msg
 */
void
00130 rpl_log_fl_msg(rpl_str_t file, int line, rpl_str_t RPL_LOG_LEVEL, rpl_str_t msg) {
    rpl_str_t dts;

    assert(msg != NULL);

    open_logfile();
    dts = now();
    fprintf(lp, "[%-5s] %-24s : %s (%s:%d)\n", RPL_LOG_LEVEL, dts, msg, file, line);
    (void)fflush(lp);
    rpl_me_free (dts);
}

/**
   Invokes the log function with DEBUG RPL_LOG_LEVEL if the llevel is low enough.

   @param msg
 */
void
00148 rpl_log_debug(rpl_c_str_t msg) {
    if(llevel <= RPL_LL_DEBUG)
        log_msg("DEBUG", msg);
}

/**
   Invokes the log function with INFO RPL_LOG_LEVEL if the llevel is low enough.

   @param msg
 */
void
00159 rpl_log_info(rpl_c_str_t msg) {
    if(llevel <= RPL_LL_INFO)
        log_msg("INFO", msg);
}

/**
   Invokes the log function with WARN RPL_LOG_LEVEL if the llevel is low enough.

   @param msg
 */
void
00170 rpl_log_warn(rpl_c_str_t msg) {
    if(llevel <= RPL_LL_WARN)
        log_msg("WARN", msg);
}

/**
   Invokes the log function with ERROR RPL_LOG_LEVEL if the llevel is low enough.

   @param msg
 */
void
00181 rpl_log_error(rpl_c_str_t msg) {
    if(llevel <= RPL_LL_ERROR)
        log_msg("ERROR", msg);
}

/**
   Invokes the log function with FATAL RPL_LOG_LEVEL and terminates.

   @param msg
 */
void
00192 rpl_log_fatal(rpl_c_str_t msg) {
    log_msg("FATAL", msg);
    /* since the does not return, the caller does not have opportunity to release resources */
    /* rpl_me_free(&msg); */
    log_msg("FATAL", "PROCESS_TERMINATED");
    rpl_log_close_logfile();
    exit(EXIT_FAILURE);
}

/**
   Sets the log level.

   @param s_llevel
 */
void
00207 rpl_log_set_level(int s_llevel) {
    llevel = s_llevel;
}

/**
   Returns the current log level.

   @return  the current log level.
 */
int
00217 rpl_log_get_level() {
    return llevel;
}

/**
   Returns description of loglevel.

   @param query_level

   @return  description of loglevel.
 */
rpl_str_t
00229 rpl_log_get_level_desc(int query_level) {
    rpl_str_t desc;

    desc = (rpl_str_t) rpl_me_malloc(20);
    switch(query_level) {
    case RPL_LL_DEBUG:
        strcpy(desc,"DEBUG");
        break;
    case RPL_LL_INFO:
        strcpy(desc,"INFO");
        break;
    case RPL_LL_WARN:
        strcpy(desc,"WARNING");
        break;
    case RPL_LL_ERROR:
        strcpy(desc,"ERROR");
        break;
    case RPL_LL_FATAL:
        strcpy(desc,"FATAL");
        break;
    default:
        strcpy(desc,"Unknown");
        break;
    }

    return desc;
}


Generated by  Doxygen 1.6.0   Back to index