#ifndef BOOSTLOG_INL #define BOOSTLOG_INL #include "BoostLog.h" #include "StreamFormat.h" #include "boost/log/sources/basic_logger.hpp" #include "boost/log/trivial.hpp" #include "boost/scope_exit.hpp" #include #include template class LogPredicator { public: operator bool() const { bool ret = m_status; m_status = !m_status; if (ret) { ret = doOnceInterface(); if (!ret) m_status = true; } return ret; } inline bool doOnceInterface() const { return static_cast(this)->doOnce(); } protected: mutable bool m_status = true; }; class NumberPredicator : public LogPredicator { public: NumberPredicator(int limit) : m_limit(limit) {} inline bool doOnce() const { return (m_current++ % m_limit) == 0; } private: int m_limit; mutable int m_current{0}; }; class CountPredicator : public LogPredicator { public: CountPredicator(int limit) : m_limit(limit) {} inline bool doOnce() const { return m_current++ < m_limit; } private: int m_limit; mutable int m_current{0}; }; class TimePredicator : public LogPredicator { public: TimePredicator(int milliseconds) : m_limit(std::chrono::milliseconds(milliseconds)) {} inline bool doOnce() const { auto now = std::chrono::system_clock::now(); auto duration = std::chrono::duration_cast(now - m_current); bool ret = duration >= m_limit; if (ret) m_current = now; return ret; } private: std::chrono::milliseconds m_limit; mutable decltype(std::chrono::system_clock::now()) m_current{std::chrono::system_clock::now()}; }; template CategoryTaggerFeature::CategoryTaggerFeature(const CategoryTaggerFeature &obj) : BaseT(static_cast(obj)) { } template template CategoryTaggerFeature::CategoryTaggerFeature(const ArgsT &args) : BaseT(args) { } template template boost::log::record CategoryTaggerFeature::open_record_unlocked(const ArgsT &args) { std::string tag_value = args[AmassKeywords::CategoryTag | std::string()]; boost::log::attribute_set &attrs = BaseT::attributes(); boost::log::attribute_set::iterator tag = attrs.end(); if (!tag_value.empty()) { // Add the tag as a new attribute std::pair res = BaseT::add_attribute_unlocked("Category", boost::log::attributes::constant(tag_value)); if (res.second) tag = res.first; } BOOST_SCOPE_EXIT_TPL((&tag)(&attrs)) { if (tag != attrs.end()) attrs.erase(tag); } BOOST_SCOPE_EXIT_END return BaseT::open_record_unlocked(args); } template FilenameTaggerFeature::FilenameTaggerFeature(const FilenameTaggerFeature &obj) : BaseT(static_cast(obj)) { } template template FilenameTaggerFeature::FilenameTaggerFeature(const ArgsT &args) : BaseT(args) {} template template boost::log::record FilenameTaggerFeature::open_record_unlocked(const ArgsT &args) { std::string tag_value = args[AmassKeywords::FilenameTag | std::string()]; boost::log::attribute_set &attrs = BaseT::attributes(); boost::log::attribute_set::iterator tag = attrs.end(); if (!tag_value.empty()) { // Add the tag as a new attribute std::pair res = BaseT::add_attribute_unlocked("Filename", boost::log::attributes::constant(tag_value)); if (res.second) tag = res.first; } BOOST_SCOPE_EXIT_TPL((&tag)(&attrs)) { if (tag != attrs.end()) attrs.erase(tag); } BOOST_SCOPE_EXIT_END return BaseT::open_record_unlocked(args); } template FunctionTaggerFeature::FunctionTaggerFeature(const FunctionTaggerFeature &obj) : BaseT(static_cast(obj)) { } template template FunctionTaggerFeature::FunctionTaggerFeature(const ArgsT &args) : BaseT(args) {} template template boost::log::record FunctionTaggerFeature::open_record_unlocked(const ArgsT &args) { std::string tag_value = args[AmassKeywords::FunctionTag | std::string()]; boost::log::attribute_set &attrs = BaseT::attributes(); boost::log::attribute_set::iterator tag = attrs.end(); if (!tag_value.empty()) { // Add the tag as a new attribute std::pair res = BaseT::add_attribute_unlocked("Function", boost::log::attributes::constant(tag_value)); if (res.second) tag = res.first; } BOOST_SCOPE_EXIT_TPL((&tag)(&attrs)) { if (tag != attrs.end()) attrs.erase(tag); } BOOST_SCOPE_EXIT_END return BaseT::open_record_unlocked(args); } template template LineTaggerFeature::LineTaggerFeature(const ArgsT &args) : BaseT(args) {} template LineTaggerFeature::LineTaggerFeature(const LineTaggerFeature &obj) : BaseT(static_cast(obj)) {} template template boost::log::record LineTaggerFeature::open_record_unlocked(const ArgsT &args) { size_t tag_value = args[AmassKeywords::LineTag | size_t()]; boost::log::attribute_set &attrs = BaseT::attributes(); boost::log::attribute_set::iterator tag = attrs.end(); // Add the tag as a new attribute std::pair res = BaseT::add_attribute_unlocked("Line", boost::log::attributes::constant(tag_value)); if (res.second) tag = res.first; BOOST_SCOPE_EXIT_TPL((&tag)(&attrs)) { if (tag != attrs.end()) attrs.erase(tag); } BOOST_SCOPE_EXIT_END return BaseT::open_record_unlocked(args); } #endif // BOOSTLOG_INL