Search code examples
c++boostboost-logboost-logging

boost log severity empty in the log message


i am setting the formatter for log records, the severity field is printing empty in the final log message. The code compiles fine but not working as expected. please advise. The documentation on the boost log is very cryptic and unclear.

auto logFmt = (                                                         
                boost::log::expressions::stream                                 
                <<boost::log::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d:%H:%M:%S")
                <<"|"<< boost::log::expressions::attr<boost::log::trivial::severity_level>("Severity")
                <<"|pid:"<<boost::log::expressions::attr<boost::log::process_id>("ProcessID")
                <<"|tid:"<<boost::log::expressions::attr<boost::log::thread_id>("ThreadID")
                <<"| "<<boost::log::expressions::smessage);           

I am pasting the stand alone code snippet which is separated from the larger piece.

#ifndef BOOST_LOG_USE_NATIVE_SYSLOG
#define BOOST_LOG_USE_NATIVE_SYSLOG
#endif

#include <string>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <syslog.h>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/phoenix.hpp>
#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/basic_sink_backend.hpp>
#include <boost/log/sinks/syslog_backend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/attributes/value_visitation.hpp>
#include <boost/log/utility/manipulators/add_value.hpp>
#include <boost/log/sinks/text_file_backend.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/attributes/timer.hpp>
#include <boost/log/attributes/named_scope.hpp>
#include <boost/log/support/date_time.hpp>

#define __LOCATION_TAG__ <<__FILE__<<"|"<<__LINE__<<"|"<<__FUNCTION__<<"()|"<<" "

#define _fatal   BOOST_LOG_SEV(Logger::getLogger(), boost::log::v2_mt_posix::trivial::fatal)__LOCATION_TAG__
#define _error   BOOST_LOG_SEV(Logger::getLogger(), boost::log::v2_mt_posix::trivial::error)__LOCATION_TAG__
#define _warning BOOST_LOG_SEV(Logger::getLogger(), boost::log::v2_mt_posix::trivial::warning)__LOCATION_TAG__
#define _info    BOOST_LOG_SEV(Logger::getLogger(), boost::log::v2_mt_posix::trivial::info)__LOCATION_TAG__
#define _debug   BOOST_LOG_SEV(Logger::getLogger(), boost::log::v2_mt_posix::trivial::debug)__LOCATION_TAG__
#define _trace   BOOST_LOG_SEV(Logger::getLogger(), boost::log::v2_mt_posix::trivial::trace)__LOCATION_TAG__


class Logger
{
    class custom_backend :
        public boost::log::sinks::basic_sink_backend<
        boost::log::sinks::combine_requirements<
        boost::log::sinks::formatted_records,
        boost::log::sinks::concurrent_feeding,
        boost::log::sinks::flushing
        >::type
        >
    {
        public:
            typedef char                               char_type; // Character type.
            typedef std::basic_string< char_type >   string_type; // Formatted string type.
            explicit custom_backend()
            {
                return;
            }

            void consume(boost::log::record_view const& rec,
                    string_type const& formatted_message)
            {
                std::cerr<<formatted_message<<std::endl;
                return;
            }

            void flush()
            {
                return;
            }
    };

    public:
    typedef boost::log::sinks::synchronous_sink< custom_backend > sink_t;
    void initialize(std::string tag)
    {
        auto logFmt = (
                boost::log::expressions::stream
                <<boost::log::expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d:%H:%M:%S")
                <<"|"<< boost::log::expressions::attr<boost::log::trivial::severity_level>("Severity")
                <<"|pid:"<<boost::log::expressions::attr<boost::log::process_id>("ProcessID")
                <<"|tid:"<<boost::log::expressions::attr<boost::log::thread_id>("ThreadID")
                <<"| "<<boost::log::expressions::smessage);

        cbackend.reset(new custom_backend());
        custom_sink.reset(new sink_t(cbackend));
        custom_sink->set_formatter(logFmt);
        boost::log::core::get()->add_sink(custom_sink);
        return;
    }

    static Logger& getInstance()
    {
        static Logger logger;
        return logger;
    }

    void finalize()
    {
        return;
    }

    static boost::log::sources::logger_mt & getLogger()
    {
        return _lg;
    }

    private:
    static boost::log::sources::logger_mt _lg;
    boost::shared_ptr< custom_backend > cbackend;
    boost::shared_ptr< sink_t > custom_sink;
};

boost::log::sources::logger_mt Logger::_lg;

int main(int ac, char **av)
{
    auto lg = Logger::getInstance();
    lg.initialize("hello");
    _info<<"hello world."<<std::endl;
    _error<<"hello world."<<std::endl;
    return 0;
}

Solution

  • The problem is that you didn't add the severity level attribute. This attribute is normally provided by the logger, but you're using the logger_mt logger, which doesn't add any attributes and ignores the argument you provide to the BOOST_LOG_SEV macro. You should use severity_logger_mt or some other logger that provides support for severity levels. This logger will add the severity level attribute to every log record made through it and will set the level to the value you specify in the BOOST_LOG_SEV macro call.