mirror of
https://github.com/gabime/spdlog.git
synced 2024-11-16 00:45:48 +08:00
Merge pull request #279 from facontidavide/loglevel_per_sink
Loglevel per sink. Thanks @facontidavide
This commit is contained in:
commit
59bf37f769
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));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user