X-Git-Url: https://code.wpia.club/?a=blobdiff_plain;f=src%2Flog%2Flogger.hpp;h=aabbb673568ad31ea27e5784b77b1a0c2572847e;hb=90a79f28e095c7e368971ee5408ba8a10e0043c9;hp=6d1e5e50d0f9b9b0a33075ac69a8300ea3f32c05;hpb=04d8d3826d411d61f11a930e4ffcc03e136992ca;p=cassiopeia.git diff --git a/src/log/logger.hpp b/src/log/logger.hpp index 6d1e5e5..aabbb67 100644 --- a/src/log/logger.hpp +++ b/src/log/logger.hpp @@ -1,16 +1,16 @@ #pragma once -#include +#include +#include +#include #include #include #include +#include +#include namespace logger { - enum class level { - debug, note, warn, error, fatal - }; - /** * conv::to_string will be used to convert whatever argument is send * to the logger to a string. If another type shall be supported, @@ -33,25 +33,168 @@ namespace logger { inline std::string to_string( const char* arg ) { return arg; } + + } // namespace conv + + enum class level { + debug, note, warn, error, fatal + }; + + const auto default_level = level::note; + + struct log_target { + log_target( std::ostream& stream, level min_level = default_level ): + stream {&stream}, min_level {min_level} {} + log_target( std::ofstream& stream, level min_level = default_level ): + stream {&stream}, min_level {min_level} { + if( !stream.is_open() ) { + throw std::runtime_error {"logfile not open"}; + } + } + std::ostream* stream; + level min_level; + }; + + class logger_set; + namespace impl { + void reassign_stack_pointer( logger_set*& ptr ); } + /** + * Provides controll over wether a logger should automatically register itself + */ + enum class auto_register { + on, off + }; + + class logger_set { + public: + logger_set( std::initializer_list lst, auto_register = auto_register::on ); + + logger_set( logger_set&& ) noexcept; + logger_set& operator=( logger_set && ) noexcept; + ~logger_set(); + + template + void log( level l, Args&& ... args ); + template + void logf( level l, const std::string& format, Args&& ... args ); + + template + void debug( Args&& ... args ); + template + void debugf( const std::string& format, Args&& ... args ); + + template + void note( Args&& ... args ); + template + void notef( const std::string& format, Args&& ... args ); + + template + void warn( Args&& ... args ); + template + void warnf( const std::string& format, Args&& ... args ); + + template + void error( Args&& ... args ); + template + void errorf( const std::string& format, Args&& ... args ); + + template + void fatal( Args&& ... args ); + template + void fatalf( const std::string& format, Args&& ... args ); + + friend void impl::reassign_stack_pointer( logger_set*& ptr ); + friend logger_set current_logger_extended( std::initializer_list further_targets ); + private: + void log_impl( level l, const std::string& msg ); + + std::vector m_loggers; + logger_set** m_stackpointer = nullptr; + level m_min_level; + }; + + logger_set current_logger_extended( std::initializer_list further_targets ); + namespace impl { - void log( level, const std::vector& args ); - void logf( level, const std::string&, std::vector args ); + std::string concat_msg( level l, const std::vector& args ); + std::string format_msg( level l, const std::string&, std::vector args ); + logger_set& active_logger(); } - void set_stream( std::ostream& ); + template + void logger_set::log( level l, Args&& ... data ) { + if( l < m_min_level ) { + return; + } + + log_impl( l, impl::concat_msg( l, {conv::to_string( std::forward( data ) )...} ) ); + } template - void log( level l, Args&& ... data ) { - impl::log( l, {conv::to_string( std::forward( data ) )...} ); + void logger_set::logf( level l, const std::string& format, Args&& ... data ) { + if( l < m_min_level ) { + return; + } + + log_impl( l, impl::format_msg( l, format, {conv::to_string( std::forward( data ) )...} ) ); } template - void logf( level l, const std::string& format, Args&& ... data ) { - impl::logf( l, format, {conv::to_string( std::forward( data ) )...} ); + void log( level l, Args&& ... args ) { + impl::active_logger().log( l, std::forward( args )... ); + } + template + void logf( level l, const std::string& format, Args&& ... args ) { + impl::active_logger().logf( l, format, std::forward( args )... ); + } + + // concat-based methods + template + void logger_set::debug( Args&& ... args ) { + log( level::debug, std::forward( args )... ); + } + template + void logger_set::note( Args&& ... args ) { + log( level::note, std::forward( args )... ); + } + template + void logger_set::warn( Args&& ... args ) { + log( level::warn, std::forward( args )... ); + } + template + void logger_set::error( Args&& ... args ) { + log( level::error, std::forward( args )... ); + } + template + void logger_set::fatal( Args&& ... args ) { + log( level::fatal, std::forward( args )... ); + } + + // format-based methods + template + void logger_set::debugf( const std::string& fmt, Args&& ... args ) { + logf( level::debug, fmt, std::forward( args )... ); + } + template + void logger_set::notef( const std::string& fmt, Args&& ... args ) { + logf( level::note, fmt, std::forward( args )... ); + } + template + void logger_set::warnf( const std::string& fmt, Args&& ... args ) { + logf( level::warn, fmt, std::forward( args )... ); + } + template + void logger_set::errorf( const std::string& fmt, Args&& ... args ) { + logf( level::error, fmt, std::forward( args )... ); + } + template + void logger_set::fatalf( const std::string& fmt, Args&& ... args ) { + logf( level::fatal, fmt, std::forward( args )... ); } + // global concat-based template void debug( Args&& ... args ) { log( level::debug, std::forward( args )... ); @@ -73,6 +216,7 @@ namespace logger { log( level::fatal, std::forward( args )... ); } + // global format-based template void debugf( const std::string& fmt, Args&& ... args ) { logf( level::debug, fmt, std::forward( args )... );