Merge pull request #279 from facontidavide/loglevel_per_sink
Loglevel per sink. Thanks @facontidavide
This commit is contained in:
		
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -45,6 +45,7 @@ example/*
 | 
				
			|||||||
!example/example.sln
 | 
					!example/example.sln
 | 
				
			||||||
!example/example.vcxproj
 | 
					!example/example.vcxproj
 | 
				
			||||||
!example/CMakeLists.txt
 | 
					!example/CMakeLists.txt
 | 
				
			||||||
 | 
					!example/multisink.cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# generated files
 | 
					# generated files
 | 
				
			||||||
generated
 | 
					generated
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,9 @@ target_link_libraries(example spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT})
 | 
				
			|||||||
add_executable(benchmark bench.cpp)
 | 
					add_executable(benchmark bench.cpp)
 | 
				
			||||||
target_link_libraries(benchmark spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT})
 | 
					target_link_libraries(benchmark spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_executable(multisink multisink.cpp)
 | 
				
			||||||
 | 
					target_link_libraries(multisink spdlog::spdlog ${CMAKE_THREAD_LIBS_INIT})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enable_testing()
 | 
					enable_testing()
 | 
				
			||||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
 | 
					file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/logs")
 | 
				
			||||||
add_test(NAME RunExample COMMAND example)
 | 
					add_test(NAME RunExample COMMAND example)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								example/multisink.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								example/multisink.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					#include "spdlog/spdlog.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace spd = spdlog;
 | 
				
			||||||
 | 
					int main(int, char*[])
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    bool enable_debug = true;
 | 
				
			||||||
 | 
					    try
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // This other example use a single logger with multiple sinks.
 | 
				
			||||||
 | 
					        // This means that the same log_msg is forwarded to multiple sinks;
 | 
				
			||||||
 | 
					        // Each sink can have it's own log level and a message will be logged.
 | 
				
			||||||
 | 
					        std::vector<spdlog::sink_ptr> sinks;
 | 
				
			||||||
 | 
					        sinks.push_back( std::make_shared<spdlog::sinks::stdout_sink_mt>() );
 | 
				
			||||||
 | 
					        sinks.push_back( std::make_shared<spdlog::sinks::simple_file_sink_mt>("./log_regular_file.txt") );
 | 
				
			||||||
 | 
					        sinks.push_back( std::make_shared<spdlog::sinks::simple_file_sink_mt>("./log_debug_file.txt") );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        spdlog::logger console_multisink("multisink",  sinks.begin(), sinks.end() );
 | 
				
			||||||
 | 
					        console_multisink.set_level( spdlog::level::warn);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        sinks[0]->set_level( spdlog::level::trace);  // console. Allow everything.  Default value
 | 
				
			||||||
 | 
					        sinks[1]->set_level( spdlog::level::trace);  //  regular file. Allow everything.  Default value
 | 
				
			||||||
 | 
					        sinks[2]->set_level( spdlog::level::off);    //  regular file. Ignore everything.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        console_multisink.warn("warn: will print only on console and regular file");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if( enable_debug )
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            console_multisink.set_level( spdlog::level::debug); // level of the logger
 | 
				
			||||||
 | 
					            sinks[1]->set_level( spdlog::level::debug);  // regular file
 | 
				
			||||||
 | 
					            sinks[2]->set_level( spdlog::level::debug);  // debug file
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        console_multisink.debug("Debug: you should see this on console and both files");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Release and close all loggers
 | 
				
			||||||
 | 
					        spdlog::drop_all();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    // Exceptions will only be thrown upon failed logger or sink construction (not during logging)
 | 
				
			||||||
 | 
					    catch (const spd::spdlog_ex& ex)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        std::cout << "Log init failed: " << ex.what() << std::endl;
 | 
				
			||||||
 | 
					        return 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -303,8 +303,11 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
 | 
				
			|||||||
            log_msg incoming_log_msg;
 | 
					            log_msg incoming_log_msg;
 | 
				
			||||||
            incoming_async_msg.fill_log_msg(incoming_log_msg);
 | 
					            incoming_async_msg.fill_log_msg(incoming_log_msg);
 | 
				
			||||||
            _formatter->format(incoming_log_msg);
 | 
					            _formatter->format(incoming_log_msg);
 | 
				
			||||||
            for (auto &s : _sinks)
 | 
					            for (auto &s : _sinks){
 | 
				
			||||||
                s->log(incoming_log_msg);
 | 
					                if(s->should_log( incoming_log_msg.level)){
 | 
				
			||||||
 | 
					                    s->log(incoming_log_msg);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -317,7 +320,6 @@ inline bool spdlog::details::async_log_helper::process_next_msg(log_clock::time_
 | 
				
			|||||||
        handle_flush_interval(now, last_flush);
 | 
					        handle_flush_interval(now, last_flush);
 | 
				
			||||||
        sleep_or_yield(now, last_pop);
 | 
					        sleep_or_yield(now, last_pop);
 | 
				
			||||||
        return !_terminate_requested;
 | 
					        return !_terminate_requested;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -245,8 +245,11 @@ inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) cons
 | 
				
			|||||||
inline void spdlog::logger::_sink_it(details::log_msg& msg)
 | 
					inline void spdlog::logger::_sink_it(details::log_msg& msg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _formatter->format(msg);
 | 
					    _formatter->format(msg);
 | 
				
			||||||
    for (auto &sink : _sinks)
 | 
					    for (auto &sink : _sinks){
 | 
				
			||||||
        sink->log(msg);
 | 
					        if( sink->should_log( msg.level)){
 | 
				
			||||||
 | 
					            sink->log(msg);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(_should_flush_on(msg))
 | 
					    if(_should_flush_on(msg))
 | 
				
			||||||
        flush();
 | 
					        flush();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,11 +35,13 @@ protected:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void _sink_it(const details::log_msg& msg) override
 | 
					    void _sink_it(const details::log_msg& msg) override
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        for (auto &sink : _sinks)
 | 
					        for (auto &sink : _sinks){
 | 
				
			||||||
            sink->log(msg);
 | 
					            if( sink->should_log( msg.level)){
 | 
				
			||||||
 | 
					                sink->log(msg);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
    void flush() override
 | 
					    void flush() override
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,10 +15,33 @@ namespace sinks
 | 
				
			|||||||
class sink
 | 
					class sink
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
 | 
					    sink(): _level( level::trace ) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual ~sink() {}
 | 
					    virtual ~sink() {}
 | 
				
			||||||
    virtual void log(const details::log_msg& msg) = 0;
 | 
					    virtual void log(const details::log_msg& msg) = 0;
 | 
				
			||||||
    virtual void flush() = 0;
 | 
					    virtual void flush() = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    bool should_log(level::level_enum msg_level) const;
 | 
				
			||||||
 | 
					    void set_level(level::level_enum log_level);
 | 
				
			||||||
 | 
					    level::level_enum level() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
					    level_t _level;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline bool sink::should_log(level::level_enum msg_level) const {
 | 
				
			||||||
 | 
					    return msg_level >= _level.load(std::memory_order_relaxed);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline void sink::set_level(level::level_enum log_level) {
 | 
				
			||||||
 | 
					    _level.store(log_level);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					inline level::level_enum sink::level() const {
 | 
				
			||||||
 | 
					    return static_cast<spdlog::level::level_enum>(_level.load(std::memory_order_relaxed));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user