Šimon Tóth
Šimon Tóth

Reputation: 36433

Boost log - formatting with severity_channel_logger

I have seen several examples with formatters, but those used custom defined attributes.

How do I specify format for the severity_channel_logger? What I get now is:

[2015-07-20 11:53:09.879305] [0x00007f047b525740] [trace]   Bla, bla bla, bla bla bla.
[2015-07-20 11:53:09.879370] [0x00007f047b525740] [trace]   Bla, bla bla, bla bla bla.
[2015-07-20 11:53:09.879376] [0x00007f047b525740] [fatal]   Bla, bla bla, bla bla bla.

logger.h

#ifndef LOGGER_H_
#define LOGGER_H_

#include <boost/log/trivial.hpp>
#include <boost/log/core.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/sources/channel_feature.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>

#include <string>

namespace Logging {

typedef boost::log::sources::severity_channel_logger<boost::log::trivial::severity_level,std::string> LoggerType;

BOOST_LOG_GLOBAL_LOGGER(clogger,LoggerType)

} // namespace Logging

#endif

logger.cpp

#include "logger.h"
#include <memory>

#include <boost/log/core/core.hpp>
#include <boost/log/expressions/formatters/date_time.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks/sync_frontend.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/core/null_deleter.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>

using namespace Logging;

BOOST_LOG_GLOBAL_LOGGER_INIT(clogger, LoggerType)
{
    boost::log::sources::severity_channel_logger< boost::log::trivial::severity_level, std::string > lg;
    return lg;
}

main.cpp

#include "logger.h"
#include <boost/log/attributes/named_scope.hpp>
using namespace Logging;

int main()
{
    BOOST_LOG_FUNCTION();
    BOOST_LOG(clogger::get()) << "Bla, bla bla, bla bla bla.";
    BOOST_LOG_CHANNEL(clogger::get(),"standard") << "Bla, bla bla, bla bla bla.";
    BOOST_LOG_CHANNEL_SEV(clogger::get(),"standard",boost::log::trivial::fatal) << "Bla, bla bla, bla bla bla.";
}

Upvotes: 2

Views: 2649

Answers (2)

Andrey Semashev
Andrey Semashev

Reputation: 10606

You need to set a formatter to your sink. The formatter can be defined in multiple ways but the bottom line is that it extracts attribute values from log records and put them into a string. It doesn't matter whether the attributes are defined by user or library - you just need the attribute name and the type of its values.

The severity_channel_logger is a composite logger that inserts both severity level and a channel in log records made through that logger. As such, you'll know from the docs that the attribute names are "Severity" and "Channel", respectively, and the attribute value types are the types you specify as the logger template parameters - boost::log::trivial::severity_level and std::string in your case.

Now you are able to set the formatter you want to your sink. For example:

namespace expr = boost::log::expressions;

sink->set_formatter(
    expr::stream
        << expr::attr< boost::log::trivial::severity_level >("Severity")
        << " [" << expr::attr< std::string >("Channel") << "]: "
        << expr::smessage;
);

Upvotes: 3

cwfighter
cwfighter

Reputation: 502

Actually, there are many introductions in boost.org. Now I will give me my code:

#include <fstream>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <boost/smart_ptr/make_shared_object.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/text_ostream_backend.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/sources/record_ostream.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>

namespace logging = boost::log;
namespace src = boost::log::sources;
namespace expr = boost::log::expressions;
namespace sinks = boost::log::sinks;
namespace keywords = boost::log::keywords;

void init()
{
    typedef sinks::synchronous_sink< sinks::text_ostream_backend > text_sink;
    boost::shared_ptr< text_sink > sink = boost::make_shared< text_sink >();

    sink->locked_backend()->add_stream(
        boost::make_shared< std::ofstream >("sample.log"));

    sink->set_formatter
    (
        expr::stream
           // line id will be written in hex, 8-digits, zero-filled
        << expr::format_date_time< boost::posix_time::ptime >("TimeStamp", "%Y-%m-%d, %H:%M:%S")
        << std::hex << std::setw(8) << std::setfill('0') << expr::attr< unsigned int >("LineID")
        << ": <" << logging::trivial::severity
        << "> " << expr::smessage
);

logging::core::get()->add_sink(sink);
}

int main()
{
init();
logging::add_common_attributes();

using namespace logging::trivial;
src::severity_logger< severity_level > lg;

BOOST_LOG_SEV(lg, trace) << "A trace severity message";
BOOST_LOG_SEV(lg, debug) << "A debug severity message";
BOOST_LOG_SEV(lg, info) << "An informational severity message";
BOOST_LOG_SEV(lg, warning) << "A warning severity message";
BOOST_LOG_SEV(lg, error) << "An error severity message";
BOOST_LOG_SEV(lg, fatal) << "A fatal severity message";

return 0;

}

According to my codes, you will get a format output in sample.log.It will display with timestamp and log level. For more details, you should go to the site[http://www.boost.org/doc/libs/1_58_0/libs/log/example/doc/tutorial_fmt_format.cpp]. I hope this can help you. By the way, the output is:

2015-07-20, 23:19:0200000001: <trace> A trace severity message
2015-07-20, 23:19:0200000002: <debug> A debug severity message
2015-07-20, 23:19:0200000003: <info> An informational severity message
2015-07-20, 23:19:0200000004: <warning> A warning severity message
2015-07-20, 23:19:0200000005: <error> An error severity message
2015-07-20, 23:19:0200000006: <fatal> A fatal severity message

Upvotes: 0

Related Questions