Factored console_appender into its own header/cpp
Added file_appender Updated tests
This commit is contained in:
parent
71ea16cf8b
commit
b527bbbab6
10 changed files with 215 additions and 105 deletions
|
|
@ -50,6 +50,8 @@ include_directories( include )
|
|||
|
||||
set( sources
|
||||
src/logger.cpp
|
||||
src/console_appender.cpp
|
||||
src/file_appender.cpp
|
||||
src/appender.cpp
|
||||
src/logger_config.cpp
|
||||
src/ssh.cpp
|
||||
|
|
|
|||
56
include/fc/console_appender.hpp
Normal file
56
include/fc/console_appender.hpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#pragma once
|
||||
#include <fc/appender.hpp>
|
||||
#include <fc/logger.hpp>
|
||||
|
||||
namespace fc {
|
||||
class console_appender : public appender {
|
||||
public:
|
||||
struct color {
|
||||
enum type {
|
||||
red,
|
||||
green,
|
||||
brown,
|
||||
blue,
|
||||
magenta,
|
||||
cyan,
|
||||
white,
|
||||
console_default,
|
||||
};
|
||||
};
|
||||
struct stream { enum type { std_out, std_error }; };
|
||||
|
||||
struct level_color {
|
||||
level_color( log_level::type l=log_level::all,
|
||||
color::type c=color::console_default )
|
||||
:level(l),color(c){}
|
||||
|
||||
log_level::type level;
|
||||
console_appender::color::type color;
|
||||
};
|
||||
|
||||
struct config {
|
||||
config()
|
||||
:format( "${when} ${thread} ${context} ${file}:${line} ${method} ${level}] ${message}" ),
|
||||
stream(console_appender::stream::std_error),flush(true){}
|
||||
|
||||
fc::string format;
|
||||
console_appender::stream::type stream;
|
||||
fc::vector<level_color> level_colors;
|
||||
bool flush;
|
||||
};
|
||||
|
||||
|
||||
console_appender( const value& args );
|
||||
const char* get_color( log_level::type l )const;
|
||||
virtual void log( const log_message& m );
|
||||
private:
|
||||
config cfg;
|
||||
color::type lc[log_level::off+1];
|
||||
};
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT_ENUM( fc::console_appender::stream::type, (std_out)(std_error) )
|
||||
FC_REFLECT_ENUM( fc::console_appender::color::type, (red)(green)(brown)(blue)(magenta)(cyan)(white)(console_default) )
|
||||
FC_REFLECT( fc::console_appender::level_color, (level)(color) )
|
||||
FC_REFLECT( fc::console_appender::config, (format)(stream)(level_colors)(flush) )
|
||||
29
include/fc/file_appender.hpp
Normal file
29
include/fc/file_appender.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
#include <fc/appender.hpp>
|
||||
#include <fc/logger.hpp>
|
||||
#include <fc/filesystem.hpp>
|
||||
|
||||
namespace fc {
|
||||
|
||||
class file_appender : public appender {
|
||||
public:
|
||||
struct config {
|
||||
config( const fc::path& p = "log.txt" );
|
||||
|
||||
fc::string format;
|
||||
fc::path filename;
|
||||
bool flush;
|
||||
bool truncate;
|
||||
};
|
||||
file_appender( const value& args );
|
||||
~file_appender();
|
||||
virtual void log( const log_message& m );
|
||||
|
||||
private:
|
||||
class impl;
|
||||
fc::shared_ptr<impl> my;
|
||||
};
|
||||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::file_appender::config, (format)(filename)(flush)(truncate) )
|
||||
|
|
@ -22,6 +22,7 @@ namespace fc {
|
|||
ostring context;
|
||||
ostring thread;
|
||||
ostring fiber;
|
||||
ostring host;
|
||||
string file;
|
||||
int line;
|
||||
string method;
|
||||
|
|
@ -102,7 +103,7 @@ namespace fc {
|
|||
} // namespace fc
|
||||
|
||||
#include <fc/reflect.hpp>
|
||||
FC_REFLECT( fc::log_message, (when)(level)(context)(thread)(method)(file)(line)(format)(args)(meta) )
|
||||
FC_REFLECT( fc::log_message, (when)(level)(context)(thread)(fiber)(host)(method)(file)(line)(format)(args)(meta) )
|
||||
FC_REFLECT_ENUM( fc::log_level::type, (all)(trace)(debug)(info)(warn)(error)(fatal)(off) )
|
||||
|
||||
#define fc_scope_log( LOGGER, FORMAT, ... ) \
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ namespace fc {
|
|||
/// if any appenders are sepecified, then parent's appenders are not set.
|
||||
bool additivity;
|
||||
fc::vector<string> appenders;
|
||||
|
||||
logger_config& add_appender( const string& s );
|
||||
};
|
||||
|
||||
struct logging_config {
|
||||
|
|
|
|||
102
src/appender.cpp
102
src/appender.cpp
|
|
@ -9,11 +9,9 @@
|
|||
#include <fc/console_defines.h>
|
||||
#include <fc/log.hpp>
|
||||
#include <fc/value_cast.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <fc/console_appender.hpp>
|
||||
#include <fc/file_appender.hpp>
|
||||
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace fc {
|
||||
|
||||
|
|
@ -47,100 +45,6 @@ namespace fc {
|
|||
return ap;
|
||||
}
|
||||
|
||||
class console_appender : public appender{
|
||||
public:
|
||||
struct color {
|
||||
enum type {
|
||||
red,
|
||||
green,
|
||||
brown,
|
||||
blue,
|
||||
magenta,
|
||||
cyan,
|
||||
white,
|
||||
console_default,
|
||||
};
|
||||
};
|
||||
struct stream { enum type { std_out, std_error }; };
|
||||
|
||||
struct level_color {
|
||||
level_color( log_level::type l=log_level::all,
|
||||
color::type c=color::console_default )
|
||||
:level(l),color(c){}
|
||||
|
||||
log_level::type level;
|
||||
console_appender::color::type color;
|
||||
};
|
||||
|
||||
struct config {
|
||||
config()
|
||||
:format( "${when} ${thread} ${context} ${file}:${line} ${method} ${level}] ${message}" ),
|
||||
stream(console_appender::stream::std_error),flush(true){}
|
||||
|
||||
fc::string format;
|
||||
console_appender::stream::type stream;
|
||||
fc::vector<level_color> level_colors;
|
||||
bool flush;
|
||||
};
|
||||
|
||||
config cfg;
|
||||
color::type lc[log_level::off+1];
|
||||
|
||||
console_appender( const value& args );
|
||||
const char* get_color(color::type t ) {
|
||||
switch( t ) {
|
||||
case color::red: return CONSOLE_RED;
|
||||
case color::green: return CONSOLE_GREEN;
|
||||
case color::brown: return CONSOLE_BROWN;
|
||||
case color::blue: return CONSOLE_BLUE;
|
||||
case color::magenta: return CONSOLE_MAGENTA;
|
||||
case color::cyan: return CONSOLE_CYAN;
|
||||
case color::white: return CONSOLE_WHITE;
|
||||
case color::console_default:
|
||||
default:
|
||||
return CONSOLE_DEFAULT;
|
||||
}
|
||||
}
|
||||
const char* get_color( log_level::type l ) {
|
||||
return get_color( lc[l] );
|
||||
}
|
||||
|
||||
virtual void log( const log_message& m ) {
|
||||
fc::string message = fc::substitute( m.format, m.args );
|
||||
fc::value lmsg(m);
|
||||
|
||||
FILE* out = stream::std_error ? stderr : stdout;
|
||||
fc::string fmt_str = fc::substitute( cfg.format, value(m).set( "message", message) );
|
||||
|
||||
fc::unique_lock<boost::mutex> lock(log_mutex());
|
||||
#ifndef WIN32
|
||||
if(isatty(fileno(out))) fprintf( out, "\r%s", get_color( m.level ) );
|
||||
#endif
|
||||
|
||||
fprintf( out, "%s", fmt_str.c_str() );
|
||||
|
||||
#ifndef WIN32
|
||||
if(isatty(fileno(out))) fprintf( out, "\r%s", CONSOLE_DEFAULT );
|
||||
#endif
|
||||
fprintf( out, "\n" );
|
||||
if( cfg.flush ) fflush( out );
|
||||
}
|
||||
};
|
||||
} // namespace fc
|
||||
|
||||
FC_REFLECT_ENUM( fc::console_appender::stream::type, (std_out)(std_error) )
|
||||
FC_REFLECT_ENUM( fc::console_appender::color::type, (red)(green)(brown)(blue)(magenta)(cyan)(white)(console_default) )
|
||||
FC_REFLECT( fc::console_appender::level_color, (level)(color) )
|
||||
FC_REFLECT( fc::console_appender::config, (format)(stream)(level_colors)(flush) )
|
||||
|
||||
namespace fc {
|
||||
console_appender::console_appender( const value& args ) {
|
||||
cfg = fc::value_cast<config>(args);
|
||||
for( int i = 0; i < log_level::off+1; ++i )
|
||||
lc[i] = color::console_default;
|
||||
for( auto itr = cfg.level_colors.begin(); itr != cfg.level_colors.end(); ++itr )
|
||||
lc[itr->level] = itr->color;
|
||||
}
|
||||
|
||||
static bool reg_console_appender = appender::register_appender<console_appender>( "console" );
|
||||
static bool reg_file_appender = appender::register_appender<file_appender>( "file" );
|
||||
} // namespace fc
|
||||
|
|
|
|||
56
src/console_appender.cpp
Normal file
56
src/console_appender.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
#include <fc/console_appender.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <fc/unique_lock.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/value_cast.hpp>
|
||||
#ifndef WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace fc {
|
||||
console_appender::console_appender( const value& args ) {
|
||||
cfg = fc::value_cast<config>(args);
|
||||
for( int i = 0; i < log_level::off+1; ++i )
|
||||
lc[i] = color::console_default;
|
||||
for( auto itr = cfg.level_colors.begin(); itr != cfg.level_colors.end(); ++itr )
|
||||
lc[itr->level] = itr->color;
|
||||
}
|
||||
const char* get_console_color(console_appender::color::type t ) {
|
||||
switch( t ) {
|
||||
case console_appender::color::red: return CONSOLE_RED;
|
||||
case console_appender::color::green: return CONSOLE_GREEN;
|
||||
case console_appender::color::brown: return CONSOLE_BROWN;
|
||||
case console_appender::color::blue: return CONSOLE_BLUE;
|
||||
case console_appender::color::magenta: return CONSOLE_MAGENTA;
|
||||
case console_appender::color::cyan: return CONSOLE_CYAN;
|
||||
case console_appender::color::white: return CONSOLE_WHITE;
|
||||
case console_appender::color::console_default:
|
||||
default:
|
||||
return CONSOLE_DEFAULT;
|
||||
}
|
||||
}
|
||||
const char* console_appender::get_color( log_level::type l )const {
|
||||
return get_console_color( lc[l] );
|
||||
}
|
||||
void console_appender::log( const log_message& m ) {
|
||||
fc::string message = fc::substitute( m.format, m.args );
|
||||
fc::value lmsg(m);
|
||||
|
||||
FILE* out = stream::std_error ? stderr : stdout;
|
||||
fc::string fmt_str = fc::substitute( cfg.format, value(m).set( "message", message) );
|
||||
|
||||
fc::unique_lock<boost::mutex> lock(log_mutex());
|
||||
#ifndef WIN32
|
||||
if(isatty(fileno(out))) fprintf( out, "\r%s", get_color( m.level ) );
|
||||
#endif
|
||||
|
||||
fprintf( out, "%s", fmt_str.c_str() );
|
||||
|
||||
#ifndef WIN32
|
||||
if(isatty(fileno(out))) fprintf( out, "\r%s", CONSOLE_DEFAULT );
|
||||
#endif
|
||||
fprintf( out, "\n" );
|
||||
if( cfg.flush ) fflush( out );
|
||||
}
|
||||
|
||||
}
|
||||
44
src/file_appender.cpp
Normal file
44
src/file_appender.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
#include <fc/file_appender.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <fc/scoped_lock.hpp>
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <fc/value.hpp>
|
||||
#include <fc/value_cast.hpp>
|
||||
#include <fc/fstream.hpp>
|
||||
|
||||
namespace fc {
|
||||
class file_appender::impl : public fc::retainable {
|
||||
public:
|
||||
config cfg;
|
||||
ofstream out;
|
||||
boost::mutex slock;
|
||||
};
|
||||
file_appender::config::config( const fc::path& p )
|
||||
:format( "${when} ${thread} ${context} ${file}:${line} ${method} ${level}] ${message}" ),
|
||||
filename(p),flush(true),truncate(true){}
|
||||
|
||||
file_appender::file_appender( const value& args )
|
||||
:my( new impl() )
|
||||
{
|
||||
try {
|
||||
my->cfg = fc::value_cast<config>(args);
|
||||
my->out.open( my->cfg.filename.string().c_str() );
|
||||
} catch ( ... ) {
|
||||
elog( "%s", fc::except_str().c_str() );
|
||||
}
|
||||
}
|
||||
file_appender::~file_appender(){}
|
||||
|
||||
void file_appender::log( const log_message& m )
|
||||
{
|
||||
fc::string message = fc::substitute( m.format, m.args );
|
||||
fc::value lmsg(m);
|
||||
|
||||
fc::string fmt_str = fc::substitute( my->cfg.format, value(m).set( "message", message) );
|
||||
{
|
||||
fc::scoped_lock<boost::mutex> lock(my->slock);
|
||||
my->out << fmt_str << "\n";
|
||||
}
|
||||
if( my->cfg.flush ) my->out.flush();
|
||||
}
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
namespace fc {
|
||||
std::unordered_map<std::string,logger>& get_logger_map();
|
||||
std::unordered_map<std::string,appender::ptr>& get_appender_map();
|
||||
logger_config& logger_config::add_appender( const string& s ) { appenders.push_back(s); return *this; }
|
||||
|
||||
void configure_logging( const fc::path& lc )
|
||||
{
|
||||
|
|
@ -26,13 +27,15 @@ namespace fc {
|
|||
for( size_t i = 0; i < cfg.loggers.size(); ++i ) {
|
||||
auto lgr = logger::get( cfg.loggers[i].name );
|
||||
|
||||
// TODO: configure logger here...
|
||||
// TODO: finish configure logger here...
|
||||
if( cfg.loggers[i].parent ) {
|
||||
lgr.set_parent( logger::get( *cfg.loggers[i].parent ) );
|
||||
}
|
||||
lgr.set_name(cfg.loggers[i].name);
|
||||
lgr.set_log_level( *cfg.loggers[i].level );
|
||||
|
||||
|
||||
for( auto a = cfg.loggers[i].appenders.begin();
|
||||
a != cfg.loggers[i].appenders.end(); ++a ){
|
||||
for( auto a = cfg.loggers[i].appenders.begin(); a != cfg.loggers[i].appenders.end(); ++a ){
|
||||
auto ap = appender::get( *a );
|
||||
if( ap ) { lgr.add_appender(ap); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,25 @@
|
|||
#include <fc/logger_config.hpp>
|
||||
#include <fc/file_appender.hpp>
|
||||
#include <fc/value_cast.hpp>
|
||||
|
||||
int main( int argc, char** argv ) {
|
||||
auto lgr = fc::logger::get();
|
||||
fc::configure_logging( fc::logging_config::default_config() );
|
||||
auto dconfig = fc::logging_config::default_config();
|
||||
dconfig.appenders.push_back( fc::appender_config("logfile", "file", fc::value(fc::file_appender::config("test.log")) ) );
|
||||
dconfig.loggers.push_back( fc::logger_config("main").add_appender("stderr").add_appender("logfile") );
|
||||
fc::configure_logging( dconfig );
|
||||
fc_dlog( lgr, "Hello Debug" );
|
||||
fc_ilog( lgr, "Hello Info" );
|
||||
fc_wlog( lgr, "Hello Warn" );
|
||||
fc_elog( lgr, "Hello Error" );
|
||||
fc_flog( lgr, "Hello Fatal" );
|
||||
|
||||
|
||||
auto main_lgr = fc::logger::get( "main" );
|
||||
fc_dlog( main_lgr, "Hello Debug" );
|
||||
fc_ilog( main_lgr, "Hello Info" );
|
||||
fc_wlog( main_lgr, "Hello Warn" );
|
||||
fc_elog( main_lgr, "Hello Error" );
|
||||
fc_flog( main_lgr, "Hello Fatal" );
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue