ロギングライブラリの比較





このネットワークには、Q&A形式の膨大な数のサイトがあり、カテゴリから質問が寄せられます。





人々は自分の経験と知識を共有しますが、そのようなサイトの形式は、応答者の個人的な好みのみを表示できます。 たとえば、パンテイオスは最も生産性の高いロガーの1つと呼ばれることが最も多く、メーカーのテストによれば、100万を超えるログ行を書き込むのに100秒以上かかりますが、最新のハードウェアでは約30秒ですか?



この記事では、近年の最も有名で価値のあるロガーと、比較的若い数人のロガーを25を超える基準で比較します。



やる気



私が知っているほぼすべてのプロジェクトで、遅かれ早かれロギングが登場し、エンジニアは「この問題を解決する方法」を自問しました。誰かがQ&Aサイトを調べ、「Logger Xが近づいてきました。通常のフライトのようです」(1)彼は自分のロガーを書き(2)、誰かが患者であり、彼らの興味の対象についてロガーの群れ全体を研究し、1週間後に別の選択をしました(3)。



この記事は3つのグループすべてを対象としています。



  1. 最初のグループについては、この記事では「ロガーXが最適です」という推奨事項よりもロガーの広範な比較を示します。
  2. 2番目のグループの場合、この記事では現在の技術レベルについて説明し、おそらく「既製の方が使いやすい」または「すごい作業がたくさんありますが、もっとうまくいくことができます」という方向にスケールを変えるでしょう。
  3. 3番目の最も退屈なグループについては、この記事が3週間の研究の少なくとも1つを節約することを願っています。業界全体で、これは驚くべき工数になります。


NBこの記事は非常に膨大ですので、読むことにした場合は、しばらくお待ちください!



ロガーとその主なパラメーター



比較するロガーの選択は面倒で簡単ではありません。いずれにしても「なぜロガーXが考慮されなかったのか?」という疑問が生じます。私が言えることは、ロジックは単純だったということです。



しかし、これらの8人の候補者を比較することでさえ、ドックの喫煙、問題、フォーラムの閲覧、テストの作成、結果の収集に3週間以上かかりました。



何らかの方法で、非常に重要なロガーを見逃した場合-記事を更新できます。 レビューには以下が含まれます。



  1. パンテイオス
  2. グログ
  3. log4cpp
  4. P7
  5. G3log
  6. Spdlog
  7. イージーロギング
  8. Boost.Log(巨大なBoostライブラリの一部)


選択されたロガーの一般的な特性

人。 言語 リフレッシュ プラット。 比較
パンテイオス BSD C ++ 2010 Windows * nix、OS-X VC ++、GCC、Intel、Borland、Comeau、Digital Mars、Metrowerks
グログ 3節のBSD C ++ 2018年 Windows * nix、QNX VC ++、GCC、clang、intel
log4cpp LGPL C ++ 2017年 Windows * nix、Solaris VC ++、GCC、Sun CC、OpenVMS
P7 LGPL C ++、C、C#、Python 2018年 Windows * nix VC ++、GCC、clang、MinGW
G3log パブリックドメイン C ++ 11 2018年 Windows * nix VC ++、GCC、clang
Spdlog MIT C ++ 11 2018年 Windows、Linux、Solaris、OS-X、Android VC ++、GCC、Clang
イージーロギング MIT C ++ 11 2018年 Windows、Linux、Solaris、OS-X、Android VC ++、GCC、Clang、Intel
Boost.log ブースト( 1 C ++ 2016年 Windows、Linux( 2 VC ++、GCC、Clang( 3


  1. 独自のライセンスwww.boost.org/LICENSE_1_0.txt
  2. www.boost.org/doc/libs/1_62_0/libs/log/doc/html/log/installation.html
  3. Boostをコンパイルできるプラットフォームおよびコンパイラは他にも多数ありますが、それらは公式にはサポートされておらず、おそらく追加の作業が必要になります。


ドキュメントと依存関係



複雑なプロジェクトのドキュメントの重要性に異議を唱えることは難しく、現代のロガーは単純なプロジェクトと呼ばれることがあり、優れたドキュメントの可用性は、実装とエラーの修正を大幅にスピードアップします。

ドキュメント 依存関係
パンテイオス フル(API +使用) STLSoft
グログ 初歩的、ほとんど欠席 Google gflags、弱い依存関係( 1
log4cpp 生成(Doxygen)(APIのみ) ブースト、弱い中毒( 1
P7 フル(API +使用) いや
G3log 基本(一般的な使用方法) いや
Spdlog 基本(一般的な使用方法) いいえ、ヘッダーファイルのみ( 2
イージーロギング 基本(一般的な使用方法) いいえ、ヘッダーファイルのみ( 2
Boost.log 基本(一般的な使用方法)に加えて、いくつかのクラスとそのメソッドの基本的な説明 ブースト


  1. 弱い依存関係-コードの一部はサードパーティのソリューションに依存しますが、コンパイルを妨げませんが、機能を部分的に制限します。



  2. ヘッダーファイルのみ-ライブラリは、プログラムの各ソースファイルに含める必要がある1つまたは複数のヘッダーファイルの形式で配布されます; Easyloggingの場合、コンパイル速度は大幅に低下します。 しかし、この状況から抜け出す方法があります-これらのプロジェクトをライブラリの形でコンパイルし、既に接続することですが、これにはプロジェクトの作成にさらに時間がかかります。


ロガータイプ、メモリ消費制御、スレッドセーフ



現在、ロギングへの2つのアプローチが広まっています。





確かに、ロギングライブラリのさまざまなメーカーによって非同期性を理解する微妙な違いがあります。



  1. タイプ番号1:Log(..)関数の呼び出しはアトミックである必要があると考える人もいるため、ファイル内のログメッセージの順序は00:00-> 00:01-> 00:02のように連続します。



  2. タイプNo. 2:他の人は、最大のパフォーマンスを達成するために、Log(..)関数呼び出しの原子性を犠牲にして、ファイル内のログメッセージがインターリーブされるという事実に耐えることができると考えています。たとえば、00:00-> 00:05-> 00 :01。


個人的には、非同期ログに関する最初のグループの観点に固執します。混合ログの分析は、特に大きなログファイルであり、単一のログが混合されていないが、数百または数千の要素のロググループである場合、快適とは言えません。



ロガーを非同期にするには、データをバッファに保存し、別のストリームから書き込む必要があるため、非同期ロギングのもう1つの重要な側面はメモリ割り当ての制御です。 そして、ここには重要な些細な問題があります-どのサイズのバッファーが最適であり、ユーザーはこのパラメーターに影響を与えることができますか? テストされたロガーの一部はニーズに合わせて数百メガバイトを割り当てたため、この質問はまったく無駄では​​ありません。

種類 メモリ制御 スレッドセーフ
パンテイオス 同期 いや はい
グログ 同期 いや はい
log4cpp 同期 いや はい
P7 非同期、(タイプ1)( 2 正確(1Kbステップ) はい
G3log 非同期、(タイプ2)( 3 いいえ( 5 はい
Spdlog 非同期、(タイプ2)( 3 部分的( 6 はい
イージーロギング 同期( 1 いや いいえ( 4
Boost.log 同期、非同期、(タイプ2)( 7 デフォルトなし( 8 はい


  1. 非同期モードは実験状態です
  2. シャッフルされないタイムスタンプとメッセージ
  3. タイムスタンプとメッセージがシャッフルされる場合があります
  4. デフォルトでは使用できません。マクロELPP_THREAD_SAFEを有効にする必要があります
  5. 制御されていないメモリ割り当て、高負荷下では数百メガバイトを割り当てることができる、著者のコメント: kjellkod.wordpress.com/2014/08/16/presenting-g3log-the-next-version-of-the-next-generation-of-the-next-generation-of-loggers

    g2logまたはg3logの場合、std ::キューが使用されます。内部的にはstd :: dequeです。 制限はありませんが、std :: vectorよりもはるかにメモリ耐性があります。 内部的に、キューはshared_queue.hpp内でラップされます。



  6. キューの長さは要素で設定できます。初期形式の要素のサイズは88バイト+テキストメッセージ(30〜160バイト)です。 最適なパフォーマンスを得るには、キューサイズを100万メッセージに設定することをお勧めします。これは、ロギングライブラリのみで120メガバイトから250メガバイトのメモリコストに変換されます。
  7. メッセージのシーケンスはデフォルトのライブラリでは保証されていません。異なるストリームからログを記録する場合、結果のファイルにタイムスタンプを混在させることができます: 「マルチスレッドアプリケーションでログレコードの順序が弱いのはなぜですか?」ライブラリの作成者は、「unbounded_ordering_queue」 。 ソートが実行される属性「RecordID」
  8. デフォルトでは、ライブラリは「unbounded_fifo_queue」を使用します。これにより、集中的なロギングでメモリ消費が制御不能に増加します。 追加の構成には「bounded_fifo_queue」を使用できます。 この場合、要素でキューの長さを指定できます。 各項目(図書館用語の記録)は約1KBかかります


プロセス障害処理



プロセス障害の正しい処理(クラッシュ処理)は、非同期ロガーにとって主に重要です。 一部のデータはバッファに保存され、それらが時間通りに保存されない場合、おそらく最も重要なデータが障害の直前に失われます。



転倒を傍受する方法は3つあります。





パンテイオス いや
グログ 自動、Linuxのみ( 1
log4cpp いや
P7 手動および自動( 2
G3log 自動、Linuxのみ( 3
Spdlog いいえ( 4
イージーロギング 自動、Linuxのみ( 5
Boost.log いいえ( 6


  1. 以下のシグナルがインターセプトされます:SIGSEGV、SIGILL、SIGFPE、SIGABRT、SIGBUS、SIGTERM。
  2. SIGSEGV、SIGILL、SIGFPE、SIGINT、SIGABRT、SIGBUS、SIGTERM、SIGBUS、PureVirtualCall、VectoredException、Newhandler、InvalidParameterHandler、status_access_、exception_array_bounds_exceeded、exception_datatype_misalignment、exception_flt_divide_by_zero、exception_flt_stack_check、EXCEPTION_ILLEGAL_INSTRUCTION、EXCEPTION_INT_DIVIDE_BY_ZERO、exception_noncontinuable_exception、exception_priv_instruction、EXCEPTION_STACK_OVERFLOW次の信号を傍受
  3. 次のシグナルがインターセプトされます:SIGSEGV、SIGILL、SIGFPE、SIGABRT、SIGBUS、SIGTERM、ゼロによるDiv、不正なprintf、範囲外、アクセス違反、std :: future_error
  4. github.com/gabime/spdlog/issues/55-欠陥は2015年に「クローズ」されました。 この方向での作業は予測されていません。
  5. 以下のシグナルがインターセプトされます:SIGABRT、SIGFPE、SIGILL、SIGSEGV、SIGINT
  6. 同期モードの場合でも、プロセスに障害が発生するとデータ損失のリスクがあります;非同期モードを使用する場合、データ損失のリスクは非常に高くなります


ロギングスタイルと出力(シンク)



ほとんどのライブラリは、確立された2つのロギングスタイルをサポートしています。





スタイル 出力(シンク)
パンテイオス テンプレート+オーバーロード関数

F(A)、F(A、A)、F(A、A、A)、... F(A、<-64->、A)

Printf

ファイル、syslog、コンソール、音声、ACE、COMerror、WinEventLog

グログ ログ()<<メッセージ ファイル、syslog、コンソール
log4cpp Printf、Log()<<メッセージ ファイル、syslog、コンソール、NTログ、IDS / A、OsStream、StringQueue、Win32Debug
P7( 6 Printf バイナリファイル、コンソール、syslog、テキストファイル(Linux:UTF8、Windows:UTF-16)ネットワーク(独自のプロトコルとサーバー( 2 ))、null
G3log Printf、Log()<<メッセージ ファイル( 3
Spdlog Printf( 4 ファイル、syslog、コンソール
イージーロギング Printf( 1 )、Log()<<メッセージ ファイル、syslog、コンソール
Boost.log ログ()<<メッセージ( 5 ファイル、syslog、コンソール、Win32Debug、WinEventLog、IPC


  1. 使用された場合、Printfは例外をスローしましたが、これはおそらく一時的な問題です。
  2. そのサーバーは、最大のパフォーマンスを実現するために使用されます。 このサーバーは無料ですが、残念ながらWindowsのみをサポートしており、明らかにQtに基づいており、作成者にLinuxサポートのリクエストが送信されました。 テスト構成でネットワークを介してログを送信する速度は、CPUのロード時に毎秒約350万でした-13%。 パフォーマンステストについては、次の章で詳しく説明します。
  3. 公式ディストリビューションには、ファイルローテーションとコンソールをサポートするSinkは含まれていませんが、これらの拡張機能はgithub.com/KjellKod/g3sinksからダウンロードできます
  4. Printfライブラリ関数の文字列形式は標準形式と互換性がないため、あるロガーを別のロガーに簡単に置き換えることは困難です
  5. nullptr文字列をロガーへの引数として渡すと、セグメンテーション違反/アクセス違反が発生します
  6. 最も生産的なシンク:バイナリファイル、Baical


ロガーの初期化



パラメータの初期化または受け渡しは重要なポイントです。 ロガーに柔軟性を追加し、たとえばロギングレベルを変更する場合に再コンパイルの必要性を排除します。

パンテイオス 手動(コードのみ)
グログ コマンドライン、マニュアル、環境変数
log4cpp 構成ファイル( 1 )、マニュアル
P7 コマンドライン( 2 )、マニュアル
G3log 手動(コードのみ)
Spdlog 手動(コードのみ)
イージーロギング 設定ファイル、コマンドライン、マニュアル
Boost.log 構成ファイル( 3 )、手動


  1. ロガーパラメーターの詳細かつ適切に設定された設定は、おそらく最も詳細です。
  2. 他のすべてのロガーでは、コマンドラインパラメーターを処理するために、int main(int argc、char * argv [])関数から手でロガーに渡す必要があります。 このロガーでは、これらのパラメーターはプログラム/モジュール(dllなど)の任意の部分から自動的にインターセプトできます。
  3. ライブラリは、構成ファイルを介した構成のための最も基本的なプリミティブのみを提供します 。 この問題のより完全な議論はここで見つけることができます。 そして結論として
    有効なエントリは、シンク、フィルタなどを実装するソースコードから派生しているため、構成ファイル形式のエントリの説明を見つけるのは難しいように思えます。 この実装はユーザー定義であってもよいため、明示的な構成フォーマットの説明を提供することは不可能です


フィルタリング設定



最も一般的なフィルタリング手法は、ログレベルによるものです。たとえば、フィルターがERRORレベルに設定されている場合、ERRORより小さいすべて(TRACE、DEBUG、INFO、WARNING ...)はログに記録されません。 この方法は、現時点では必要のない大量の情報をふるいにかけ、CPUとディスク容量を節約するのに非常に便利です。

パンテイオス いいえ( 1
グログ コマンドライン、マニュアル、環境変数
log4cpp 構成ファイル( 4 )、手動
P7 ネットワーク経由でリアルタイムでリモートでコマンドライン( 2 )( 3 )、手動
G3log いいえ( 5
Spdlog マニュアル
イージーロギング マニュアル( 6
Boost.log 手動構成ファイル


  1. フィルタリングを整理するには、フロントエンドを開発する必要があります
  2. データがネットワーク経由で送信される場合にのみサポートされます;ローカルファイルに書き込む場合、サーバーは詳細レベルにアクセスできません。
  3. グローバルレベルに加えて、各モジュールのレベルを設定できます。
  4. 各ロガーの階層的なロギングとレベルの個別設定
  5. デフォルトでは無効になっており、マクロG3_DYNAMIC_LOGGINGによって有効になっています。その後、すべてのロガーのレベルを手動で設定できます。 パフォーマンスが大幅に低下します。
  6. 製造元によってサポートが発表されましたが、機能させることはできませんでした。使用中に機能が開発中または放棄されたようです。


Unicodeサポート



テストのこの部分は最も悲しいものの1つでした。2016年、このような有名なライブラリでのUnicodeサポートは「 公式ではない 」レベルのままです。



ライブラリは重要なアプリケーションデータ(ユーザー名、ファイルパス、ドメイン名)を保存するために必要であり、既存のもののほとんどは、データが些細な文字に収まらない場合、これを許可しません。

パンテイオス UTF-16( 1 )( 4 )、UTF-8
グログ いや
log4cpp いや
P7 Windows-UTF-16、* nix-UTF-8、UTF-32
G3log いや
Spdlog いや
イージーロギング Windows Utf-16( 2 )、Utf-8( 3
Boost.log 部分的にUTF-8( 5


  1. 結果のログファイルにUnicodeトークンがなく、ビューアでのエンコーディングを自分で選択する必要があることを除いて、ほぼ完璧です。
  2. サポートは要求されていますが、実装されていません。Unicode文字はログファイルに含まれていません。
  3. START_EASYLOGGINGPPマクロはUnicodeをサポートしていません
  4. UTF-16など、ANSI文字列を1つのメッセージに結合することはできません
  5. Unicodeサポートは、Boost.Localeライブラリを使用して実行され、UTF-8 / 16/32およびその他の国のロケールのさまざまな形式に対する印象的な幅広いサポートが提供されますが、残念ながら、UTF-8ファイル形式でのみ初期化関数を使用してBoost.Logを動作させることができました同期ロガー「logging :: add_file_log」、他のすべての試行は失敗し、Unicode文字はファイルに到達しませんでした。おそらく、この機能を動作させるのに十分な時間です


ロガーへのアクセス



現代の図書館では、「誰がロガーを所有しているのか」という疑問が舞台裏に残っており、ほとんどの場合、LOG(ERROR)<< "My message"と書くことができ、図書館がすべてを処理します。 この単純さは、グローバル変数を使用して実現されます。 グローバル変数を使用するという倫理を舞台裏で残しますが、これは特別な場合ですが、単純なアプリケーションの場合にグローバル変数を使用する単純さは、多くの動的または静的モジュールで構成される複雑なアプリケーションの開発者に背を向けます。



ロガーにアクセスする別のオプションは、自分でオブジェクトを作成し、そのライフサイクルを制御することです。



最後のオプションはハイブリッドで、ロガーオブジェクトは手動モードで作成され、動的モジュールを含むプロセス全体に共通するグローバル変数(レジストリ)または共有メモリが使用されます。

パンテイオス グローバル変数、自動初期化
グログ グローバル変数、自動初期化
log4cpp グローバル変数、自動および手動の初期化
P7 共有メモリ、手動初期化
G3log グローバル変数、自動および手動の初期化
Spdlog グローバル変数、手動初期化
イージーロギング グローバル変数、自動初期化
Boost.log グローバル変数、自動および手動の初期化


ファイルの回転



パンテイオス いや
グログ 大きさ
log4cpp サイズ( 2
P7 時間、サイズ( 1 )( 2
G3log サイズ、デフォルトでは使用不可( 1
Spdlog サイズ、時間(日)( 1
イージーロギング 大きさ
Boost.log 時間、サイズ( 1 )( 2


  1. 名前の各ファイルには日付と時刻が含まれています。
  2. オプション「最大。 ファイル数」は、最後のファイルのうちN個だけを保存することを許可します


時間精度



この記事で説明するロガーの多くは、高い生産性を念頭に置いて設計されており、毎秒数百万メッセージの可能性があります。 しかし、高速に加えて、正確で高解像度のタイムスタンプが必要です。 ログファイルに同じタイムスタンプを持つ数十または数百のメッセージがある場合、これは実行時間に関する情報の一部がすでに失われていることを意味します。

パンテイオス Windows:10ミリ秒( 1 )、カスタムバックエンドは精度の向上に役立ちます

Linux:理論。 最小値1ns、ハードウェア依存

グログ Windows:10ms( 1

Linux:理論。 最小値1ns、ハードウェア依存

log4cpp Windows:10ms( 1

Linux:理論。 最小値1ns、ハードウェア依存

P7 Windows:100ns

Linux:理論。 最小値1ns、ハードウェア依存

G3log Windows:1ms

Linux:1us

Spdlog Windows:1ms

Linux:理論。 最小値1ns、ハードウェア依存

イージーロギング Windows:1ms

Linux:1us

Boost.log Windows:10ms( 1

Linux:理論。 最小値1ns、ハードウェア依存



  1. 1ミリ秒の粒度を取得できる場合もありますが、多くの場合、クォンタムは10ミリ秒です。


性能



この記事のリストにあるロガーの多くは、パフォーマンスが最優先事項の1つであると主張しています。



私はこの声明を真剣に受け止め、一連のテストを実施しました。





各テストでは、時間を測定し、100万のメッセージをファイルに保存するためにロガーがCPUを消費します。 3つの測定が実行され、平均指標が計算されます。



テストは、デバッグ(最適化が無効)およびリリース(O2最適化)アセンブリでも実施されました。 テストでは、次の構成が使用されました。





テストを実際の使用に近づけるために、各メッセージログに次の情報が保存されました。





各ロガーに対して実行されたコード(コンパイルにはC ++ 11サポートが必要です):



ソーステキスト
#include <stdio.h> #include <atomic> #include <thread> #include <vector> //Include specific logger headers #include "Logger headers ..." using namespace std; using namespace std::chrono; //Use this macro to switch on multi-threading mode //#define MULTI_THREAD int main(int argc, char* argv[]) { //Logger initialization //.. unsigned int thread_count = 4; unsigned int howmany = 1'000'000; vector<thread> threads; auto start = system_clock::now(); #if !defined(MULTI_THREAD) for(unsigned int i=0; i < howmany; i++) { //Has to be customized for every logger LOG(INFO) << " Message + all required information, #" << i; } #else howmany /= thread_count; for (int t = 0; t < thread_count; ++t) { threads.push_back(std::thread([&] { for(unsigned int i=0; i < howmany; i++) { //Has to be customized for every logger LOG(INFO) << " Message + all required information, #" << i; } })); } for(auto &t:threads) { t.join(); }; howmany *= thread_count; #endif auto delta = system_clock::now() - start; auto delta_d = duration_cast<duration<double>> (delta).count(); LOG(INFO) << "Time = " << (double)howmany / delta_d << " per second, total time = " << delta_d; //Logger uninitialization if necessary return 0; }
      
      







シングルスレッド



1つのストリームでファイルごとに100万のメッセージを保存する必要があります。フィルタリングは無効になり、ファイルのローテーションは無効になります。 ランタイムおよび平均CPU使用率が測定されます。

デバッグする

時間(ミリ秒)
デバッグする

CPU(%)
リリース

時間(ミリ秒)
リリース

CPU(%)
パンテイオス 140 300 13% 28,400 13%
グログ 52,500 13% 8 270 13%
log4cpp 130 570 13% 13 806 13%
P7( 1 )( 2 )( 6 520 14% 100 14%
G3log( 1 )( 3 102 990 38% 3 660 37%
Spdlog( 1 )( 4 64,250 13% 869 13%
Spdlog( 1 )( 5 65,660 13% 885 13%
イージーロギング 271,060 13% 9 100 13%
Boost.Log( 1 )( 7 2 310 200 17% 44,300 9%
Boost.Log( 1 )( 8 649,480 25% 12 680 25%


  1. 非同期ロギング
  2. オプション "/P7.Pool=1024"でコンパイル-使用可能なメモリの合計量は1メガバイトです。
  3. ほとんどの場合、ロガーはバッファーにデータを追加し、アプリケーションを終了すると記録が行われるため、測定は合成と見なすことができます。この作業には、ログ時間を1桁、ログを1秒、データを10秒保存する時間を超える時間がかかります。
  4. ロガーが約250メガバイトのメモリを消費している間に、製造元が推奨する条件 "spdlog :: set_async_mode(1048576)"でログを記録する
  5. 「spdlog :: set_async_mode(4096)」というメモリ消費量が等しい条件下でのロギング-この場合、ロガーには4k要素のバッファがあり、各要素は約250バイトを占有し、最終的には約1メガバイトのメモリ消費になります。
  6. 録音は、UTF-16形式のテキストのバイナリファイルで実行されました。
  7. メモリ消費が等しい条件(asynchronous_sink + text_file_backend + bounded_ordering_queue + block_on_overflow)でログインすると、キューの長さは1024要素であり、各要素は約1100バイトかかり、最終的には1 MBを少し超えるメモリ消費を与えます。
  8. 総合テスト。 最も快適な状態、デフォルトのロガー構成(asynchronous_sink + text_file_backend + unbounded_fifo_queue)でのロギング。 メモリ消費に制限はありません。到着順にメッセージをソートすることはありません。 メモリ消費は1.8GBに固定されました。


4スレッド



4つのスレッドでファイルごとに合計100万のメッセージを保存する必要があります。フィルタリングは無効になり、ファイルのローテーションは無効になります。



ランタイムおよび平均CPU使用率が測定されます。

デバッグする

時間(ミリ秒)
デバッグする

CPU(%)
リリース

時間(ミリ秒)
リリース

CPU(%)
パンテイオス 10 600 48% 9 500 48%
グログ 30,200 93% 5,900 93%
log4cpp 149,600 18% 16 900 19%
P7( 1 )( 2 )( 6 790 19% 230 19%
G3log( 1 )( 3 39,700 75% 2,300 75%
Spdlog( 1 )( 4 11 510 13% 270 25%
Spdlog( 1 )( 5 73,240 25% 4,653 25%
イージーロギング 328 230 19% 8 575 25%
Boost.Log( 1 )( 7 2 645 120 14% 48,290 14%
Boost.Log( 1 )( 8 655,470 65% 13 560 65%


  1. 非同期ロギング
  2. オプション "/P7.Pool=1024"でコンパイル-使用可能なメモリの合計量は1メガバイトです。
  3. ほとんどの場合、ロガーはバッファーにデータを追加し、アプリケーションを終了すると記録が行われるため、測定は合成と見なすことができます。この作業には、ログ時間を1桁、ログを1秒、データを10秒保存する時間を超える時間がかかります。
  4. ロガーが約250メガバイトのメモリを消費している間に、製造元が推奨する条件 "spdlog :: set_async_mode(1048576)"でログを記録する
  5. 「spdlog :: set_async_mode(4096)」というメモリ消費量が等しい条件下でのロギング-この場合、ロガーには4k要素のバッファがあり、各要素は約250バイトを占有し、最終的には約1メガバイトのメモリ消費になります。
  6. 録音は、UTF-16形式のテキストのバイナリファイルで実行されました。
  7. メモリ消費が等しい条件(asynchronous_sink + text_file_backend + bounded_ordering_queue + block_on_overflow)でログインすると、キューの長さは1024要素であり、各要素は約1100バイトかかり、最終的には1 MBを少し超えるメモリ消費を与えます。
  8. 総合テスト。 最も快適な状態、デフォルトのロガー構成(asynchronous_sink + text_file_backend + unbounded_fifo_queue)でのロギング。 メモリ消費に制限はありません。到着順にメッセージをソートすることはありません。 メモリ消費は1.8GBに固定されました。


フィルタリング



ロガーは100万のメッセージを処理し、それらをフィルタリングする必要があります。 最終ファイルに届くメッセージは1つではありません。



実行時間が測定されます。

デバッグする

1スレッド、時間(ms)
デバッグする

4スレッド、時間(ms)
リリース

1スレッド、時間(ms)
リリース

4スレッド、時間(ms)
パンテイオス( 1 - - - -
グログ 55 520 28,240 6 840 4,790
log4cpp 200 70 80 45
P7 84 102 23 42
G3log 5 530 1950 24 9
Spdlog 269 134 6 32
イージーロギング( 2 - - - -
Boost.log 26,407 8 554 699 389


  1. フィルタリングはデフォルトでは使用できません
  2. フィルタリングを機能させることができませんでした


パフォーマンスの概要



多くのロガーのパフォーマンスは非常に良いレベルでした。

残念ながら、P7を除くほとんどすべてのロガーには、デバッグビルドとリリースビルドの間に大きなパフォーマンスギャップがあり、比率が74に達することがあります(Spdlog:65660/885)。 これにより、ロギングの遅延が増加するため、プロジェクトのデバッグが複雑になる可能性があります。



アプリケーションにロギングライブラリを実装する開発者は、ニーズに合わせて250メガバイトのメモリを割り当てたり、CPUの75%以上を消費したりしないため、実行されるテストはある意味で合成と呼ばれます。



通常、インテグレーターはライブラリーを非表示にし、特に小さな組み込みシステムの場合は、最小限のハードウェア要件で作業を行いたいと考えています。



したがって、1%のCPUと1MBに相当するが十分な量のメモリを使用して書き込むことができるメッセージログの数を判断するために、各ロガーの最適なインジケータを再計算しました( メモリ消費量が等しいテスト



計算式:

((10000 ms /テスト時間(ms))* 1 000 000メッセージ)/テストでのCPU使用率


1%CPU使用時の1秒あたりのメッセージ
P7 714,285メッセージ(1,000,000 *(1000/100 ms)/ 14%)
Spdlog 86 918件の投稿(1,000,000 *(1000/885ミリ秒)/ 13%)
グログ 9 301メッセージ(1,000,000 *(1000/8270 ms)/ 13%)
イージーロギング 8,453メッセージ(1,000,000 *(1,000 / 9,100ミリ秒)/ 13%)
G3log 7 384メッセージ(1,000,000 *(1000/3660ミリ秒)/ 37%)
log4cpp 5 571メッセージ(1,000,000 *(1000/13806 ms)/ 13%)
パンテイオス 2,708メッセージ(1,000,000 *(1000 / 28,400ミリ秒)/ 13%)
Boost.log 2 508メッセージ(1,000,000 *(1000/44300 ms)/ 9%)




結論



パンテイオス



このライブラリはかなり複雑な印象を与えました。一方で著者はプロジェクトに徹底的かつ思慮深くアプローチしましたが、一方では機能、ドキュメントの良いレビュー、他方で生産性は低くなりますが(著者は反対の(1)を指摘していますが)、ファイルのローテーションやその他の些細なことの欠如は全体的な印象を大きく損ないます。



したがって、ライブラリの利点:



短所:



  1. 信じられないほど効率的で、他のすべての深刻なC ++診断ログライブラリよりも大幅に(最大2桁) 高速ですwww.pantheios.org/essentials.html


NB:ライブラリは、比較されるすべての中で最大かつ最も複雑なライブラリの1つであるため、その機能の多くが考慮されていない可能性が高いです。



グログ



ライブラリの機能はかなり貧弱で、パフォーマンスもありませんが、このライブラリは、「父」を大きく成長させた他の多くのプロジェクトに影響を与えました。 これだけがすでに著者のカルマで太っている。



ライブラリの利点:



短所:





log4cpp



別の名誉あるロガーは非常に良い印象を与えました。大きな失望はなく、知名度の高いプロモーションはありません。約束は果たされません。



ライブラリの利点:



短所:





P7



この記事で説明したものの中で最も珍しいロガーの1つであるこのパッケージには、ロガーだけでなく、ネットワーク経由でメッセージを受信し、ログファイルを表示し、フィルタリング、エクスポート、冗長レベルをリモートで制御するためのサーバー、および他の多くの機能が含まれます。 プロジェクトはネットワークと正確なメモリ管理に焦点を合わせていたため、SpdLogの場合と同様に、範囲はパフォーマンスと組み込みデバイスで使用する機能を対象としていました。

また、Sink = FileBinまたはSink = Baicalを使用する場合、プロジェクトはネットワーク経由で受信、表示、フィルタリングなどを行うための無料ソフトウェアを提供することにも注意してください。
ソフトウェア。
画像








ライブラリの利点:



短所:





G3log



G2Logの相続人は、Glogを再考した結果でした。 著者は、主に生産性を追求し、この主題に関する非常に活発な教育研究を行っています( 1 )( 2 )。 残念ながら、パフォーマンステストは総合的なものであることが判明し、結果は予想からはほど遠いものでした。



ライブラリの利点:



短所:





  1. kjellkod.wordpress.com/2014/08/16/presenting-g3log-the-next-version-of-the-next-generation-of-loggers
  2. kjellkod.wordpress.com/2015/06/30/the-worlds-fastest-logger-vs-g3log




Spdlog



パフォーマンスに目を向けて作成された別のロガーは、残念ながら、数百メガバイトのRAMを使用しないと良好なパフォーマンスが得られません。 機能は他の多くのロガーの標準であり、主な重点は速度です。



ライブラリの利点:



短所:





イージーロギング



ロガーは、唯一のヘッダーファイル(約6700行のコード)である「軽量」を目指しました。 他の多くのロガーの機能は標準です。



ライブラリの利点:



短所:





Boost.log



機能性、シンプルさ、生産性に目を向けたロガーは、このような優先順位と目標を著者が追求しています: モチベーション。

このプロジェクトはほぼ9年間開発されており、Boostなどの大規模プロジェクトに存在しています。



ライブラリの利点:



短所:





まとめ



注意!
著者の主観的な意見。
  • Pantheios — , , ,
  • Glog — , , . — , .
  • Log4cpp — , - ( , ) , /.
  • P7 — , embedded . , , , ( home ). – , . , ( Sink ) (5-7)
  • G3Log, SpdLog — , , –
  • Easylogging — , ,
  • Boost.Log — , , - , , nullptr . , - .




ご清聴ありがとうございました。この記事が、現代のロガーの現実についての一般的なアイデアの作成に役立つことを願っています。



All Articles