implementing the custom property feature with a hash map owned by the logger, including an example

pull/353/head
Andre Abrantes 9 years ago
parent 35865ee54e
commit 9285bbf256

@ -57,6 +57,13 @@ int main(int, char*[])
spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***"); spd::set_pattern("*** [%H:%M:%S %z] [thread %t] %v ***");
rotating_logger->info("This is another message with custom format"); rotating_logger->info("This is another message with custom format");
// Using a per-logger dynamic property map
console->set_pattern("*** [%H:%M:%S %z] [thread %t] [%{property_name}] %v ***");
auto properties = console->properties();
(*properties)["property_name"] = "some property";
console->info("This message has a custom property");
(*properties)["property_name"] = "new property";
console->info("The property has changed");
// Runtime log levels // Runtime log levels
spd::set_level(spd::level::info); //Set global log level to info spd::set_level(spd::level::info); //Set global log level to info

@ -56,13 +56,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries> <UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries> <UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset> <PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization> <WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet> <CharacterSet>Unicode</CharacterSet>
</PropertyGroup> </PropertyGroup>

@ -65,7 +65,7 @@ inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_forma
inline void spdlog::async_logger::_set_pattern(const std::string& pattern) inline void spdlog::async_logger::_set_pattern(const std::string& pattern)
{ {
_formatter = std::make_shared<pattern_formatter>(pattern); _formatter = std::make_shared<pattern_formatter>(pattern, _properties);
_async_log_helper->set_formatter(_formatter); _async_log_helper->set_formatter(_formatter);
} }

@ -18,7 +18,8 @@ template<class It>
inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end): inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end):
_name(logger_name), _name(logger_name),
_sinks(begin, end), _sinks(begin, end),
_formatter(std::make_shared<pattern_formatter>("%+")) _properties(std::make_shared<std::unordered_map<std::string, std::string>>()),
_formatter(std::make_shared<pattern_formatter>("%+", _properties))
{ {
_level = level::info; _level = level::info;
_flush_level = level::off; _flush_level = level::off;
@ -57,6 +58,11 @@ inline void spdlog::logger::set_pattern(const std::string& pattern)
_set_pattern(pattern); _set_pattern(pattern);
} }
inline std::shared_ptr<std::unordered_map<std::string, std::string>> spdlog::logger::properties() const
{
return _properties;
}
template <typename... Args> template <typename... Args>
inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args) inline void spdlog::logger::log(level::level_enum lvl, const char* fmt, const Args&... args)
@ -259,7 +265,7 @@ inline void spdlog::logger::_sink_it(details::log_msg& msg)
inline void spdlog::logger::_set_pattern(const std::string& pattern) inline void spdlog::logger::_set_pattern(const std::string& pattern)
{ {
_formatter = std::make_shared<pattern_formatter>(pattern); _formatter = std::make_shared<pattern_formatter>(pattern, _properties);
} }
inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter)
{ {

@ -396,6 +396,25 @@ private:
char _ch; char _ch;
}; };
class property_formatter:public flag_formatter
{
public:
explicit property_formatter(std::shared_ptr<std::unordered_map<std::string, std::string>> properties, const std::string& property_name)
: properties(properties), property_name(property_name)
{}
void format(details::log_msg& msg, const std::tm&) override
{
auto it = properties->find(property_name);
if (it != properties->end())
msg.formatted << it->second;
else
msg.formatted << "null";
}
private:
std::shared_ptr<std::unordered_map<std::string, std::string>> properties;
std::string property_name;
};
//aggregate user chars to display as is //aggregate user chars to display as is
class aggregate_formatter:public flag_formatter class aggregate_formatter:public flag_formatter
@ -469,7 +488,7 @@ class full_formatter:public flag_formatter
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// pattern_formatter inline impl // pattern_formatter inline impl
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern) inline spdlog::pattern_formatter::pattern_formatter(const std::string& pattern, std::shared_ptr<std::unordered_map<std::string, std::string>> properties): properties(properties)
{ {
compile_pattern(pattern); compile_pattern(pattern);
} }
@ -485,10 +504,29 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter
if (user_chars) //append user chars found so far if (user_chars) //append user chars found so far
_formatters.push_back(std::move(user_chars)); _formatters.push_back(std::move(user_chars));
if (++it != end) if (++it == end)
handle_flag(*it);
else
break; break;
// the right brace must be found and the string consumed up until it
if (*it == '{')
{
auto key_start_pos = it + 1 - pattern.begin();
auto key_end_pos = pattern.find('}', key_start_pos);
// ignoring rest of the pattern
if (key_end_pos == pattern.size())
break;
auto key_length = key_end_pos - key_start_pos;
auto key = pattern.substr(key_start_pos, key_length);
handle_flag(*it, key);
it += key_length + 1;
}
else
{
handle_flag(*it);
}
} }
else // chars not following the % sign should be displayed as is else // chars not following the % sign should be displayed as is
{ {
@ -501,9 +539,9 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter
{ {
_formatters.push_back(std::move(user_chars)); _formatters.push_back(std::move(user_chars));
} }
} }
inline void spdlog::pattern_formatter::handle_flag(char flag)
inline void spdlog::pattern_formatter::handle_flag(char flag, const std::string& param)
{ {
switch (flag) switch (flag)
{ {
@ -625,6 +663,9 @@ inline void spdlog::pattern_formatter::handle_flag(char flag)
case ('P'): case ('P'):
_formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::pid_formatter())); _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::pid_formatter()));
break; break;
case ('{'):
_formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::property_formatter(properties, param)));
break;
default: //Unkown flag appears as is default: //Unkown flag appears as is
_formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::ch_formatter('%'))); _formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::ch_formatter('%')));

@ -111,9 +111,11 @@ public:
void set_pattern(const std::string& pattern) void set_pattern(const std::string& pattern)
{ {
std::lock_guard<Mutex> lock(_mutex); std::lock_guard<Mutex> lock(_mutex);
_formatter = std::make_shared<pattern_formatter>(pattern);
for (auto& l : _loggers) for (auto& l : _loggers)
{
_formatter = std::make_shared<pattern_formatter>(pattern, l.second->properties());
l.second->set_formatter(_formatter); l.second->set_formatter(_formatter);
}
} }
void set_level(level::level_enum log_level) void set_level(level::level_enum log_level)

@ -7,9 +7,9 @@
#include <spdlog/details/log_msg.h> #include <spdlog/details/log_msg.h>
#include <vector>
#include <string>
#include <memory> #include <memory>
#include <unordered_map>
#include <vector>
namespace spdlog namespace spdlog
{ {
@ -29,14 +29,16 @@ class pattern_formatter : public formatter
{ {
public: public:
explicit pattern_formatter(const std::string& pattern); explicit pattern_formatter(const std::string& pattern, std::shared_ptr<std::unordered_map<std::string, std::string>> properties);
pattern_formatter(const pattern_formatter&) = delete; pattern_formatter(const pattern_formatter&) = delete;
pattern_formatter& operator=(const pattern_formatter&) = delete; pattern_formatter& operator=(const pattern_formatter&) = delete;
void format(details::log_msg& msg) override; void format(details::log_msg& msg) override;
private: private:
const std::string _pattern; const std::string _pattern;
std::vector<std::unique_ptr<details::flag_formatter>> _formatters; std::vector<std::unique_ptr<details::flag_formatter>> _formatters;
void handle_flag(char flag); std::shared_ptr<std::unordered_map<std::string, std::string>> properties;
void handle_flag(char flag, const std::string& param="");
void compile_pattern(const std::string& pattern); void compile_pattern(const std::string& pattern);
}; };
} }

@ -15,9 +15,9 @@
#include <spdlog/sinks/base_sink.h> #include <spdlog/sinks/base_sink.h>
#include <spdlog/common.h> #include <spdlog/common.h>
#include <vector>
#include <memory> #include <memory>
#include <string> #include <unordered_map>
#include <vector>
namespace spdlog namespace spdlog
{ {
@ -59,6 +59,8 @@ public:
void set_pattern(const std::string&); void set_pattern(const std::string&);
void set_formatter(formatter_ptr); void set_formatter(formatter_ptr);
std::shared_ptr<std::unordered_map<std::string, std::string>> properties() const;
// error handler // error handler
void set_error_handler(log_err_handler); void set_error_handler(log_err_handler);
log_err_handler error_handler(); log_err_handler error_handler();
@ -83,6 +85,7 @@ protected:
const std::string _name; const std::string _name;
std::vector<sink_ptr> _sinks; std::vector<sink_ptr> _sinks;
std::shared_ptr<std::unordered_map<std::string, std::string>> _properties;
formatter_ptr _formatter; formatter_ptr _formatter;
spdlog::level_t _level; spdlog::level_t _level;
spdlog::level_t _flush_level; spdlog::level_t _flush_level;

Loading…
Cancel
Save