6

デバッグ目的でロガーが必要で、Boost.Log (boost.org ホームページにパッチが適用された 1.54.0) を使用しています。

次のようなマクロを作成しました。

#define LOG_MESSAGE( lvl ) BOOST_LOG_TRIVIAL( lvl )

デバッグ モードでのみ LOG_MESSAGE( lvl ) が BOOST_LOG_TRIVIAL( lvl ) で拡張され、リリースでは無視されるようになりましたか?

例えば:

LOG_MESSAGE( critical ) << "If I read this message we're in debug mode"

編集 私の最初の試みはヌルストリームを作成することです...リリースモードではコンパイラがそれを最適化すると思います...

#if !defined( NDEBUG )
#include <boost/log/trivial.hpp>
#define LOG_MESSAGE( lvl ) BOOST_LOG_TRIVIAL( lvl )
#else
#if defined( __GNUC__ )
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-value"
#endif


#include <iosfwd>
struct nullstream : public std::ostream {
    nullstream() : std::ios(0), std::ostream(0) {}
};

static nullstream g_nullstream;

#define LOG_MESSAGE( lvl ) g_nullstream

#if defined( __GNUC__ )
#pragma GCC diagnostic pop
#endif

#endif
4

4 に答える 4

7

ログ エントリの重大度レベルは、シンクのフィルターとしてのみ機能します。シンクは、重大度レベルに基づいて、メッセージをどう処理するか (印刷するかどうか) を決定します。ただし、メッセージは引き続き送信されます。

メッセージをまったく送信しない場合は、LOG_MESSAGE実際には何もしないものに再定義する必要があります。これについては Boost ライブラリに何かがあるかもしれません。それ以外の場合は、自分で作成する必要があります。おそらくこれが始まりになるでしょう:

class NullLogger
{
public:
  template <typename SeverityT> NullLogger (SeverityT) {};
  template <typename Val> NullLog& operator<< (const Val&) { return * this};
};

...その後:

#define LOG_MESSAGE (lvl) NullLogger (lvl)

ただし、ログ メッセージまたはそれを構成する式に対して何も行われていない場合でも、式は引き続き評価されることに注意してください。これらの式の一部が高価である場合でも、パフォーマンス ヒットが発生します。例えば:

LOG_MESSAGE (debug) << SomeSuperExpensiveFunction();

NullLogger上記を使用している場合でも、SomeSuperExpensiveFunction()引き続き呼び出されます。

別の方法として、実行時に評価されるフラグを追加し、実行時にログを記録するかどうかを決定することをお勧めします

if (mLogStuff)
{ 
  LOG_MESSAGE (debug) << SomeSuperExpensiveFunction();
}

bool平均比較は非常に安価であり、将来、ログのオンとオフを切り替える機能が非常に便利になる可能性があります。また、これを行うと、さらに別の を追加する必要がなくなります#define。これは常に良いことです。

于 2013-07-11T16:13:59.497 に答える
3

私はジョンのNullLoggerクラスが好きです。私が行う唯一の変更は次のとおりです

#define LOG_MESSAGE(lvl) while (0) NullLogger (lvl)

残念ながら、これにより警告が生成される可能性がありますが、適切なコンパイラが関連するすべてのログ コードを削除できることを願っています。

于 2013-08-03T07:23:48.143 に答える