diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bb6abb1..66faa235 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -146,7 +146,8 @@ set(SPDLOG_HEADERS "include/spdlog/sinks/systemd_sink.h" "include/spdlog/sinks/tcp_sink.h" "include/spdlog/sinks/udp_sink.h" - "include/spdlog/sinks/async_sink.h") + "include/spdlog/sinks/async_sink.h" + "include/spdlog/attributes.h") set(SPDLOG_SRCS "src/common.cpp" "src/logger.cpp" diff --git a/include/spdlog/attributes.h b/include/spdlog/attributes.h new file mode 100644 index 00000000..63ac12c7 --- /dev/null +++ b/include/spdlog/attributes.h @@ -0,0 +1,88 @@ +#pragma once + +#include + +#include +#include + +namespace spdlog { + +class SPDLOG_API log_attributes { +public: + using attr_map_t = std::unordered_map; + using key_t = attr_map_t::key_type; + using value_t = attr_map_t::mapped_type; + using const_iter = attr_map_t::const_iterator; + + log_attributes() = default; + log_attributes(const log_attributes& other) { + const auto& o_map = other.get_map(); + attr_ctx(o_map.begin(), o_map.end()); + } + log_attributes& operator=(const log_attributes& other) { + if (this != &other) { + clear(); + const auto& o_map = other.get_map(); + attr_ctx(o_map.begin(), o_map.end()); + } + return *this; + } + + void put(const key_t& key, const value_t& value) { + auto lck = lock(); + attrs[key] = value; + } + + void remove(const key_t& key) { + auto lck = lock(); + auto value_it = attrs.find(key); + if (value_it != attrs.end()) { + attrs.erase(key); + } + } + + void clear() { + auto lck = lock(); + attrs.clear(); + } + + bool empty() const { + auto lck = lock(); + return attrs.empty(); + } + + std::pair const get(key_t const& key) const { + auto lck = lock(); + auto value_it = attrs.find(key); + + return std::make_pair(value_it == attrs.end(), value_it); + } + + // provide a local copy of the attributes to be free of race issues + // alternative is to lock the attr_map while the formatter iterates over it + attr_map_t get_map() const { + auto lck = lock(); + return attrs; + } + + template + void attr_ctx(Attribute_Iter begin, Attribute_Iter end) { + auto lck = lock(); + attrs.insert(begin, end); + } + + void attr_ctx(std::initializer_list attributes) { attr_ctx(attributes.begin(), attributes.end()); } + + bool empty() { + auto lck = lock(); + return attrs.empty(); + } + +private: + std::lock_guard lock() const { return std::lock_guard(attrs_mtx); } + + mutable std::mutex attrs_mtx; + attr_map_t attrs; +}; + +} // namespace spdlog \ No newline at end of file