Make syslog and file loggers configurable at runtime

This commit is contained in:
Tobias Brunner
2012-10-18 14:42:10 +02:00
parent 18a8893e8e
commit d35d669180
8 changed files with 186 additions and 81 deletions
+97 -11
View File
@@ -17,10 +17,15 @@
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include "file_logger.h"
#include <daemon.h>
#include <threading/mutex.h>
#include <threading/rwlock.h>
typedef struct private_file_logger_t private_file_logger_t;
@@ -35,7 +40,12 @@ struct private_file_logger_t {
file_logger_t public;
/**
* output file
* File name of the target
*/
char *filename;
/**
* Current output file
*/
FILE *out;
@@ -58,6 +68,11 @@ struct private_file_logger_t {
* Mutex to ensure multi-line log messages are not torn apart
*/
mutex_t *mutex;
/**
* Lock to read/write options (FD, levels, time_format, etc.)
*/
rwlock_t *lock;
};
METHOD(logger_t, log_, void,
@@ -69,6 +84,12 @@ METHOD(logger_t, log_, void,
struct tm tm;
time_t t;
this->lock->read_lock(this->lock);
if (!this->out)
{ /* file is not open */
this->lock->unlock(this->lock);
return;
}
if (this->time_format)
{
t = time(NULL);
@@ -117,17 +138,24 @@ METHOD(logger_t, log_, void,
current = next + 1;
}
this->mutex->unlock(this->mutex);
this->lock->unlock(this->lock);
}
METHOD(logger_t, get_level, level_t,
private_file_logger_t *this, debug_t group)
{
return this->levels[group];
level_t level;
this->lock->read_lock(this->lock);
level = this->levels[group];
this->lock->unlock(this->lock);
return level;
}
METHOD(file_logger_t, set_level, void,
private_file_logger_t *this, debug_t group, level_t level)
{
this->lock->write_lock(this->lock);
if (group < DBG_ANY)
{
this->levels[group] = level;
@@ -139,23 +167,81 @@ METHOD(file_logger_t, set_level, void,
this->levels[group] = level;
}
}
this->lock->unlock(this->lock);
}
METHOD(file_logger_t, set_options, void,
private_file_logger_t *this, char *time_format, bool ike_name)
{
this->lock->write_lock(this->lock);
free(this->time_format);
this->time_format = strdupnull(time_format);
this->ike_name = ike_name;
this->lock->unlock(this->lock);
}
/**
* Close the current file, if any
*/
static void close_file(private_file_logger_t *this)
{
if (this->out && this->out != stdout && this->out != stderr)
{
fclose(this->out);
this->out = NULL;
}
}
METHOD(file_logger_t, open_, void,
private_file_logger_t *this, bool flush_line, bool append)
{
FILE *file;
if (streq(this->filename, "stderr"))
{
file = stderr;
}
else if (streq(this->filename, "stdout"))
{
file = stdout;
}
else
{
file = fopen(this->filename, append ? "a" : "w");
if (file == NULL)
{
DBG1(DBG_DMN, "opening file %s for logging failed: %s",
this->filename, strerror(errno));
return;
}
if (flush_line)
{
setlinebuf(file);
}
}
this->lock->write_lock(this->lock);
close_file(this);
this->out = file;
this->lock->unlock(this->lock);
}
METHOD(file_logger_t, destroy, void,
private_file_logger_t *this)
{
if (this->out != stdout && this->out != stderr)
{
fclose(this->out);
}
this->lock->write_lock(this->lock);
close_file(this);
this->lock->unlock(this->lock);
this->mutex->destroy(this->mutex);
this->lock->destroy(this->lock);
free(this->time_format);
free(this->filename);
free(this);
}
/*
* Described in header.
*/
file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name)
file_logger_t *file_logger_create(char *filename)
{
private_file_logger_t *this;
@@ -166,16 +252,16 @@ file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name)
.get_level = _get_level,
},
.set_level = _set_level,
.set_options = _set_options,
.open = _open_,
.destroy = _destroy,
},
.out = out,
.time_format = time_format,
.ike_name = ike_name,
.filename = strdup(filename),
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
set_level(this, DBG_ANY, LEVEL_SILENT);
return &this->public;
}
+24 -5
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -43,6 +44,22 @@ struct file_logger_t {
*/
void (*set_level) (file_logger_t *this, debug_t group, level_t level);
/**
* Set options used by this logger
*
* @param time_format format of timestamp prefix, as in strftime(), cloned
* @param ike_name TRUE to prefix the name of the IKE_SA
*/
void (*set_options) (file_logger_t *this, char *time_format, bool ike_name);
/**
* Open (or reopen) the log file according to the given parameters
*
* @param flush_line TRUE to flush buffers after every logged line
* @param append FALSE to overwrite an existing file, TRUE to append
*/
void (*open) (file_logger_t *this, bool flush_line, bool append);
/**
* Destroys a file_logger_t object.
*/
@@ -52,11 +69,13 @@ struct file_logger_t {
/**
* Constructor to create a file_logger_t object.
*
* @param out FILE to write to
* @param time_format format of timestamp prefix, as in strftime()
* @param ike_name TRUE to prefix the name of the IKE_SA
* @return file_logger_t object
* The logger has to be opened via file_logger_t.open() before anything is
* logged.
*
* @param filename name of the log file (stderr and stdout are handled
* specially), cloned
* @return file_logger_t object
*/
file_logger_t *file_logger_create(FILE *out, char *time_format, bool ike_name);
file_logger_t *file_logger_create(char *filename);
#endif /** FILE_LOGGER_H_ @}*/
+28 -4
View File
@@ -21,6 +21,7 @@
#include "sys_logger.h"
#include <threading/mutex.h>
#include <threading/rwlock.h>
typedef struct private_sys_logger_t private_sys_logger_t;
@@ -53,6 +54,11 @@ struct private_sys_logger_t {
* Mutex to ensure multi-line log messages are not torn apart
*/
mutex_t *mutex;
/**
* Lock to read/write options (levels, ike_name)
*/
rwlock_t *lock;
};
METHOD(logger_t, log_, void,
@@ -65,6 +71,7 @@ METHOD(logger_t, log_, void,
/* cache group name and optional name string */
snprintf(groupstr, sizeof(groupstr), "%N", debug_names, group);
this->lock->read_lock(this->lock);
if (this->ike_name && ike_sa)
{
if (ike_sa->get_peer_cfg(ike_sa))
@@ -78,6 +85,7 @@ METHOD(logger_t, log_, void,
ike_sa->get_unique_id(ike_sa));
}
}
this->lock->unlock(this->lock);
/* do a syslog for every line */
this->mutex->lock(this->mutex);
@@ -100,12 +108,18 @@ METHOD(logger_t, log_, void,
METHOD(logger_t, get_level, level_t,
private_sys_logger_t *this, debug_t group)
{
return this->levels[group];
level_t level;
this->lock->read_lock(this->lock);
level = this->levels[group];
this->lock->unlock(this->lock);
return level;
}
METHOD(sys_logger_t, set_level, void,
private_sys_logger_t *this, debug_t group, level_t level)
{
this->lock->write_lock(this->lock);
if (group < DBG_ANY)
{
this->levels[group] = level;
@@ -117,12 +131,21 @@ METHOD(sys_logger_t, set_level, void,
this->levels[group] = level;
}
}
this->lock->unlock(this->lock);
}
METHOD(sys_logger_t, set_options, void,
private_sys_logger_t *this, bool ike_name)
{
this->lock->write_lock(this->lock);
this->ike_name = ike_name;
this->lock->unlock(this->lock);
}
METHOD(sys_logger_t, destroy, void,
private_sys_logger_t *this)
{
closelog();
this->lock->destroy(this->lock);
this->mutex->destroy(this->mutex);
free(this);
}
@@ -130,7 +153,7 @@ METHOD(sys_logger_t, destroy, void,
/*
* Described in header.
*/
sys_logger_t *sys_logger_create(int facility, bool ike_name)
sys_logger_t *sys_logger_create(int facility)
{
private_sys_logger_t *this;
@@ -141,11 +164,12 @@ sys_logger_t *sys_logger_create(int facility, bool ike_name)
.get_level = _get_level,
},
.set_level = _set_level,
.set_options = _set_options,
.destroy = _destroy,
},
.facility = facility,
.ike_name = ike_name,
.mutex = mutex_create(MUTEX_TYPE_DEFAULT),
.lock = rwlock_create(RWLOCK_TYPE_DEFAULT),
);
set_level(this, DBG_ANY, LEVEL_SILENT);
+9 -2
View File
@@ -1,4 +1,5 @@
/*
* Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -43,6 +44,13 @@ struct sys_logger_t {
*/
void (*set_level) (sys_logger_t *this, debug_t group, level_t level);
/**
* Set options used by this logger.
*
* @param ike_name TRUE to prefix the name of the IKE_SA
*/
void (*set_options) (sys_logger_t *this, bool ike_name);
/**
* Destroys a sys_logger_t object.
*/
@@ -53,9 +61,8 @@ struct sys_logger_t {
* Constructor to create a sys_logger_t object.
*
* @param facility syslog facility to use
* @param ike_name TRUE to prefix the name of the IKE_SA
* @return sys_logger_t object
*/
sys_logger_t *sys_logger_create(int facility, bool ike_name);
sys_logger_t *sys_logger_create(int facility);
#endif /** SYS_LOGGER_H_ @}*/