2013-06-05 19:19:00 +00:00
|
|
|
#pragma once
|
2018-03-19 16:35:57 +00:00
|
|
|
#include <fc/config.hpp>
|
2013-06-05 19:19:00 +00:00
|
|
|
#include <fc/string.hpp>
|
|
|
|
|
#include <fc/time.hpp>
|
|
|
|
|
#include <fc/shared_ptr.hpp>
|
|
|
|
|
#include <fc/log/log_message.hpp>
|
|
|
|
|
|
|
|
|
|
namespace fc
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
class appender;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
@code
|
|
|
|
|
void my_class::func()
|
|
|
|
|
{
|
|
|
|
|
fc_dlog( my_class_logger, "Format four: ${arg} five: ${five}", ("arg",4)("five",5) );
|
|
|
|
|
}
|
|
|
|
|
@endcode
|
|
|
|
|
*/
|
|
|
|
|
class logger
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
static logger get( const fc::string& name = "default");
|
|
|
|
|
|
|
|
|
|
logger();
|
|
|
|
|
logger( const string& name, const logger& parent = nullptr );
|
|
|
|
|
logger( std::nullptr_t );
|
|
|
|
|
logger( const logger& c );
|
|
|
|
|
logger( logger&& c );
|
|
|
|
|
~logger();
|
|
|
|
|
logger& operator=(const logger&);
|
|
|
|
|
logger& operator=(logger&&);
|
|
|
|
|
friend bool operator==( const logger&, nullptr_t );
|
|
|
|
|
friend bool operator!=( const logger&, nullptr_t );
|
|
|
|
|
|
|
|
|
|
logger& set_log_level( log_level e );
|
|
|
|
|
log_level get_log_level()const;
|
|
|
|
|
logger& set_parent( const logger& l );
|
|
|
|
|
logger get_parent()const;
|
|
|
|
|
|
|
|
|
|
void set_name( const fc::string& n );
|
|
|
|
|
const fc::string& name()const;
|
|
|
|
|
|
|
|
|
|
void add_appender( const fc::shared_ptr<appender>& a );
|
2014-01-14 19:00:30 +00:00
|
|
|
std::vector<fc::shared_ptr<appender> > get_appenders()const;
|
|
|
|
|
void remove_appender( const fc::shared_ptr<appender>& a );
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
bool is_enabled( log_level e )const;
|
|
|
|
|
void log( log_message m );
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
class impl;
|
|
|
|
|
fc::shared_ptr<impl> my;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // namespace fc
|
|
|
|
|
|
2014-06-16 22:48:02 +00:00
|
|
|
#ifndef DEFAULT_LOGGER
|
|
|
|
|
#define DEFAULT_LOGGER
|
2014-06-16 20:27:21 +00:00
|
|
|
#endif
|
|
|
|
|
|
2015-01-20 21:10:34 +00:00
|
|
|
// suppress warning "conditional expression is constant" in the while(0) for visual c++
|
|
|
|
|
// http://cnicholson.net/2009/03/stupid-c-tricks-dowhile0-and-c4127/
|
|
|
|
|
#define FC_MULTILINE_MACRO_BEGIN do {
|
|
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
# define FC_MULTILINE_MACRO_END \
|
|
|
|
|
__pragma(warning(push)) \
|
|
|
|
|
__pragma(warning(disable:4127)) \
|
|
|
|
|
} while (0) \
|
|
|
|
|
__pragma(warning(pop))
|
|
|
|
|
#else
|
|
|
|
|
# define FC_MULTILINE_MACRO_END } while (0)
|
|
|
|
|
#endif
|
|
|
|
|
|
2013-06-05 19:19:00 +00:00
|
|
|
#define fc_dlog( LOGGER, FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (LOGGER).is_enabled( fc::log_level::debug ) ) \
|
2013-06-05 19:19:00 +00:00
|
|
|
(LOGGER).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define fc_ilog( LOGGER, FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (LOGGER).is_enabled( fc::log_level::info ) ) \
|
2013-06-05 19:19:00 +00:00
|
|
|
(LOGGER).log( FC_LOG_MESSAGE( info, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define fc_wlog( LOGGER, FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (LOGGER).is_enabled( fc::log_level::warn ) ) \
|
2013-06-05 19:19:00 +00:00
|
|
|
(LOGGER).log( FC_LOG_MESSAGE( warn, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define fc_elog( LOGGER, FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (LOGGER).is_enabled( fc::log_level::error ) ) \
|
2013-06-05 19:19:00 +00:00
|
|
|
(LOGGER).log( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define dlog( FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::debug ) ) \
|
2014-06-16 22:48:02 +00:00
|
|
|
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
2014-06-19 15:19:22 +00:00
|
|
|
/**
|
|
|
|
|
* Sends the log message to a special 'user' log stream designed for messages that
|
|
|
|
|
* the end user may like to see.
|
|
|
|
|
*/
|
|
|
|
|
#define ulog( FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (fc::logger::get("user")).is_enabled( fc::log_level::debug ) ) \
|
2014-06-19 15:19:22 +00:00
|
|
|
(fc::logger::get("user")).log( FC_LOG_MESSAGE( debug, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2014-06-19 15:19:22 +00:00
|
|
|
|
|
|
|
|
|
2013-06-05 19:19:00 +00:00
|
|
|
#define ilog( FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::info ) ) \
|
2014-06-16 22:48:02 +00:00
|
|
|
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( info, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define wlog( FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::warn ) ) \
|
2014-06-16 22:48:02 +00:00
|
|
|
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( warn, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define elog( FORMAT, ... ) \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_BEGIN \
|
|
|
|
|
if( (fc::logger::get(DEFAULT_LOGGER)).is_enabled( fc::log_level::error ) ) \
|
2014-06-16 22:48:02 +00:00
|
|
|
(fc::logger::get(DEFAULT_LOGGER)).log( FC_LOG_MESSAGE( error, FORMAT, __VA_ARGS__ ) ); \
|
2015-01-20 21:10:34 +00:00
|
|
|
FC_MULTILINE_MACRO_END
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#include <boost/preprocessor/seq/for_each.hpp>
|
|
|
|
|
#include <boost/preprocessor/seq/enum.hpp>
|
|
|
|
|
#include <boost/preprocessor/seq/size.hpp>
|
|
|
|
|
#include <boost/preprocessor/seq/seq.hpp>
|
|
|
|
|
#include <boost/preprocessor/stringize.hpp>
|
|
|
|
|
#include <boost/preprocessor/punctuation/paren.hpp>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define FC_FORMAT_ARG(r, unused, base) \
|
|
|
|
|
BOOST_PP_STRINGIZE(base) ": ${" BOOST_PP_STRINGIZE( base ) "} "
|
|
|
|
|
|
|
|
|
|
#define FC_FORMAT_ARGS(r, unused, base) \
|
2018-03-19 16:35:57 +00:00
|
|
|
BOOST_PP_LPAREN() BOOST_PP_STRINGIZE(base),fc::variant(base,FC_MAX_LOG_OBJECT_DEPTH) BOOST_PP_RPAREN()
|
2013-06-05 19:19:00 +00:00
|
|
|
|
|
|
|
|
#define FC_FORMAT( SEQ )\
|
|
|
|
|
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARG, v, SEQ )
|
|
|
|
|
|
2014-06-10 13:56:58 +00:00
|
|
|
// takes a ... instead of a SEQ arg because it can be called with an empty SEQ
|
|
|
|
|
// from FC_CAPTURE_AND_THROW()
|
|
|
|
|
#define FC_FORMAT_ARG_PARAMS( ... )\
|
|
|
|
|
BOOST_PP_SEQ_FOR_EACH( FC_FORMAT_ARGS, v, __VA_ARGS__ )
|
2013-06-05 19:19:00 +00:00
|
|
|
|
2018-05-09 19:39:57 +00:00
|
|
|
#define fc_ddump( LOGGER, SEQ ) \
|
|
|
|
|
fc_dlog( LOGGER, FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
|
|
|
|
#define fc_idump( LOGGER, SEQ ) \
|
|
|
|
|
fc_ilog( LOGGER, FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
|
|
|
|
#define fc_wdump( LOGGER, SEQ ) \
|
|
|
|
|
fc_wlog( LOGGER, FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
|
|
|
|
#define fc_edump( LOGGER, SEQ ) \
|
|
|
|
|
fc_elog( LOGGER, FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
|
|
|
|
|
2015-08-04 14:24:31 +00:00
|
|
|
#define ddump( SEQ ) \
|
|
|
|
|
dlog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
2013-06-05 19:19:00 +00:00
|
|
|
#define idump( SEQ ) \
|
|
|
|
|
ilog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
2014-06-06 20:42:42 +00:00
|
|
|
#define wdump( SEQ ) \
|
|
|
|
|
wlog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
|
|
|
|
#define edump( SEQ ) \
|
|
|
|
|
elog( FC_FORMAT(SEQ), FC_FORMAT_ARG_PARAMS(SEQ) )
|
2013-06-05 19:19:00 +00:00
|
|
|
|
2014-10-03 20:52:45 +00:00
|
|
|
// this disables all normal logging statements -- not something you'd normally want to do,
|
|
|
|
|
// but it's useful if you're benchmarking something and suspect logging is causing
|
|
|
|
|
// a slowdown.
|
|
|
|
|
#ifdef FC_DISABLE_LOGGING
|
|
|
|
|
# undef ulog
|
2015-01-20 21:10:34 +00:00
|
|
|
# define ulog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
|
2014-10-03 20:52:45 +00:00
|
|
|
# undef elog
|
2015-01-20 21:10:34 +00:00
|
|
|
# define elog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
|
2014-10-03 20:52:45 +00:00
|
|
|
# undef wlog
|
2015-01-20 21:10:34 +00:00
|
|
|
# define wlog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
|
2014-10-03 20:52:45 +00:00
|
|
|
# undef ilog
|
2015-01-20 21:10:34 +00:00
|
|
|
# define ilog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
|
2014-10-03 20:52:45 +00:00
|
|
|
# undef dlog
|
2015-01-20 21:10:34 +00:00
|
|
|
# define dlog(...) FC_MULTILINE_MACRO_BEGIN FC_MULTILINE_MACRO_END
|
2015-08-04 14:24:31 +00:00
|
|
|
#endif
|