156 lines
5.1 KiB
C++
156 lines
5.1 KiB
C++
#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 <chrono>
|
|
#include <iomanip>
|
|
|
|
template <typename Derived>
|
|
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<const Derived *>(this)->doOnce(); }
|
|
|
|
protected:
|
|
mutable bool m_status = true;
|
|
};
|
|
|
|
class NumberPredicator : public LogPredicator<NumberPredicator> {
|
|
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<CountPredicator> {
|
|
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<TimePredicator> {
|
|
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<std::chrono::milliseconds>(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 <typename BaseT>
|
|
CategoryTaggerFeature<BaseT>::CategoryTaggerFeature(const CategoryTaggerFeature &obj)
|
|
: BaseT(static_cast<const BaseT &>(obj)) {
|
|
}
|
|
|
|
template <typename BaseT>
|
|
template <typename ArgsT>
|
|
CategoryTaggerFeature<BaseT>::CategoryTaggerFeature(const ArgsT &args) : BaseT(args) {
|
|
}
|
|
|
|
template <typename BaseT>
|
|
template <typename ArgsT>
|
|
boost::log::record CategoryTaggerFeature<BaseT>::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<boost::log::attribute_set::iterator, bool> res =
|
|
BaseT::add_attribute_unlocked("Category", boost::log::attributes::constant<std::string>(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 <typename BaseT>
|
|
FilenameTaggerFeature<BaseT>::FilenameTaggerFeature(const FilenameTaggerFeature &obj)
|
|
: BaseT(static_cast<const BaseT &>(obj)) {
|
|
}
|
|
|
|
template <typename BaseT>
|
|
template <typename ArgsT>
|
|
FilenameTaggerFeature<BaseT>::FilenameTaggerFeature(const ArgsT &args) : BaseT(args) {}
|
|
|
|
template <typename BaseT>
|
|
template <typename ArgsT>
|
|
boost::log::record FilenameTaggerFeature<BaseT>::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<boost::log::attribute_set::iterator, bool> res =
|
|
BaseT::add_attribute_unlocked("Filename", boost::log::attributes::constant<std::string>(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 <typename BaseT>
|
|
template <typename ArgsT>
|
|
LineTaggerFeature<BaseT>::LineTaggerFeature(const ArgsT &args) : BaseT(args) {}
|
|
|
|
template <typename BaseT>
|
|
LineTaggerFeature<BaseT>::LineTaggerFeature(const LineTaggerFeature &obj) : BaseT(static_cast<const BaseT &>(obj)) {}
|
|
|
|
template <typename BaseT>
|
|
template <typename ArgsT>
|
|
boost::log::record LineTaggerFeature<BaseT>::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<boost::log::attribute_set::iterator, bool> res =
|
|
BaseT::add_attribute_unlocked("Line", boost::log::attributes::constant<size_t>(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
|