あるプログラマーは、「ログ」の問題のために一晩でハゲになりました。これは道徳的な衰退なのか、それとも何かのせいなのか。。。。
真夜中の朝の2時に。良心的なプログラマーであるXiaoZhangは、コンピューターに向かい、キーボードで入力しています。彼は会社が提供できない大規模なシステムを開発しています。このシステムは少し大きいので、Xiao Zhangは常に、デバッグやテストのSystem.out.println("");
ために簡単に表示できるように、いくつかの重要なデータをコンソールに印刷することを好みます。
しばらくして、Xiao Zhangは、数え切れないほどの髪の毛を失うことを犠牲にして、ついにシステムを開発しました。しかし、ある日、上司がシャオチャンに駆け寄ると言った:「シャオチャンありSystem.out.println("");
すぎてあなたに?システムあなたが彼を取り除くことができます。」方法はありません、シャオチャンできる唯一の彼の仕事保存しましょう。System.out.println("");
RID上司のスケベさの下でこれの。
Xiao ZhangはそれをSystem.out.println("");
取り除いたところ、上司が駆け寄って「出力はかなり良いと思います。コンソールからプロジェクトの実行状況を理解できます」と言いました。XiaoZhangはそのことで上司の家族に心から挨拶しました。時間。。。。
Xiao Zhangは、落ち着くためにタバコを吸いました。そういえば、後で制御できるように、ファイルに書き込むだけでいいのではないでしょうか。Xiao Zhangは、System.out.println("");
また行く時間だと思いました。いいえ、いいえ、それはあまりにも面倒です。XiaoZhangは、システム情報を記録するためのフレームワークを作成するだけだと思いました。早くやれよ。
それからそれはまた別のハゲの日でした。XiaoZhangがついにフレームワークを作成しました。それを与えるzhanglogging.jar
名前を:。このフレームワークのパフォーマンスは悪くなく、XiaoZhangはこのフレームワークに非常に満足しています。しかし、予測できない状況があります。時代の進展とともに、Xiao Zhangは、このフレームワークの機能は少し初歩的であり、もはや時代のペースに追いつくことができないと感じています。Xiao Zhangは、非同期モード、自動アーカイブ、日ごとのログを日ごとに並べ替えてファイルに保存するなど、いくつかの重要な機能について突然考えました。待って待って待って…
それから、いくつかの髪の日があります、言うまでもなく、優れた技術を備えた張、そして最後に開発された第2世代のロギングフレームワークに、名前を付けます:zhanglogging-good.jar
。しかし、シャオ・チャンの髪の毛はどんどん少なくなっています。良い人生の数日以内に、シャオ・チャンが直面した問題が再び起こりました。Xiao Zhangによって作成された新しいフレームワークのAPIまたは一部の設計は、以前に作成された古いフレームワークとは少し異なる場合があります。では、どうすればよいでしょうか。古いフレームの前に削除して、前に関連するAPIを改訂するための新しいフレームワークを配置するだけでなく、いくつかの機能を改善することもできます。最後に、完璧なフレームワークが出てきて、Zhangの名前は次のようになりますzhanglogging-prefect.jar;
。
しかし、問題は再び発生しています。フレームワークを変更するたびにコードを変更する必要があるため、面倒です。XiaoZhangは突然パターンを考えました。JDBCとデータベースドライバの関係を考えてみてください。データベースはすべてインターフェイス指向プログラミングであるため、データベースの実装をデータベースに組み込むだけで済みます。Xiao Zhangは、フレームをこのようにデザインしてみませんか?早くやれよ。
Xiao Zhangは、ログファサード(ログの抽象層)と呼ばれるすべてのログフレームワーク用の統合インターフェイスレイヤーを作成し、次のように名前を付けzhanglogging-abstract.jar
ました。将来コーディングする場合、zhanglogging-abstract.jar
プログラミングのみ、どのログを使用しますかフレームワークはインポートするだけで済みますプロジェクトへの特定のログ実装。以前のロギングフレームワークはすべて、実装された抽象化レイヤーです。Xiao Zhangは本当に会社への心を痛め、彼の髪の毛はどんどん少なくなっています。XiaoZhangのためにワンキー3接続を作りましょう。
次に、今日のトピックに移ります。
記事のディレクトリ
SpringBootロギングフレームワークの選択
JUL(java.util.logging)、JCL(Apche Commons Logging)、Log4j、Log4j2、Logback、SLF4j、jboss-loggingなど、開発中の多くのロギングフレームワークがあります。
ログファサード(ログの抽象化レイヤー) | ログの実装 |
---|---|
JCL(Jakarta Commons Logging)SLF4j(Simple Logging Facade for Java)jboss-logging | Log4jの7月(のjava.util.logging)Log4j2 Logback |
- SpringBootのロギングフレームワークを使用するということは、抽象化レイヤーと実装レイヤーが必要であることを意味します。SpringBootは、実装レイヤーとして
SLF4j
抽象化レイヤーになることを選択しますlogback
。ここで言いたいのは、SpringBootの最下層はSpringフレームワークであり、Springフレームワークはデフォルトで抽象化層としてJCLになっているということです。
SLF4jの使用
システムでSLF4jを使用する方法
(新しいプロジェクトを作成する際に、すでにインポートしていますslf4j和logback
)システムでSLF4jを使用するにはどうすればよいですか?将来の開発では、loggingメソッドの呼び出しは、ログ実装クラスを直接呼び出すのではなく、ログ抽象化レイヤーのメソッドを呼び出す必要があります。
- SLF4は公式に簡単な例を示しています。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
- 次の図は、さまざまなログフレームワークを組み合わせたSLF4Jの公式例です。この図から、SLF4J APIが常にログのファサードであり、アプリケーションに直接適用されることがはっきりとわかります。slf4j公式ウェブサイトユーザーマニュアル
各ログ実装フレームワークには、独自の構成ファイルがあります。slf4jを使用した後も、構成ファイルはログ実装フレームワーク自体の構成ファイルになります。
残りの問題
SpringBootプロジェクトを作成したいのですが、ロギングフレームワークの組み合わせを使用する予定ですSlf4j+logback
が、プロジェクトにはSpring、Hibernate、MyBatis、その他のコンポーネントの依存関係が統合されています。現時点では、統合されたコンポーネントフレームワークに問題があります。独自のロギングフレームワーク。たとえば、SpringにはSpringが付属していますcommons-logging、Hibernate(jboss-logging)
。現時点では、プロジェクトはロギングフレームワークの寄せ集めのようなものであり、非常に面倒です。したがって、プロジェクト内のロギングフレームワークを統合する必要があります。依存しているコンポーネントログフレームワークが付属しているので、構成する必要がありますSlf4j+logback
。
公式ドキュメントを見てみ
ましょう。コンポーネントログのオーバーレイを個別に導入する必要があります。コンポーネント内のログを削除するため、コンポーネントのログフレームワークパッケージを削除できません。これにより、コンポーネントが発生します。クラッシュすると、基になるソースコードが返されます。クラッシュしないため、他のコンポーネントのログフレームワークjarパッケージを削除する場合は、オーバーレイjarパッケージのレイヤーをインポートする必要があります。このjarには、元のAPIが引き続き含まれています。コンポーネントのログフレームワークであり、コンポーネントはエラーなしで実行されます。これは、moreと同等です。適応のレイヤーを作成し、を呼び出してSlf4j+logback
から、この適応のレイヤーを介して各コンポーネントのログフレームワークを呼び出します。
システム内のすべてのログをslf4jに統合する方法。
1.最初にシステム内の他のログフレームワークを除外します。
2.元のログフレームワークを中間パッケージに置き換えます。
3.slf4jの他の実装をインポートします
SpringBootログの関係
- 新しいプロジェクトの
pom.xm
ファイルの内容は自動的に導入されます - スターターはpom.xmlで導入されています。実際、各スターターは多数の依存関係を導入しているので、以下に示すように、どのようにチェックしますか。
- ダブルクリックして
spring-boot-starter-logging
真ん中を入力すると、次のように表示されます
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.4.3</version>
<scope>compile</scope>
</dependency>
総括する:
- SpringBootの最下層は
slf4j+logback
ロギングにも使用されます - SpringBootは、他のログもslf4jに置き換えました。
- 中間交換パッケージ
- 他のフレームワークを導入したい場合。このフレームワークのデフォルトのログ依存関係を必ず削除してください。Springフレームワークはcommons-loggingを使用します。
- SpringBootはすべてのログに自動的に適応でき、最下層はslf4j + logbackを使用してログを記録します。他のフレームワークを導入する場合は、このフレームワークが依存するログフレームワークを削除するだけで済みます。
ログの使用
新しく作成したプロジェクトのテストクラスを直接実行すると、SpringBootがログの構成に役立つことがわかりました。
- テストクラスを変更します。
@SpringBootTest
class SpringbootLoggingApplicationTests {
//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
void contextLoads() {
//trace<debug<info<warn<error
logger.trace("这是trace日志");
logger.debug("这是debug日志");
logger.info("这是info日志");
logger.warn("这是warn日志");
logger.error("这是error日志");
}
}
ロガーが新しいバージョンのアイデアでインスタンス化
Logger logger=LoggerFactory.getLogger(getClass());
されると、自動的にインポートさ
import org.junit.platform.commons.logging.Logger;
import org.junit.platform.commons.logging.LoggerFactory;
れるため、手動で次のように置き換える必要があります。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
ログレベル:
trace<debug<info<warn<error
ログの出力レベルを調整するために、低から高へ。- ログは、このレベル以降のより高いレベルでのみ有効になります
- SpringBootはデフォルトで
info
レベルを使用します。指定されたレベルがない場合は、デフォルトでSpringBootによって指定されたレベルを使用します。つまり、infoがルートレベルです。
情報以上のレベルのみが出力されていることがわかります。
- メイン構成ファイルを次のように変更します
logging.level.com.cz=trace
これは、czパッケージのすべてのクラスが
trace
レベルに調整されていることを意味します
- 設定ファイルの内容を変更し続けてから、1つずつ説明します。
logging.level.com.cz=trace
#当前项目下生成springboot.log日志
logging.file.name=springboot.log
# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
#logging.file.path=/spring/log
# 在控制台输出的日志的格式
logging.pattern.console=%d{
yyyy-MM-dd} [%thread] %-5level %logger{
50} - %msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d{
yyyy-MM-dd} === [%thread] === %-5level === %logger{
50} ==== %msg%n
logging.file.name
ファイルへのログ生成を指定する
-
logging.pattern.console
- 後者
%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
は私たち自身が指定したフォーマットです。
- 後者
-
ログ出力形式:
%d
:日付と時刻を示します。%thread
:スレッド名を表します。%-5level
:レベルは左から5文字幅で表示されます%logger{50}
:ロガー名の長さが最大50文字であることを示します。それ以外の場合は、ピリオドで分割されます。%msg
:ログメッセージ、%n
:改行文字です
指定配置
それでも非同期ロギングなどの機能を使用する必要がある場合は、ロギング専用の構成ファイルを作成する必要があります。詳細については、公式ログ構成ファイルの説明を参照してください
- 各ログフレームワークの独自の構成ファイルをクラスパスの下に置くだけです。SpringBootはデフォルトの構成を使用しません。
ロギングシステム | カスタマイズ |
---|---|
ログバック | logback-spring.xml 、logback-spring.groovy 、logback.xml またはlogback.groovy |
Log4j2 | log4j2-spring.xml または log4j2.xml |
JDK(Java Util Logging) | logging.properties |
logback.xmlを作成し、ログ構成の関連コンテンツを含むリソースディレクトリに配置できます。直接作成するだけで、何も構成する必要はありません。SpringBootは自動的に認識します。
logback.xml
:ログフレームワークによって直接認識されます。
logback-spring.xml
:ログフレームワークはログの構成項目を直接ロードしません。ログ構成はSpringBootによって解析され、SpringBootの高度なプロファイル機能を使用できます。
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
可以指定某段配置只在某个环境下生效
</springProfile>
といった:
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
</springProfile>
<springProfile name="!dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
</springProfile>
</layout>
</appender>
logback.xml
ログ設定ファイルとして使用し、プロファイル機能も使用すると、以下のエラーが発生します。
no applicable action for [springProfile]
ログフレームの切り替え
ただし、切り替えることはお勧めしません。何年にもわたるテストの結果、現在のログフレームワークが使用されています。次の点を確認してください。
その後、依存関係から除外されます。現時点では、pom.xmlで変更するログ実装レイヤーを導入するだけで済みます。