Skip to content

Performance issue: Boost.Log does a huge work when filtering records #202

Description

@evgn

I worked with Boost.Log library and encountered a huge performance impact in case when all content passed to the logger supposed to be filtered.
I reduced the logger to the simplest one with a console backend and the result remained the same.

Here is the sample code:

#include <boost/log/sources/severity_feature.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/common.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/phoenix/bind.hpp>

enum severity_level
{
    critical,
    info,
    trace
};

BOOST_LOG_ATTRIBUTE_KEYWORD(severity_level_kw, "Severity", severity_level)

using backend_type = boost::log::sinks::synchronous_sink<boost::log::sinks::basic_text_ostream_backend<char>>;

bool filter_impl(severity_level lvl) { return lvl < trace; }
bool filter(const boost::log::value_ref<severity_level, tag::severity_level_kw> & lvl) {
    return filter_impl(*lvl);
}

void logging_function() {
    auto sink = boost::make_shared<backend_type>();
    sink->set_filter(boost::phoenix::bind(&filter, severity_level_kw.or_none()));
    sink->locked_backend()->add_stream(boost::shared_ptr<std::ostream>(&std::cout, boost::null_deleter{}));
    boost::log::core::get()->add_sink(std::move(sink));

    boost::log::sources::severity_logger<severity_level> slg;
    for(int i = 0; i < 100000000; ++i) {
        // I expect this line only applies the filter and does nothing else since trace-messages supposed to be filtered
        BOOST_LOG_SEV(slg, trace) << "Trace message: " << i;
    }
}

int main()
{
    logging_function();
    return 0;
}

This simple program works for ~14 seconds.
But if I change the loop like this:

for(int i = 0; i < 100000000; ++i) {
    if(filter_impl(trace))
        std::cout << "Debug message: " << i << "\n";
}

the program completes instantly as it supposed to. And it's what I expect the log library should do.

I profiled the program with dotTrace and here is the result

image

As you can see filter function takes only 95ms and the rest time goes to another stuff including memory allocations which I wouldn't expect to see.

This problem makes Boost.Log unusable in cases when performance is a priority.

As a hot-fix one can filter records manually by introducing a special macro, for example.

But is it worth expecting this issue will be fixed?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions