diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 11 | ||||
-rw-r--r-- | src/bitz-server.cpp | 100 | ||||
-rw-r--r-- | src/bitz-server.h | 4 | ||||
-rw-r--r-- | src/bitz/config.cpp | 38 | ||||
-rw-r--r-- | src/bitz/config.h | 3 | ||||
-rw-r--r-- | src/bitz/logger.cpp | 98 | ||||
-rw-r--r-- | src/bitz/logger.h | 62 | ||||
-rw-r--r-- | src/bitz/manager.cpp | 41 | ||||
-rw-r--r-- | src/bitz/manager.h | 6 | ||||
-rw-r--r-- | src/bitz/request_handler.cpp | 71 | ||||
-rw-r--r-- | src/bitz/request_handler.h | 2 | ||||
-rw-r--r-- | src/bitz/worker.cpp | 28 | ||||
-rw-r--r-- | src/bitz/worker.h | 4 | ||||
-rw-r--r-- | src/main.cpp | 29 |
14 files changed, 169 insertions, 328 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index b3038cd..15a6efc 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,12 +1,15 @@ ## src/ AUTOMAKE_OPTIONS = subdir-objects -AM_CPPFLAGS = -I$(top_srcdir)/lib ${libconfig_CFLAGS} ${log4cpp_CFLAGS} ${psocksxx_CFLAGS} +AM_CPPFLAGS = -std=c++11 \ + -I$(top_srcdir)/lib \ + ${libconfig_CFLAGS} \ + ${psocksxx_CFLAGS} bitzincludedir = $(pkgincludedir) sbin_PROGRAMS = bitz-server -bitz_server_LDFLAGS = -ldl -export-dynamic +bitz_server_LDFLAGS = -ldl -lpthread -export-dynamic bitz_server_LDADD = $(top_builddir)/lib/icap/libicap.la \ - ${libconfig_LIBS} ${log4cpp_LIBS} \ + ${libconfig_LIBS} \ ${psocksxx_LIBS} bitz_server_SOURCES = main.cpp \ @@ -14,7 +17,6 @@ bitz_server_SOURCES = main.cpp \ bitz/exception.h bitz/exception.cpp \ bitz/manager_exception.h bitz/manager_exception.cpp \ bitz/config.h bitz/config.cpp \ - bitz/logger.h bitz/logger.cpp \ bitz/common.h \ bitz/util.h bitz/util.cpp \ bitz/manager.h bitz/manager.cpp \ @@ -27,6 +29,5 @@ bitz_server_SOURCES = main.cpp \ bitzinclude_HEADERS = \ bitz/config.h \ - bitz/logger.h \ bitz/modifier.h diff --git a/src/bitz-server.cpp b/src/bitz-server.cpp index d6257fd..e99078e 100644 --- a/src/bitz-server.cpp +++ b/src/bitz-server.cpp @@ -29,6 +29,8 @@ #include <sys/stat.h> #include <sys/wait.h> +#include <spdlog/spdlog.h> + #include <config.h> #include "bitz-server.h" @@ -41,15 +43,12 @@ namespace bitz { void init() { // initialise defaults - globals.pid_handle = -1; + globals.pid = -1; + globals.pidfd = -1; globals.manager = NULL; globals.terminating = 0; globals.daemon = false; - // logger (syslog) - setlogmask( LOG_UPTO( LOG_INFO ) ); - openlog( PACKAGE_NAME, LOG_CONS, LOG_USER ); - // signal handlers init_signal_handlers(); @@ -100,9 +99,10 @@ namespace bitz { pid_t worker_pid; int status; - std::cout << "[" << getpid() << "] inside zombie deleter: "; + auto logger = spdlog::get( "bitz-server" ); + logger->trace( "[{}] inside zombie reaper", getpid() ); while ( ( worker_pid = waitpid( WAIT_ANY, &status, WNOHANG ) ) > 0 ) { - std::cout << "child " << worker_pid << " terminated with status " << status << std::endl; + logger->trace( "[reaper] child {} terminated with status {}", worker_pid, status ); if ( globals.manager != NULL ) { globals.manager->reap_worker( worker_pid ); @@ -134,7 +134,8 @@ namespace bitz { void sigterm_handler( int sig, siginfo_t *siginfo, void *context ) { - std::cout << "[" << getpid() << "] inside SIGTERM handler" << std::endl; + auto logger = spdlog::get( "bitz-server" ); + logger->trace( "[{}] inside SIGTERM handler", getpid() ); termination_handler( sig, siginfo, context ); } @@ -162,7 +163,8 @@ namespace bitz { void sigquit_handler( int sig, siginfo_t *siginfo, void *context ) { - std::cout << "[" << getpid() << "] inside SIGQUIT handler" << std::endl; + auto logger = spdlog::get( "bitz-server" ); + logger->trace( "[{}] inside SIGQUIT handler", getpid() ); termination_handler( sig, siginfo, context ); } @@ -190,7 +192,8 @@ namespace bitz { void sigint_handler( int sig, siginfo_t *siginfo, void *context ) { - std::cout << "[" << getpid() << "] inside SIGQINT handler" << std::endl; + auto logger = spdlog::get( "bitz-server" ); + logger->trace( "[{}] inside SIGQINT handler", getpid() ); termination_handler( sig, siginfo, context ); } @@ -198,20 +201,28 @@ namespace bitz { void daemonize( const char *rundir, const char *pidfile ) { - pid_t pid, sid; + pid_t pid; long i; char str[10]; - // notify - syslog( LOG_NOTICE, "starting daemon (version %s)", PACKAGE_VERSION ); + /* fork daemon */ + pid = fork(); + if ( pid < 0 ) { + exit( EXIT_FAILURE ); + } - // check parent process id value - if ( getppid() == 1 ) { - // we are already a daemon - return; + // exit the parent + if ( pid > 0 ) { + exit( EXIT_SUCCESS ); } - /* fork daemon */ + // get a new process group + if ( setsid() < 0 ) { + exit(EXIT_FAILURE); + } + + + // 2nd fork (to make PID != SID) pid = fork(); if ( pid < 0 ) { exit( EXIT_FAILURE ); @@ -224,63 +235,67 @@ namespace bitz { /* child (a.k.a daemon) continues */ - // set file permissions (750) umask( 027 ); - // get a new process group - sid = setsid(); - if ( sid < 0 ) { - exit(EXIT_FAILURE); + // change running directory + chdir( rundir ); + + // close all open file descriptors + for ( int fd = sysconf( _SC_OPEN_MAX ); fd > 0; fd-- ) { + close( fd ); } - // route I/O connections - close( STDIN_FILENO ); - close( STDOUT_FILENO ); - close( STDERR_FILENO ); - // change running directory - chdir( rundir ); + // logger (syslog) + setlogmask( LOG_UPTO( LOG_INFO ) ); + openlog( PACKAGE_NAME, LOG_CONS, LOG_USER ); + + // notify + syslog( LOG_NOTICE, "starting daemon (version %s)", PACKAGE_VERSION ); /* lock pid file to ensure we have only one copy */ - globals.pid_handle = open( pidfile, O_RDWR | O_CREAT, 0600 ); - if ( globals.pid_handle == -1 ) { + globals.pidfd = open( pidfile, O_RDWR | O_CREAT, 0600 ); + if ( globals.pidfd == -1 ) { syslog( LOG_ERR, "could not open pid lock file: %s", pidfile ); exit( EXIT_FAILURE ); } - if ( lockf( globals.pid_handle, F_TLOCK, 0 ) == -1 ) { + if ( lockf( globals.pidfd, F_TLOCK, 0 ) == -1 ) { syslog( LOG_ERR, "could not lock pid lock file: %s", pidfile); exit( EXIT_FAILURE ); } // get and format pid - sprintf( str, "%d\n", getpid() ); + globals.pid = getpid(); + sprintf( str, "%d\n", globals.pid ); // write pid to lockfile - write( globals.pid_handle, str, strlen( str ) ); + write( globals.pidfd, str, strlen( str ) ); // update status globals.daemon = true; - } void shutdown() { // notify - if ( globals.daemon && ( getppid() == 1 ) ) { + if ( globals.daemon && ( getpid() == globals.pid ) ) { syslog( LOG_NOTICE, "shutting down daemon (version %s)", PACKAGE_VERSION ); } // close pid file - if ( globals.pid_handle != -1 ) { - close( globals.pid_handle ); + if ( globals.pidfd != -1 ) { + close( globals.pidfd ); } + // flush logs + spdlog::get( "bitz-server" )->flush(); + // close logger (syslog) closelog(); @@ -289,12 +304,15 @@ namespace bitz { void termination_handler( int sig, siginfo_t * sig_info, void * context ) { - std::cout << "[" << getpid() << "] inside termination handler" << std::endl; + pid_t pid = getpid(); + auto logger = spdlog::get( "bitz-server" ); + logger->trace( "[{}] inside termination handler", pid ); // exit by re-raising the signal if termination // already in progress if ( globals.terminating ) { - std::cout << "[" << getpid() << "] already terminating" << std::endl; + logger->warn( "[{}] already terminating", pid ); + raise( sig ); } @@ -455,7 +473,7 @@ namespace bitz { sigprocmask( SIG_UNBLOCK, &mask, NULL ); // manage workers - globals.manager->manager_workers(); + globals.manager->manage_workers(); // block termination signals sigprocmask( SIG_BLOCK, &mask, &oldmask ); diff --git a/src/bitz-server.h b/src/bitz-server.h index c7dda05..2a4b57f 100644 --- a/src/bitz-server.h +++ b/src/bitz-server.h @@ -23,6 +23,7 @@ #include "bitz/manager.h" #include <csignal> +#include <sys/types.h> namespace bitz { @@ -34,7 +35,8 @@ namespace bitz { * by the init() method. */ struct server_t { - int pid_handle; + pid_t pid; + int pidfd; volatile sig_atomic_t terminating; bool daemon; diff --git a/src/bitz/config.cpp b/src/bitz/config.cpp index aaa247f..f5ef810 100644 --- a/src/bitz/config.cpp +++ b/src/bitz/config.cpp @@ -18,9 +18,7 @@ */ #include "config.h" -#include "logger.h" -#include <iostream> #include <cstdlib> @@ -32,7 +30,6 @@ namespace bitz { _config.port = 1344; _config.pid_file = "/dev/null"; _config.log_file = "/dev/null"; - _config.log_category = "bitz"; _config.req_handlers_count = 0; _config.req_handlers = NULL; @@ -44,6 +41,9 @@ namespace bitz { // defaults _lconfig = NULL; + // logger + _logger = spdlog::get( "bitz-server" ); + } Config::~Config() { @@ -72,12 +72,10 @@ namespace bitz { try { config->readFile( config_file.c_str() ); } catch ( const libconfig::FileIOException &ex ) { - std::cerr << "[config] failed to read config file: " << config_file - << ", exception: " << ex.what() << std::endl; + _logger->error( "[config] failed to read config file: {}, exception: {}", config_file, ex.what() ); exit( EXIT_FAILURE ); } catch ( const libconfig::ParseException &pex ) { - std::cerr << "[config] parse error at " << pex.getFile() - << ":" << pex.getLine() << " - " << pex.getError() << std::endl; + _logger->error( "[config] parse error at {}:{} - {}", pex.getFile(), pex.getLine(), pex.getError() ); exit( EXIT_FAILURE ); } @@ -87,7 +85,6 @@ namespace bitz { config->lookupValue( "port", _config.port ); config->lookupValue( "pid_file", _config.pid_file ); config->lookupValue( "log_file", _config.log_file ); - config->lookupValue( "log_category", _config.log_category ); config->lookupValue( "max_workers", _config.max_workers ); config->lookupValue( "max_worker_requests", _config.max_worker_requests ); @@ -95,8 +92,7 @@ namespace bitz { config->lookupValue( "comm_timeout", _config.comm_timeout ); } catch ( const libconfig::SettingNotFoundException &e ) { - std::cerr << "[config] failed to load core configs, " - << e.getPath() << " : " << e.what() << std::endl; + _logger->error( "[config] failed to load core configs, {} : {}", e.getPath(), e.what() ); } // cache configs @@ -125,12 +121,11 @@ namespace bitz { libconfig::Setting &setting = _lconfig->lookup( std::string( "modules." ).append( module ) ); setting.lookupValue( config, config_value ); } catch ( const libconfig::SettingNotFoundException &e ) { - // TODO: log errors ?? - std::cerr << "[config] " << e.getPath() << " : " << e.what() << std::endl; + _logger->error( "[config] {} : {}", e.getPath(), e.what() ); } } else { - std::cout << "[config] 'modules' configs not found" << std::endl; + _logger->info( "[config] 'modules' configs not found" ); } return config_value; @@ -143,16 +138,14 @@ namespace bitz { int i, j; std::string s; - std::cout << "[config] looking for req_handlers... "; + _logger->trace( "[config] looking for req_handlers" ); if ( _lconfig->exists( "req_handlers" ) ) { - std::cout << "found "; - libconfig::Setting &req_handlers = _lconfig->lookup( "req_handlers" ); _config.req_handlers_count = req_handlers.getLength(); _config.req_handlers = new req_handlers_config_t[_config.req_handlers_count]; - std::cout << "(" << _config.req_handlers_count << ")" << std::endl; + _logger->debug( "[config] found {} request handlers", _config.req_handlers_count ); try { @@ -162,29 +155,28 @@ namespace bitz { _config.req_handlers[i].class_name = (const char *) req_handlers[i]["class"]; // read request handler modules config - std::cout << "[config] looking for " << _config.req_handlers[i].name << " modules... "; + _logger->debug( "[config] looking for {} modules", _config.req_handlers[i].name ); if ( req_handlers[i].exists( "modules" ) ) { - std::cout << "found "; _config.req_handlers[i].modules_count = req_handlers[i]["modules"].getLength(); _config.req_handlers[i].modules = new modules_config_t[_config.req_handlers[i].modules_count]; - std::cout << "(" << _config.req_handlers[i].modules_count << ")" << std::endl; + _logger->debug( "[config] found {} modules for {}", _config.req_handlers[i].modules_count, _config.req_handlers[i].name ); for ( j = 0; j < _config.req_handlers[i].modules_count; j++ ) { _config.req_handlers[i].modules[j].name = (const char *) req_handlers[i]["modules"][j]["name"]; _config.req_handlers[i].modules[j].module = (const char *) req_handlers[i]["modules"][j]["module"]; } } else { - std::cout << "not found" << std::endl; + _logger->info( "[config] no modules found for {}", _config.req_handlers[i].name ); } } } catch ( const libconfig::SettingNotFoundException &ex ) { - std::cerr << "[config] Error: " << ex.getPath() << ex.what() << std::endl; + _logger->error( "[config] {} : {}", ex.getPath(), ex.what() ); } } else { - std::cout << "not found" << std::endl; + _logger->info( "[config] no request handlers found" ); } } diff --git a/src/bitz/config.h b/src/bitz/config.h index 021384b..06cd4df 100644 --- a/src/bitz/config.h +++ b/src/bitz/config.h @@ -22,6 +22,7 @@ #include <string> #include <libconfig.h++> +#include <spdlog/spdlog.h> #ifndef BITZ_SERVER_CONFIG_FILE @@ -50,7 +51,6 @@ namespace bitz { int comm_timeout; std::string pid_file; std::string log_file; - std::string log_category; unsigned int req_handlers_count; req_handlers_config_t * req_handlers; @@ -80,6 +80,7 @@ namespace bitz { private: config_t _config; libconfig::Config * _lconfig; + std::shared_ptr<spdlog::logger> _logger; Config(); ~Config(); diff --git a/src/bitz/logger.cpp b/src/bitz/logger.cpp deleted file mode 100644 index 1d7d833..0000000 --- a/src/bitz/logger.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * bitz-server, An ICAP server implementation in C++ - * Copyright (C) 2012 Uditha Atukorala - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include "logger.h" - -#include <log4cpp/FileAppender.hh> -#include <log4cpp/PatternLayout.hh> - -namespace bitz { - - Logger::Logger( std::string log_file, std::string category ) { - this->LOGGER = NULL; - this->initialise( log_file, category ); - } - - Logger::~Logger() { - this->LOGGER->debug( "closing down logger" ); - } - - void Logger::initialise( std::string log_file, std::string category ) { - - this->LOGGER = &log4cpp::Category::getInstance( category ); - - // setting up appender, layout and category - log4cpp::Appender * log_appender = new log4cpp::FileAppender( "FileAppender", log_file ); - log4cpp::PatternLayout * log_layout = new log4cpp::PatternLayout(); - log_layout->setConversionPattern( "%d %p %c %x: %m%n" ); - - log_appender->setLayout( log_layout ); - this->LOGGER->setAppender( log_appender ); - this->LOGGER->setPriority( this->getPriorityValue( "DEBUG" ) ); - - this->LOGGER->debug( "logger initialised, log_file: " + log_file ); - - } - - int Logger::getPriorityValue( const std::string &priority ) { - return ( log4cpp::Priority::getPriorityValue( priority ) ); - } - - void Logger::log( log4cpp::Priority::Value priority, const std::string &message ) { - this->LOGGER->log( priority, message ); - } - - void Logger::fatal( const std::string& message ) { - this->LOGGER->fatal( message ); - } - - void Logger::emerg( const std::string& message ) { - this->LOGGER->emerg( message ); - } - - void Logger::alert( const std::string& message ) { - this->LOGGER->alert( message ); - } - - void Logger::crit( const std::string& message ) { - this->LOGGER->crit( message ); - } - - void Logger::error( const std::string& message ) { - this->LOGGER->error( message ); - } - - void Logger::warn( const std::string& message ) { - this->LOGGER->warn( message ); - } - - void Logger::notice( const std::string& message ) { - this->LOGGER->notice( message ); - } - - void Logger::info( const std::string& message ) { - this->LOGGER->info( message ); - } - - void Logger::debug( const std::string& message ) { - this->LOGGER->debug( message ); - } - -} /* end of namespace bitz */ - diff --git a/src/bitz/logger.h b/src/bitz/logger.h deleted file mode 100644 index f1c9c6c..0000000 --- a/src/bitz/logger.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * bitz-server, An ICAP server implementation in C++ - * Copyright (C) 2012 Uditha Atukorala - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#ifndef BITZ_LOGGER_H -#define BITZ_LOGGER_H - -#include <string> -#include <log4cpp/Category.hh> - -namespace bitz { - - class Logger { - public: - static Logger &instance( std::string log_file = "/dev/null" , std::string category = "logger" ) { - static Logger logger( log_file, category ); - return logger; - } - - void initialise( std::string log_file, std::string category ); - - static int getPriorityValue( const std::string& priority ); - void log( int priority, const std::string &message ); - - void fatal( const std::string& message ); - void emerg( const std::string& message ); - void alert( const std::string& message ); - void crit( const std::string& message ); - void error( const std::string& message ); - void warn( const std::string& message ); - void notice( const std::string& message ); - void info( const std::string& message ); - void debug( const std::string& message ); - - private: - log4cpp::Category * LOGGER; - - Logger( std::string log_file, std::string category ); - ~Logger(); - Logger( Logger const © ); - Logger &operator=( const Logger © ); - }; - -} /* end of namespace bitz */ - -#endif /* !BITZ_LOGGER_H */ - diff --git a/src/bitz/manager.cpp b/src/bitz/manager.cpp index 14033a5..38b431f 100644 --- a/src/bitz/manager.cpp +++ b/src/bitz/manager.cpp @@ -18,7 +18,6 @@ */ #include "manager.h" -#include "logger.h" #include "util.h" #include <cstdlib> @@ -55,20 +54,19 @@ namespace bitz { throw ManagerException( std::string( "failed to initialise socket, " ).append( e.what() ) ); } - Logger &logger = Logger::instance(); - logger.debug( "manager initialised" ); + // logger + _logger = spdlog::get( "bitz-server" ); + _logger->debug( "manager initialised" ); } Manager::~Manager() { - Logger &logger = Logger::instance(); - if ( _manager.worker ) { - logger.debug( "[worker] cleaning up manager" ); + _logger->debug( "[worker] cleaning up manager" ); } else { - logger.debug( "[manager] shutting down manager" ); + _logger->debug( "[manager] shutting down manager" ); } delete [] _manager.worker_pool; @@ -102,7 +100,6 @@ namespace bitz { void Manager::spawn_worker( unsigned int worker_id ) throw( ManagerException ) { - Logger &logger = Logger::instance(); pid_t worker_pid; // create a worker child @@ -122,7 +119,7 @@ namespace bitz { _manager.worker_pool[worker_id].worker_pid = worker_pid; _manager.worker_pool[worker_id].worker->run( _manager.socket, _manager.max_worker_requests, _manager.comm_timeout ); - logger.info( std::string( "end of cycle, worker[" ).append( util::itoa( worker_id ) ).append( "]" ) ); + _logger->info( std::string( "end of cycle, worker[" ).append( util::itoa( worker_id ) ).append( "]" ) ); delete _manager.worker_pool[worker_id].worker; _exit( EXIT_SUCCESS ); @@ -130,7 +127,7 @@ namespace bitz { } else { /* manager */ - logger.info( std::string( "[manager] worker spawned with pid: " ).append( util::itoa( worker_pid) ) ); + _logger->info( std::string( "[manager] worker spawned with pid: " ).append( util::itoa( worker_pid) ) ); _manager.workers_count++; @@ -146,12 +143,9 @@ namespace bitz { void Manager::shutdown( bool graceful ) throw() { - // logger - Logger &logger = Logger::instance(); - if ( _manager.worker ) { - logger.info( "[worker] manager shutdown request received" ); + _logger->info( "[worker] manager shutdown request received" ); /* worker: cleanup */ delete _manager.worker_pool[_manager.worker_id].worker; @@ -159,21 +153,21 @@ namespace bitz { } else { /* manager: stop all child processes */ - logger.info( "[manager] shutdown request received" ); + _logger->info( "[manager] shutdown request received" ); for (unsigned int i = 0; i < _manager.max_workers; i++ ) { if ( _manager.worker_pool[i].worker_pid != 0 ) { if ( graceful ) { kill( _manager.worker_pool[i].worker_pid, SIGTERM ); - logger.debug( std::string( "[manager] sending SIGTERM to worker[" ).append( util::itoa( i ) ) + _logger->debug( std::string( "[manager] sending SIGTERM to worker[" ).append( util::itoa( i ) ) .append( "], pid: " ).append( util::itoa( _manager.worker_pool[i].worker_pid ) ) ); } else { kill( _manager.worker_pool[i].worker_pid, SIGKILL ); - logger.debug( std::string( "[manager] sending SIGKILL to worker[" ).append( util::itoa( i ) ) + _logger->debug( std::string( "[manager] sending SIGKILL to worker[" ).append( util::itoa( i ) ) .append( "], pid: " ).append( util::itoa( _manager.worker_pool[i].worker_pid ) ) ); } } else { - logger.debug( std::string( "[manager] worker[" ).append( util::itoa( i ) ).append( "] already closed" ) ); + _logger->debug( std::string( "[manager] worker[" ).append( util::itoa( i ) ).append( "] already closed" ) ); } } } @@ -183,9 +177,7 @@ namespace bitz { void Manager::reap_worker( pid_t worker_pid ) throw() { - // logger - Logger &logger = Logger::instance(); - logger.debug( std::string( "reaping worker, pid: " ).append( util::itoa( worker_pid ) ) ); + _logger->debug( std::string( "reaping worker, pid: " ).append( util::itoa( worker_pid ) ) ); if (! _manager.worker ) { for (unsigned int i = 0; i < _manager.max_workers; i++ ) { @@ -205,10 +197,7 @@ namespace bitz { } - void Manager::manager_workers() throw() { - - // logger - Logger &logger = Logger::instance(); + void Manager::manage_workers() throw() { if (! _manager.worker ) { @@ -222,7 +211,7 @@ namespace bitz { // spawn a worker for the missing spawn_worker( i ); } catch ( ManagerException &mex ) { - logger.warn( std::string( "[manager] failed to spawn worker[" ).append( util::itoa( i ) ).append( "], exception: ").append( mex.what() ) ); + _logger->warn( std::string( "[manager] failed to spawn worker[" ).append( util::itoa( i ) ).append( "], exception: ").append( mex.what() ) ); } } } diff --git a/src/bitz/manager.h b/src/bitz/manager.h index ce49e9e..8ad23e9 100644 --- a/src/bitz/manager.h +++ b/src/bitz/manager.h @@ -21,6 +21,7 @@ #define BITZ_MANAGER_H #include <unistd.h> +#include <spdlog/spdlog.h> #include <psocksxx/tcpnsockstream.h> #include "manager_exception.h" @@ -75,11 +76,12 @@ namespace bitz { virtual void shutdown( bool graceful = true ) throw(); virtual void reap_worker( pid_t worker_pid ) throw(); - virtual void manager_workers() throw(); + virtual void manage_workers() throw(); private: - manager_t _manager; + manager_t _manager; + std::shared_ptr<spdlog::logger> _logger; virtual void spawn_worker( unsigned int worker_id ) throw( ManagerException ); diff --git a/src/bitz/request_handler.cpp b/src/bitz/request_handler.cpp index 56f9bc0..aa906f9 100644 --- a/src/bitz/request_handler.cpp +++ b/src/bitz/request_handler.cpp @@ -19,7 +19,6 @@ #include "request_handler.h" #include "config.h" -#include "logger.h" #include "util.h" #include <dlfcn.h> @@ -37,6 +36,9 @@ namespace bitz { // update variables _req_handler.method = method; + // logger + _logger = spdlog::get( "bitz-server" ); + // load modifier modules load_modules(); @@ -52,8 +54,7 @@ namespace bitz { delete [] _handlers; } - Logger &logger = Logger::instance(); - logger.debug( std::string( "[req] exiting request handler [" ).append( _req_handler.method ).append( "]" ) ); + _logger->debug( std::string( "[req] exiting request handler [" ).append( _req_handler.method ).append( "]" ) ); } @@ -65,13 +66,9 @@ namespace bitz { icap::Response * RequestHandler::process( icap::RequestHeader * req_header, psocksxx::iosockstream * socket ) throw() { - icap::Request * request; icap::Response * response = NULL; - // logger - Logger &logger = Logger::instance(); - // request request = new icap::Request( req_header ); @@ -79,22 +76,22 @@ namespace bitz { // read request data if (! icap::util::read_req_data( request, socket ) ) { - logger.warn( "[req] failed to read request data" ); + _logger->warn( "[req] failed to read request data" ); response = new icap::Response( icap::ResponseHeader::SERVER_ERROR ); } else { - logger.debug( std::string( "[req] payload.req-hdr:\r\n").append( request->payload().req_header ) ); - logger.debug( std::string( "[req] payload.req-body:\r\n").append( request->payload().req_body ) ); - logger.debug( std::string( "[req] payload.res-hdr:\r\n").append( request->payload().res_header ) ); - logger.debug( std::string( "[req] payload.res-body:\r\n").append( request->payload().res_body ) ); + _logger->debug( std::string( "[req] payload.req-hdr:\r\n").append( request->payload().req_header ) ); + _logger->debug( std::string( "[req] payload.req-body:\r\n").append( request->payload().req_body ) ); + _logger->debug( std::string( "[req] payload.res-hdr:\r\n").append( request->payload().res_header ) ); + _logger->debug( std::string( "[req] payload.res-body:\r\n").append( request->payload().res_body ) ); // check for message preview if ( request->preview_size() >= 0 ) { // process preview - logger.debug( std::string( "[req] message preview request, preview: " ).append( util::itoa( request->preview_size() ) ) ); + _logger->debug( std::string( "[req] message preview request, preview: " ).append( util::itoa( request->preview_size() ) ) ); response = process_preview( request, socket ); } @@ -108,7 +105,7 @@ namespace bitz { if ( response == NULL ) { // process modify - logger.debug( "[req] modify request" ); + _logger->debug( "[req] modify request" ); response = process_modify( request ); } @@ -120,7 +117,7 @@ namespace bitz { // sanity check if ( response == NULL ) { - logger.warn( "[req] no valid response from modifiers, creating a server error (500) response" ); + _logger->warn( "[req] no valid response from modifiers, creating a server error (500) response" ); response = new icap::Response( icap::ResponseHeader::SERVER_ERROR ); } @@ -131,18 +128,15 @@ namespace bitz { bool RequestHandler::load_modifier( const std::string &file, Modifier::symbols_t &symbols ) throw() { - // logger - Logger &logger = Logger::instance(); - // vars const char* dlsym_error; // load the modifier module - logger.debug( "[req] loading modifier: " + file ); + _logger->debug( "[req] loading modifier: " + file ); symbols.modifier = dlopen( file.c_str(), RTLD_LAZY | RTLD_LOCAL ); if (! symbols.modifier ) { - logger.warn( std::string( "[req] failed to load modifier: " ).append( file ).append( dlerror() ) ); + _logger->warn( std::string( "[req] failed to load modifier: " ).append( file ).append( dlerror() ) ); return false; } @@ -154,7 +148,7 @@ namespace bitz { dlsym_error = dlerror(); if ( dlsym_error ) { - logger.warn( std::string( "[req] failed to load create symbol: " ).append( dlsym_error ) ); + _logger->warn( std::string( "[req] failed to load create symbol: " ).append( dlsym_error ) ); return false; } @@ -162,7 +156,7 @@ namespace bitz { dlsym_error = dlerror(); if ( dlsym_error ) { - logger.warn( std::string( "[req] failed to load destroy symbol: " ).append( dlsym_error ) ); + _logger->warn( std::string( "[req] failed to load destroy symbol: " ).append( dlsym_error ) ); return false; } @@ -223,12 +217,9 @@ namespace bitz { int i = 0; - // logger - Logger &logger = Logger::instance(); - for ( i = 0; i < _handlers_count; i++ ) { - logger.debug( std::string( "[req] unloading module: " ).append( _handlers[i].name ) ); + _logger->debug( std::string( "[req] unloading module: " ).append( _handlers[i].name ) ); // unload unload_modifier( _handlers[i].symbols.modifier ); @@ -246,9 +237,6 @@ namespace bitz { int i = 0; bool continue_status = false; - // logger - Logger &logger = Logger::instance(); - /* * Loop through loaded modifier modules and grab responses @@ -262,17 +250,17 @@ namespace bitz { // sanity check if ( _handlers[i].name == "" ) { - logger.info( "[req] modifier not loaded, not trying to get a response" ); + _logger->info( "[req] modifier not loaded, not trying to get a response" ); continue; } // grab the response from modifier - logger.debug( std::string( "[req] getting preview response from modifier: " ).append( _handlers[i].name ) ); + _logger->debug( std::string( "[req] getting preview response from modifier: " ).append( _handlers[i].name ) ); modifier = _handlers[i].symbols.create(); response = modifier->preview( request ); // cleanup - logger.debug( std::string( "[req] cleaning up modifier: " ).append( _handlers[i].name ) ); + _logger->debug( std::string( "[req] cleaning up modifier: " ).append( _handlers[i].name ) ); _handlers[i].symbols.destroy( modifier ); // check response status @@ -309,7 +297,7 @@ namespace bitz { } // we shouldn't have got this far - logger.info( std::string( "[req] unrecognised preview response from modifier: " ).append( _handlers[i].name ) ); + _logger->info( std::string( "[req] unrecognised preview response from modifier: " ).append( _handlers[i].name ) ); } @@ -325,9 +313,6 @@ namespace bitz { int i = 0; - // logger - Logger &logger = Logger::instance(); - /* * Loop through loaded modifier modules and grab responses @@ -339,22 +324,22 @@ namespace bitz { // sanity check if ( _handlers[i].name == "" ) { - logger.info( "[req] modifier not loaded, not trying to get a response" ); + _logger->info( "[req] modifier not loaded, not trying to get a response" ); continue; } // grab the response from modifier - logger.debug( std::string( "[req] getting modify response from modifier: " ).append( _handlers[i].name ) ); + _logger->debug( std::string( "[req] getting modify response from modifier: " ).append( _handlers[i].name ) ); modifier = _handlers[i].symbols.create(); response = modifier->modify( request ); // cleanup - logger.debug( std::string( "[req] cleaning up modifier: " ).append( _handlers[i].name ) ); + _logger->debug( std::string( "[req] cleaning up modifier: " ).append( _handlers[i].name ) ); _handlers[i].symbols.destroy( modifier ); // status 200 OK means content modified if ( response->header()->status() == icap::ResponseHeader::OK ) { - logger.debug( "[req] OK response received, not getting responses from other modifiers" ); + _logger->debug( "[req] OK response received, not getting responses from other modifiers" ); break; } @@ -369,15 +354,11 @@ namespace bitz { bool status = false; - // logger - Logger &logger = Logger::instance(); - - // sanity check if ( request->payload().ieof ) { // we can process a '100 Continue' only if an 'ieof' is not received - logger.warn( "[req] illegal '100 Continue' response" ); + _logger->warn( "[req] illegal '100 Continue' response" ); } else { diff --git a/src/bitz/request_handler.h b/src/bitz/request_handler.h index 2c31090..e05832c 100644 --- a/src/bitz/request_handler.h +++ b/src/bitz/request_handler.h @@ -25,6 +25,7 @@ #include <icap/response.h> #include <icap/request.h> #include <psocksxx/iosockstream.h> +#include <spdlog/spdlog.h> namespace bitz { @@ -124,6 +125,7 @@ namespace bitz { private: req_handler_t _req_handler; + std::shared_ptr<spdlog::logger> _logger; }; diff --git a/src/bitz/worker.cpp b/src/bitz/worker.cpp index 42fb3d0..202f531 100644 --- a/src/bitz/worker.cpp +++ b/src/bitz/worker.cpp @@ -18,7 +18,6 @@ */ #include "worker.h" -#include "logger.h" #include "util.h" #include "options_request_handler.h" #include "reqmod_request_handler.h" @@ -32,6 +31,9 @@ namespace bitz { Worker::Worker() { + // logger + _logger = spdlog::get( "bitz-server" ); + // load request handlers load_req_handlers(); @@ -40,9 +42,7 @@ namespace bitz { Worker::~Worker() { - // logger - Logger &logger = Logger::instance(); - logger.debug( "[worker] exiting" ); + _logger->debug( "[worker] exiting" ); // cleanup request handlers util::delete_req_handlers( _req_handlers ); @@ -54,15 +54,12 @@ namespace bitz { void Worker::run( psocksxx::tcpnsockstream * server_sock, unsigned int max_requests, unsigned int comm_timeout ) throw() { - // logger - Logger &logger = Logger::instance(); - // client socket stream psocksxx::nsockstream * client_sock; while ( max_requests > 0 ) { - logger.debug( std::string( "[worker] waiting for a connection" ) ); + _logger->debug( std::string( "[worker] waiting for a connection" ) ); try { @@ -70,7 +67,7 @@ namespace bitz { client_sock = server_sock->accept(); // FIXME: log accepted client details (e.g. address, port etc.) - logger.debug( std::string( "[worker] new connection accepted on [...]" ) ); + _logger->debug( std::string( "[worker] new connection accepted on [...]" ) ); // set timeout value if ( comm_timeout > 0 ) { @@ -81,7 +78,7 @@ namespace bitz { } catch ( psocksxx::sockexception &e ) { // failed to accept client connection - logger.error( std::string( "[worker] failed to accept connection: " ).append( e.what() ) ); + _logger->error( std::string( "[worker] failed to accept connection: " ).append( e.what() ) ); // update request count max_requests--; @@ -123,9 +120,6 @@ namespace bitz { unsigned int Worker::serve_client( psocksxx::nsockstream * client_sock, unsigned int max_requests ) throw() { - // logger - Logger &logger = Logger::instance(); - icap::RequestHeader * req_header = NULL; icap::Response * response; RequestHandler * req_handler; @@ -140,11 +134,11 @@ namespace bitz { // request header req_header = icap::util::read_req_header( client_sock ); - logger.debug( std::string( "[worker] request header:\r\n" ).append( req_header->raw_data() ) ); + _logger->debug( std::string( "[worker] request header:\r\n" ).append( req_header->raw_data() ) ); // check timeout if ( client_sock->timedout() ) { - logger.warn( "[worker] communication timed out..." ); + _logger->warn( "[worker] communication timed out..." ); return --max_requests; } @@ -154,7 +148,7 @@ namespace bitz { // sanity check if ( req_handler != NULL ) { - logger.debug( std::string( "[worker] handling request: " ).append( req_header->method() ) ); + _logger->debug( std::string( "[worker] handling request: " ).append( req_header->method() ) ); // process the request and grab the response response = req_handler->process( req_header, client_sock ); @@ -162,7 +156,7 @@ namespace bitz { } else { // unsupported request - logger.info( std::string( "[worker] unsupported request: " ).append( req_header->method() ) ); + _logger->info( std::string( "[worker] unsupported request: " ).append( req_header->method() ) ); response = new icap::Response( new icap::ResponseHeader( icap::ResponseHeader::NOT_ALLOWED ) ); } diff --git a/src/bitz/worker.h b/src/bitz/worker.h index 25b7bac..a3c3951 100644 --- a/src/bitz/worker.h +++ b/src/bitz/worker.h @@ -20,6 +20,7 @@ #ifndef BITZ_WORKER_H #define BITZ_WORKER_H +#include <spdlog/spdlog.h> #include <psocksxx/tcpnsockstream.h> #include "common.h" @@ -36,7 +37,8 @@ namespace bitz { unsigned int max_requests, unsigned int comm_timeout = 0 ) throw(); private: - req_handlers_t _req_handlers; + req_handlers_t _req_handlers; + std::shared_ptr<spdlog::logger> _logger; virtual void load_req_handlers() throw(); virtual unsigned int serve_client( psocksxx::nsockstream * client_sock, unsigned int max_requests ) throw(); diff --git a/src/main.cpp b/src/main.cpp index 7570e3a..c65ccc4 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,8 +22,8 @@ #include <config.h> #include "bitz-server.h" #include "bitz/config.h" -#include "bitz/logger.h" #include "bitz/util.h" +#include "spdlog/spdlog.h" int main( int argc, char **argv ) { @@ -34,6 +34,12 @@ int main( int argc, char **argv ) { // read command line options bitz::server::options_t opt = bitz::server::read_options( argc, argv ); + // logger + auto logger = spdlog::stdout_color_st( "bitz-server" ); + if ( opt.debug_flag == 1 ) { + spdlog::set_level( spdlog::level::debug ); + } + // initialise configurations bitz::Config &server_config = bitz::Config::instance(); @@ -48,28 +54,39 @@ int main( int argc, char **argv ) { // create directories if ( ( opt.debug_flag != 1 ) && (! bitz::util::mkdirp( bitz::util::dirpath( config.pid_file ) ) ) ) { - std::cerr << "[core] failed to create run dir" << std::endl; + logger->critical( "[core] failed to create run dir" ); exit( EXIT_FAILURE ); } if (! bitz::util::mkdirp( bitz::util::dirpath( config.log_file ) ) ) { - std::cerr << "[core] failed to create log dir" << std::endl; + logger->critical( "[core] failed to create log dir" ); exit( EXIT_FAILURE ); } // daemonize if ( opt.debug_flag != 1 ) { + + // close stdout logger + spdlog::drop( "bitz-server" ); + + // daemonize bitz::server::daemonize( bitz::util::dirpath( config.pid_file ).c_str(), config.pid_file.c_str() ); + + // open a file logger + logger = spdlog::rotating_logger_mt( "bitz-server", config.log_file, ( 1048576 * 1024 ), 7 ); + + } else { + logger->info( "{} initialised", PACKAGE_STRING ); } - // initialise the logger - bitz::Logger &logger = bitz::Logger::instance( config.log_file, config.log_category ); - logger.info( std::string( PACKAGE_STRING ) + " initialised" ); // start the server bitz::server::start( config.port, config.max_workers, config.max_worker_requests, config.comm_timeout ); + // flush logs + logger->flush(); + // run the server bitz::server::run(); |