1#include "Framework/Logger.h"
8#include <unordered_map>
12#include <boost/core/null_deleter.hpp>
13#include <boost/log/attributes/value_extraction.hpp>
14#include <boost/log/core/core.hpp>
15#include <boost/log/expressions/message.hpp>
16#include <boost/log/sinks/sync_frontend.hpp>
17#include <boost/log/sinks/text_ostream_backend.hpp>
18#include <boost/log/utility/formatting_ostream.hpp>
19#include <boost/log/utility/setup/common_attributes.hpp>
20#include <boost/smart_ptr/make_shared_object.hpp>
21#include <boost/smart_ptr/shared_ptr.hpp>
23#include "Framework/Configure/Parameters.h"
29namespace sinks = boost::log::sinks;
40level convertLevel(
int iLvl) {
48logger makeLogger(
const std::string& name) {
49 logger lg(log::keywords::channel = name);
50 return boost::move(lg);
54const T& safeExtract(log::attribute_value attr) {
55 static const T empty_value = {};
56 auto attr_val = log::extract<T>(attr);
72 level fallback_level_;
73 std::unordered_map<std::string, level> custom_levels_;
76 Filter(level fallback, std::unordered_map<std::string, level> custom)
77 : fallback_level_{fallback}, custom_levels_{custom} {}
79 bool operator()(log::attribute_value_set
const& attrs) {
80 auto it = custom_levels_.find(safeExtract<std::string>(attrs[
"Channel"]));
81 if (it != custom_levels_.end()) {
82 return safeExtract<level>(attrs[
"Severity"]) >= it->second;
84 return safeExtract<level>(attrs[
"Severity"]) >= fallback_level_;
90 typedef sinks::text_ostream_backend ourSinkBack_t;
91 typedef sinks::synchronous_sink<ourSinkBack_t> ourSinkFront_t;
93 level file_level{convertLevel(p.
get<
int>(
"file_level", 0))};
94 std::string file_path{p.
get<std::string>(
"file_path",
"")};
96 level term_level{convertLevel(p.
get<
int>(
"term_level", 4))};
97 std::vector<framework::config::Parameters> empty{};
98 const auto& log_rules{
99 p.
get<std::vector<framework::config::Parameters>>(
"log_rules", empty)};
100 std::unordered_map<std::string, level> custom_levels;
101 for (
const auto& log_rule : log_rules) {
102 custom_levels[log_rule.get<std::string>(
"name")] =
103 convertLevel(log_rule.get<
int>(
"level"));
111 log::add_common_attributes();
114 boost::shared_ptr<log::core> core = log::core::get();
118 if (not file_path.empty()) {
119 boost::shared_ptr<ourSinkBack_t> file_back =
120 boost::make_shared<ourSinkBack_t>();
121 file_back->add_stream(boost::make_shared<std::ofstream>(file_path));
123 boost::shared_ptr<ourSinkFront_t> file_sink =
124 boost::make_shared<ourSinkFront_t>(file_back);
127 file_sink->set_filter(Filter(file_level, custom_levels));
128 file_sink->set_formatter(
129 [](
const log::record_view& view, log::formatting_ostream& os) {
132 core->add_sink(file_sink);
136 boost::shared_ptr<ourSinkBack_t> term_back =
137 boost::make_shared<ourSinkBack_t>();
138 term_back->add_stream(boost::shared_ptr<std::ostream>(
140 boost::null_deleter()
143 term_back->auto_flush(
true);
145 boost::shared_ptr<ourSinkFront_t> term_sink =
146 boost::make_shared<ourSinkFront_t>(term_back);
149 term_sink->set_filter(Filter(term_level, custom_levels));
151 term_sink->set_formatter(
152 [](
const log::record_view& view, log::formatting_ostream& os) {
155 core->add_sink(term_sink);
163 log::core::get()->remove_all_sinks();
170 return the_formatter;
176 log::formatting_ostream& os) {
177 os <<
"[ " << log::extract<std::string>(
"Channel", view) <<
" ] "
178 << event_number_ <<
" ";
183 const level msg_level{safeExtract<level>(view[
"Severity"])};
213 os <<
": " << view[log::expressions::smessage];
Class encapsulating parameters for configuring a processor.
const T & get(const std::string &name) const
Retrieve the parameter of the given name.
Our filter implementation aligning with Boost.Log.
All classes in the ldmx-sw project use this namespace.