Boost logo

Boost :

From: Volker (boost_at_[hidden])
Date: 2021-10-15 12:46:23


Dear Boost experts!

I'm new to this list, so please have mercy if I'm not yet familiar with
your best practices.

Recently, I have been pulling my hair out while trying to use boost::log
for a severity-logger-type functionality where the sink backend is not
compatible with std::ostream. Best bet was to implement a custom sink
backend that does the job in its consume() member.

However, I can't get the attribute value for the severity level
extracted to an int. For sure, there's something totally obvious I'm
missing... Here's the source code (slightly abbreviated):

#include <string>
#include <boost/log/core.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/basic_sink_backend.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
#include <boost/smart_ptr/make_shared_object.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>

namespace logging = boost::log;
namespace sinks = boost::log::sinks;

void SomeLogChannel(int severity, const std::string& message) {}

class SinkBackend : public sinks::basic_sink_backend<sinks::synchronized_feeding>
{
public:
    explicit SinkBackend() {}
    void consume(logging::record_view const& rec)
    {
        std::string message = *rec[boost::log::expressions::smessage];
        int severity = 0;
        if (rec.attribute_values().count("Severity"))
        {
            // severity = rec.attribute_values()["Severity"].extract<int>(); // cannot convert from 'boost::log::v2s_mt_nt6::value_ref<T,TagT>' to 'int' with T=int, TagT=void
        }
        SomeLogChannel(severity, message);
    }
};

void init_logging()
{
    typedef sinks::synchronous_sink<SinkBackend> sink_t;
    boost::shared_ptr<logging::core> core = logging::core::get();
    boost::shared_ptr<SinkBackend> backend(new SinkBackend());
    boost::shared_ptr<sink_t> sink(new sink_t(backend));
    core->add_sink(sink);
    core->set_filter(logging::trivial::severity >= logging::trivial::error);
}

int main(int, char* [])
{
    init_logging();
    boost::log::sources::severity_logger< logging::trivial::severity_level > lg;
    BOOST_LOG_SEV(lg, logging::trivial::trace) << "Trace message";
    BOOST_LOG_SEV(lg, logging::trivial::error) << "Error message";
    return 0;
}

If this is a clumsy approach and there's a more elegant solution to feed
log messages into SomeLogChannel() (in reality, it's a bit more complex
because it involves a class, a couple interfaces, etc.), don't hesitate
to comment as well. I'm still trying to wrap my mind around the topic.

Thanks a bunch in advance and greets,
Volker

-- 
@:  boost_at_[hidden]

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk