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 ***");
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
spd::set_level(spd::level::info); //Set global log level to info

@ -56,13 +56,13 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v120</PlatformToolset>
<PlatformToolset>v140</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</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)
{
_formatter = std::make_shared<pattern_formatter>(pattern);
_formatter = std::make_shared<pattern_formatter>(pattern, _properties);
_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):
_name(logger_name),
_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;
_flush_level = level::off;
@ -57,6 +58,11 @@ inline void spdlog::logger::set_pattern(const std::string& pattern)
_set_pattern(pattern);
}
inline std::shared_ptr<std::unordered_map<std::string, std::string>> spdlog::logger::properties() const
{
return _properties;
}
template <typename... 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)
{
_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)
{

@ -396,6 +396,25 @@ private:
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
class aggregate_formatter:public flag_formatter
@ -469,7 +488,7 @@ class full_formatter:public flag_formatter
///////////////////////////////////////////////////////////////////////////////
// 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);
}
@ -485,10 +504,29 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter
if (user_chars) //append user chars found so far
_formatters.push_back(std::move(user_chars));
if (++it != end)
handle_flag(*it);
else
if (++it == end)
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
{
@ -501,9 +539,9 @@ inline void spdlog::pattern_formatter::compile_pattern(const std::string& patter
{
_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)
{
@ -625,6 +663,9 @@ inline void spdlog::pattern_formatter::handle_flag(char flag)
case ('P'):
_formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::pid_formatter()));
break;
case ('{'):
_formatters.push_back(std::unique_ptr<details::flag_formatter>(new details::property_formatter(properties, param)));
break;
default: //Unkown flag appears as is
_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)
{
std::lock_guard<Mutex> lock(_mutex);
_formatter = std::make_shared<pattern_formatter>(pattern);
for (auto& l : _loggers)
{
_formatter = std::make_shared<pattern_formatter>(pattern, l.second->properties());
l.second->set_formatter(_formatter);
}
}
void set_level(level::level_enum log_level)

@ -7,9 +7,9 @@
#include <spdlog/details/log_msg.h>
#include <vector>
#include <string>
#include <memory>
#include <unordered_map>
#include <vector>
namespace spdlog
{
@ -29,14 +29,16 @@ class pattern_formatter : public formatter
{
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& operator=(const pattern_formatter&) = delete;
void format(details::log_msg& msg) override;
private:
const std::string _pattern;
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);
};
}

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

Loading…
Cancel
Save