9

アプリケーションのロギング プラットフォームに Boost-Log とグローバル重大度ロガーを使用しています。プロファイリングboost::log::v2s_mt_posix::core::open_recordでは、合計実行時間の最大 25% がかかる可能性があることが示されています。

多くのログ メッセージがありますが、重大度が低く、フィルター処理されているため、それほどコストがかかるとは思いません。

これらのメッセージを実行時にそれほどコストをかけないようにする方法はありますか? (繰り返しますが、フィルターをかけた場合でもオーバーヘッドは小さく、フィルターをかけない場合はもちろんオーバーヘッドが大きくなると思います)。

いくつかのラッパー マクロを作成することにより、コンパイル時にこれを「修正」するのは比較的簡単です。

サンプル作業コードで更新:

#include <cmath>
#include <iostream>
#include <string>
#include <boost/lexical_cast.hpp>
#include <boost/log/sources/global_logger_storage.hpp>
#include <boost/log/sources/severity_logger.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/sources/severity_channel_logger.hpp>
#include <boost/log/common.hpp>
#include <boost/log/expressions.hpp>
#include <boost/log/sinks.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/console.hpp>
#include <boost/log/support/date_time.hpp>
#include <boost/utility/empty_deleter.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>

// severity levels
enum severity_level {INFO};

// Logging macro
#define LOG(level) BOOST_LOG_SEV(global_logger::get(), level)

// Initializing global boost::log logger
typedef boost::log::sources::severity_channel_logger_mt<
    severity_level, std::string> global_logger_type;

BOOST_LOG_INLINE_GLOBAL_LOGGER_INIT(global_logger, global_logger_type)
{
    return global_logger_type(boost::log::keywords::channel = "global_logger");
}

// Initialize terminal logger
void init_logger(int verbosity)
{
    namespace bl = boost::log;
    typedef bl::sinks::synchronous_sink<bl::sinks::text_ostream_backend>
      text_sink;

    boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
    sink->locked_backend()->add_stream(
        boost::shared_ptr<std::ostream>(&std::cout, boost::empty_deleter()));

    sink->locked_backend()->auto_flush(true);

    sink->set_formatter(bl::expressions::stream << bl::expressions::message);

    sink->set_filter(bl::expressions::attr<severity_level>("Severity")
                     < (severity_level) verbosity);

    bl::core::get()->add_sink(sink);
    bl::add_common_attributes();
}

int main(int argc, char* argv[])
{
    init_logger(boost::lexical_cast<int>(argv[1]));
    for(int i = 0; i < 200; ++i)
    {
        std::sin(std::sin(17.2)); // dummy processing
        LOG(INFO) << "A message!";
    }
    return 0;
}

引数を指定して実行すると0、ログ メッセージは出力されませんが、ログ メッセージをコメント アウトするよりも 2 倍 (!) 時間がかかります。

4

2 に答える 2

0

1 つの回避策 (これはマーマイトのソリューションです) は、マクロを使用してログをラップすることです。次に例を示します。

#define LOG_INFO(x) \
  if (<test if log level is INFO>) { \
    LOG(INFO) << x;  \
  }

それで:

LOG_INFO("Foo" << "Bar" << someExpensiveFunction());

someExpensiveFunction()、 をサポートするレベルでのみ実行されますINFO

一体、完全にコンパイルすることさえできます。

#ifndef _NINFO_
#define LOG_INFO(x) \
  if (<test if log level is INFO>) { \
    LOG(INFO) << x;  \
  }
#else
#define LOG_INFO(x)
#endif

これのもう 1 つの利点は、あらゆる場所ですべてのコードを変更するのではなく、マクロを変更することでロギングの実装を変更できることです。

于 2015-08-03T11:03:10.863 に答える
0

多くの場合、ログを記録するときに、ログに記録されているものを評価する必要があり、その評価は、ログに記録するかどうかを実際に決定する前に行われます。例えば:

log.debug("The current state of the system is: " + system.expensiveFunctionToGatherState());

現在の時刻をログに追加する自家製のログ システムがありました。これは の呼び出しでしたgettimeofday()。プログラムの CPU 消費量の 20% は、gettimeofday()どこにも行かないログ関数の呼び出しであることが判明しました。

于 2014-10-02T02:02:28.500 に答える