伐採のトピックとそれがもたらしたものについての私の考えを共有したいと思います。
おそらく、理論的な研究が不足しているために、ロギングは常にJavaの世界での混乱の領域でした。 時間が経つにつれて、これにより、次のようなロギング用のいくつかのライブラリが出現しました。
- Log4j
- Java Utilロギング
- コモンズロギング
- ログバック
- Log4j2
残りの部分を絞り込もうとすると、残念ながらそれぞれに欠点がありました。
また、コードの標準化の観点から、Slf4jの登場後に状況が改善された場合-ロギングの抽象化レイヤーとして、既存の実装には未解決の問題が依然として存在します。
オープンソースコミュニティとして、私たちはイニシアチブを取り、新しい革新的なアプローチを考案し、スクリプトなどの最新の開発を使用して軽量な(同時に機能的にも豊富な)ロガーを作成しています。
問題
-既存の実装は、設定でスクリプトの部分的なサポートのみを提供します
これにより、ロガー構成ファイル(XML、JSON、YAML)で宣言型プログラミングが行われますが、命令型スクリプトを使用して実行時に構成値を動的に解釈する方がはるかに簡単です。
ログレベルがINFOのメッセージのみを記録するための、Logbackのフィルター構成の例を見てみましょう。
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter>
これは、宣言型XMLプログラミングの典型的な例です。
(はい、LogbackはGroovyを使用したフィルターをサポートしますが、ロガーではなく特定のアペンダーにのみ適用されます)
しかし、文字列フォーマットのスクリプトサポートは完全に欠落しています。
-複雑で長すぎる設定
LogbackとLog4j2を取得します。
特定のアペンダーのログレベルを構成する方法はありません。
アペンダーはロガーとは別に構成され、ロガーは「AppenderRef」属性を使用してアペンダーを参照しますが、ロガーのみがロギングレベルとクラス名の設定をサポートします。
他のログファイルやクラスに影響を与えずに、特定のログファイルから1つのFooクラスのデバッグメッセージを除外する必要があるとします。
Logbackでは、これはアペンダーのGroovyスクリプトフィルターを使用して可能です-しかし、アペンダーが多数ある場合、構成のサイズは指数関数的に大きくなります。
-ロギングの各レベル-個別のファイル!
メッセージがメッセージレベル(デバッグ、情報など)によってファイルにグループ化されるような設定の可能性を見つけることができませんでした。
既存の機能では、ロギングの各レベルでアペンダーを複製する必要があります。
-ルートロガー自体のクラス名によるフィルタリングの設定
ルートロガーはログレベルのみの設定をサポートしますが、どのクラスをログに記録するかを集中管理する可能性はありません。
-アプリケーションでのログデータの生成方法と、ロガーによるこのデータの消費方法との間には概念的な切断があります。
歴史的な慣習では、ロガー(およびその構成)はファイル中心である場合よりもクラス中心です。
これは、個々のクラスを設定することを心配するのではなく、ログファイルの最終的な内容に関する期待をより論理的に知覚する人間の知覚と矛盾します。
実際には、このパラドックスが、既存の実装の機能制限の理由です。
- 複雑なファイル名構成
- ロガーの不合理な構成、たとえば:
Logbackは、「SiftingAppender」で最大1つの「識別者」をサポートします。
SiftingAppenderには、アーカイブのポリシー設定に制限があります
Log4j2で再設計されたRoutingAppender
解決策
-構成での完全なスクリプトサポート
Bobbinは、構成をアプリケーション実行時のロガーの動作を決定するGroovyスクリプトのロケーターとして使用します。
これは、「フィルター」の例のようです。
{ "levels": "['info'].contains(level)" }
ロガーの各側面は、スクリプトを使用したカスタマイズをサポートしています。
- ロギングレベル
- クラス名
- メッセージフォーマット
- ファイル名
-シンプルで簡潔なセットアップ
ボビンは、エンコーダー、パターン、フィルター、弁別器、およびその他の多くの余分なものを必要としません。
いくつかの基本的なパラメーターのみで構成されています。
- レベル
- クラス
- ファイル
- 行フォーマット
ログレベルごとに個別のファイル:Bobbin.json(構成ファイル)のファイル名マスクに「$ {level}」を入れるだけです。
設定ファイルの例:
{ "levels": "['debug', 'info', 'warn', 'error'].contains(level)", "destinations": [ { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/PLUGINS/INPUT/${className}/${level}/${className}_${level}.log\"" }, "classes": "className.contains('conf.plugins.input')" }, { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/PLUGINS/OUTPUT/${className}/${level}/${threadName}_${level}_${date}.log\"" }, "classes": "className.contains('conf.plugins.output')" }, { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/THREADS/${threadGroupName}/${threadName}/${level}/${threadName}_${level}_${date}.log\"" }, "classes": "className.contains('io.infinite.')" }, { "name": "io.infinite.bobbin.destinations.FileDestination", "properties": { "fileName": "\"./LOGS/ALL/WARNINGS_AND_ERRORS_${date}.log\"" }, "levels": "['warn', 'error'].contains(level)" }, { "name": "io.infinite.bobbin.destinations.ConsoleDestination", "levels": "['warn', 'error'].contains(level)" } ] }
今すぐボビンをお試しください:
Gradle: compile "io.infinite:bobbin:2.0.0"
* Bobbinは、Apacheの下でライセンスされるオープンソースプロジェクトです。