Simplify the logging code interaction with main

The existing syslog mask and msg level were essentially the same, as
setting the syslog mask was always also setting the msg level. Made
this more obvious by moving all the syslog handling code into the msg
module. This also give clean separation of responsibilities, and
reduces the code size, and makes the signal handlers simpler.

The significant change is dynamically allocate the ConfigManager so
that can be deleted explicitly, instead of when going out scope of
main, thus allowing for msg_shutdown to be called after this, as the
ConfigManager's destructor makes use of messaging. Being able to call
msg_shutdown mean syslog can be flushed/closed and pthread mutex not
left dangling.
master
Nicholas Brown 2017-02-20 16:02:40 +00:00 committed by Luca Boccassi
parent 8ce50f7d92
commit 5476edeae8
5 changed files with 39 additions and 54 deletions

View File

@ -4,7 +4,6 @@
bool run_program = true;
bool reload_config = false;
bool reset_syslog_mask = false;
#ifdef __APPLE__
semaphore_t mainSemaphore;

View File

@ -11,7 +11,6 @@
extern bool run_program;
extern bool reload_config;
extern bool reset_syslog_mask;
#ifdef __APPLE__
extern semaphore_t mainSemaphore;

View File

@ -30,7 +30,7 @@ extern "C" {
/** Maximum length of exception strings */
const int EXCEPTION_MAXLEN = 1024;
static int msg_level = LOG_UPTO(MSG_ERROR);
static int syslog_mask = LOG_UPTO(LOG_WARNING);
static bool quiet = false;
static bool journald_enabled = false;
static bool syslog_enabled = false;
@ -95,15 +95,26 @@ extern "C" {
// set stdout and stderr to non-buffered
setvbuf(stdout, NULL, _IONBF, 0);
setvbuf(stderr, NULL, _IONBF, 0);
if (msg_get_syslog()) {
setlogmask(syslog_mask);
openlog("vermont", LOG_PID, LOG_DAEMON);
}
}
/**
* deinitializes logging function's mutex
* vermont does not call this function
*/
void msg_shutdown()
{
pthread_mutex_destroy(&msg_mutex);
if (msg_get_syslog()) {
closelog();
}
int retval = pthread_mutex_destroy(&msg_mutex);
if (retval != 0) {
printf("!!! msg: pthread_mutex_destroy returned error code %d (%s)\n", retval, strerror(retval));
}
}
/**
@ -120,7 +131,9 @@ extern "C" {
// we must lock via mutex, else logging outputs are mixed when several
// threads log simultaneously
int retval = pthread_mutex_lock(&msg_mutex);
if (retval != 0) printf("!!! msg: pthread_mutex_lock returned error code %d (%s)\n", retval, strerror(retval));
if (retval != 0) {
printf("!!! msg: pthread_mutex_lock returned error code %d (%s)\n", retval, strerror(retval));
}
struct timeval tv;
gettimeofday(&tv, 0);
struct tm* tform = localtime(reinterpret_cast<time_t*>(&tv.tv_sec));
@ -158,7 +171,9 @@ extern "C" {
vsnprintf(logtext, EXCEPTION_MAXLEN-strlen(logtext), fmt, *args);
}
retval = pthread_mutex_unlock(&msg_mutex);
if (retval != 0) printf("!!! msg: pthread_mutex_unlock returned error code %d\n", retval);
if (retval != 0) {
printf("!!! msg: pthread_mutex_unlock returned error code %d\n", retval);
}
}
/**
@ -215,7 +230,8 @@ extern "C" {
*/
void msg_setlevel(int level)
{
msg_level=level;
syslog_mask=level;
setlogmask(level);
}
/**
@ -223,7 +239,7 @@ extern "C" {
*/
int msg_getlevel()
{
return msg_level;
return syslog_mask;
}
/**

View File

@ -47,9 +47,6 @@ void MainSignalHandler::handleSigUsr1(int x)
log_mask |= log_mask << 1;
}
msg_setlevel(log_mask);
reset_syslog_mask = true;
wakeupMainThread();
}
errno = errno_save;
@ -63,9 +60,6 @@ void MainSignalHandler::handleSigUsr2(int x)
if (log_mask != 0) {
log_mask &= log_mask >> 1;
msg_setlevel(log_mask);
reset_syslog_mask = true;
wakeupMainThread();
}
errno = errno_save;

View File

@ -34,7 +34,6 @@
#include <getopt.h>
#include <pwd.h>
#include <grp.h>
#include <syslog.h>
/* own systems */
#include "common/msg.h"
@ -51,8 +50,6 @@ struct parameters {
const char *pid_file;
uid_t uid;
gid_t gid;
int log_mask;
bool quiet;
bool daemon_mode;
};
@ -213,7 +210,7 @@ parse_args (int argc, char **argv, struct parameters *params)
switch (opt) {
case 'b':
params->daemon_mode = true;
params->quiet = true;
msg_setquiet(true);
break;
case 'f':
@ -253,18 +250,18 @@ parse_args (int argc, char **argv, struct parameters *params)
* Default log_level is LOG_WARNING (1 << 4). For each -d,
* bump log_level up to LOG_DEBUG (1 << 7).
*/
if (!(params->log_mask & LOG_MASK(LOG_DEBUG))) {
params->log_mask |= params->log_mask << 1;
if (!(msg_getlevel() & LOG_MASK(LOG_DEBUG))) {
msg_setlevel(msg_getlevel() | (msg_getlevel() << 1));
}
break;
case 'l':
level = parse_log_level(optarg, level);
params->log_mask = level;
msg_setlevel(level);
break;
case 'q':
params->quiet = true;
msg_setquiet(true);
break;
#ifdef JOURNALD_SUPPORT_ENABLED
@ -307,12 +304,12 @@ int main(int ac, char **dc)
* destructors: The d'tor of ConfigManager must be executed *before*
* the d'tors of the logging facility because the former makes use of
* the latter. */
ConfigManager manager;
ConfigManager *manager = new ConfigManager();
string statFile = "stats.log";
struct parameters parameters;
memset(&parameters, 0, sizeof(struct parameters));
parameters.log_mask = LOG_UPTO(LOG_WARNING);
msg_init();
/* parse command line */
if (parse_args (ac, dc, &parameters) < 0) {
@ -328,16 +325,6 @@ int main(int ac, char **dc)
daemonise(parameters.pid_file, parameters.uid, parameters.gid);
}
if (parameters.quiet) {
msg_setquiet(true);
}
if (msg_get_syslog()) {
setlogmask(parameters.log_mask);
openlog("vermont", LOG_PID, LOG_DAEMON);
}
msg_init();
/**< Wrapper for the main thread's signal handlers*/
MainSignalHandler main_signal_handler;
@ -349,12 +336,9 @@ int main(int ac, char **dc)
THROWEXCEPTION("failed to setup semaphore");
}
/* setup verboseness */
msg(MSG_DIALOG, "message debug level is %d", parameters.log_mask);
msg_setlevel(parameters.log_mask);
msg(MSG_DIALOG, "starting up vermont config manager");
manager.parseConfig(string(parameters.config_file));
manager->parseConfig(string(parameters.config_file));
sigset_t sigmask;
sigemptyset(&sigmask);
@ -367,28 +351,21 @@ int main(int ac, char **dc)
while (((b=timeoutsem.wait(DELETER_PERIOD)) == true) && errno == EINTR) {}// restart when interrupted by handler
if (b == false){
manager.onTimeout2();
manager->onTimeout2();
}
if (reload_config) {
msg(MSG_INFO, "reconfiguring vermont");
manager.parseConfig(string(parameters.config_file));
manager->parseConfig(string(parameters.config_file));
reload_config = false;
}
if (reset_syslog_mask) {
if (msg_get_syslog()) {
setlogmask(msg_getlevel());
}
reset_syslog_mask = false;
}
}
msg(MSG_FATAL, "got signal - exiting");
manager.shutdown();
msg(MSG_FATAL, "got signal - shutting down manager");
manager->shutdown();
delete manager;
msg(MSG_FATAL, "manager shutdown complete");
if (msg_get_syslog()) {
closelog();
}
msg_shutdown();
}
//static void __cplusplus_really_sucks_andPeopleUsingVeryStrangeNamingConventionsWithLongLongExplicitBlaBlaAndfUnNycasE()