ロギングとは、起こった出来事についての情報などを時間経過にそって記録する履歴のことです。ソフトウエアを使用する際に特にエラーが発生した場合にこの履歴を確認することで、どこでどんな不具合が発生したか把握でき対応を絞り込むことができます。
Javaではこのロギングの機能が標準モジュールとして用意されています。そんなロギングですがJavaではLoggerクラスを使用することで実装できます。この記事では、Loggerクラスについて以下の内容で解説していきます。
- 【基礎】Logging(ロギング)とは?
- 【基礎】ログレベルとは?
- 【基礎】Loggerでログを出力するには?
- 【発展】propertiesでの設定
- 【発展】Logging(ロギング)の際の留意点
今回はLoggerクラスについて、使い方をわかりやすく解説します!
なお、Javaの記事については、こちらにまとめています。
Logging(ロギング)とは?
Logging(ロギング)とは冒頭でも述べましたが、起こった出来事についての情報などを時間経過にそって記録する履歴のことです。履歴に残す内容としては以下のようなものです。
- 使用している設定値や詳細な情報表示などデバッグ用の表示
- 正常動作の記録
- 警告を出しておきたい動作の記録
- エラーなどの問題の記録
- 停止してしまうような致命的な記録
など、これらの内容は実行時に影響を及ぼす度合いによってレベル分けがされています。
これをログレベルと言いますが、ログレベルについてはこのあと詳しく説明します。
ログレベルとは?
Logging(ロギング)で履歴に残す内容は、実行時に影響を及ぼす度合いによってレベル分けがされています。これをログレベルと言います。ログレベルについてはJavaでは以下のように分類されています。
Javaではログレベルはjava.util.logging.Levelクラスで定義され、ログレベルと対応しています。
レベル分類 | Levelクラスの定数 | Loggerクラスのメソッド | 数値 |
---|---|---|---|
最も詳細 | FINEST | finest | 300 |
詳細 | FINER | finer | 400 |
普通 | FINE | fine | 500 |
構成 | CONFIG | config | 700 |
情報 | INFO | info | 800 |
警告 | WARNING | warning | 900 |
重大 | SEVERE | severe | 1000 |
このレベル分けを基準にして、どのレベルから履歴として残していくか選択することができます。例えばLevel.INFOを設定するとログとして出力されるのは、「情報」「警告」「重大」のように、設定レベル以下が履歴として残されます。
Loggerでログを出力するには?
Loggerクラスを使ってログを出力する方法について、順を追って説明していきます。
Loggerインスタンスの生成
まずLoggerクラスのインスタンスを生成します。例えば以下のように記述します。
Logger logger = Logger.getLogger("loggerの名前")
getLoggerメソッドを使います。getLoggerメソッドの引数にはloggerの名前を指定します。loggerの名前はどのような文字列でも構いませんが、通常ロギングの対象のパッケージ名やクラス名を指定します。
クラス名を取得するにはクラス名.class.getName()を使用します。
出力先の設定
次にファイルに出力する設定を記述します。ファイルに出力するには、FileHandlerクラスを使います。FileHandlerクラスのコンストラクタの第1引数にはファイルパスを指定します。
第2引数には上書き可の場合falseを、追記で指定する場合にはtrueを指定します。第2引数を指定せず、デフォルトの場合は上書き可になります。例えば以下のように記述します。
FileHandler fHandler = new FileHandler(”Sample.log”, true); fHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fHandler);
setFormatterメソッドの引数でファイル出力のフォーマットを設定します。デフォルトはXML形式で出力されますが、ここではSimpleFormatterを指定して人が読みやすい形式で出力するようにしています。
loggerからaddHandlerメソッドを呼び出し、引数にfHandlerを指定します。ちなみに、コンソールに出力することも可能で、その場合は以下のように記述します。
ConsoleHandler cHandler = new ConsoleHandler(); logger.addHandler(cHandler);
ログレベルの設定
ログレベルを設定するには以下のように記述します。
fHandler.setLevel(Level.INFO);
setLevelメソッドを使って引数にLevelクラスの定数もしくは数値を指定します。
サンプルコード
それではサンプルコードを動かして確認してみましょう。
import java.io.IOException; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.SimpleFormatter; public class LoggerSample { public static void main(String[] args) { // Loggerクラスのインスタンスを生成 Logger logger = Logger.getLogger(LoggerSample.class.getName()); try { // Handlerを生成しloggerに登録 FileHandler fHandler = new FileHandler("Sample.log", true); fHandler.setFormatter(new SimpleFormatter()); logger.addHandler(fHandler); // ログレベルの設定 logger.setLevel(Level.INFO); // Loggerクラスのメソッドを使ってメッセージを出力 logger.finest("FINEST"); logger.finer("FINER"); logger.fine("FINE"); logger.config("CONFIG"); logger.info("INFO"); logger.warning("WARNING"); logger.severe("SEVERE"); // 例外をスロー throw new IllegalArgumentException(); } catch (IllegalArgumentException e) { logger.log(Level.INFO, "例外のスローを捕捉", e); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
実行結果(Sample.log):
6月 26, 2018 11:40:18 午後 LoggerSample main 情報: INFO 6月 26, 2018 11:40:18 午後 LoggerSample main 警告: WARNING 6月 26, 2018 11:40:18 午後 LoggerSample main 重大: SEVERE 6月 26, 2018 11:40:18 午後 LoggerSample main 情報: 例外のスローを捕捉 java.lang.IllegalArgumentException at LoggerSample.main(LoggerSample.java:31)
コンストラクタFileHandlerはSecurityExceptionとIOExceptionの例外を発生するのでtry-catch構文を用いています。finestやfinerなどのメソッドでそれぞれのログレベルのログを出力するようにしています。
setLevelメソッドでログレベルの設定をLevel.INFO以下に設定しているので、それに対応したログのみが出力されています。またIllegalArgumentExceptionの例外をスロー、捕捉してlogメソッドでログを出力しています。
logメソッドの第1引数でログレベルを設定しています。第2引数でログに出力するメッセージを指定し、第3引数に例外オブジェクトを指定し、スタックトレースの内容が表示されています。
スタックトレースの内容からどこでどんな例外が発生したか情報を取得することができます。
propertiesでの設定
先ほどのサンプルコードでは、ログの出力先(ファイルかコンソールか)、ログファイルの保存先、ログレベルの設定などを実行クラスの中で指定しました。
しかし、使用するクラス全部にロギングの設定を記述するのは現実的ではないですよね。そこでlogging.propertiesというファイルを使って設定する方法を説明します。logging.propertiesファイルは例えば
C:Program FilesJavajdk-10.0.1conf
にあります。これを元に独自のlogging.propertiesファイルを作成します。
logging.properties(変更部のみ):
handlers= java.util.logging.FileHandler,java.util.logging.ConsoleHandler java.util.logging.FileHandler.level = INFO java.util.logging.FileHandler.pattern = Sample.log java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
import java.io.FileInputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import java.util.logging.LogManager; public class LoggerSample { public static void main(String[] args) { // Loggerクラスのインスタンスを生成 Logger logger = Logger.getLogger(LoggerSample.class.getName()); try { // LogManagerのインスタンスを生成しlogging.propertiesを読み込む LogManager manager = LogManager.getLogManager(); manager.readConfiguration(new FileInputStream("logging.properties")); // Loggerクラスのメソッドを使ってメッセージを出力 logger.finest("FINEST"); logger.finer("FINER"); logger.fine("FINE"); logger.config("CONFIG"); logger.info("INFO"); logger.warning("WARNING"); logger.severe("SEVERE"); // 例外をスロー throw new IllegalArgumentException(); } catch (IllegalArgumentException e) { logger.log(Level.INFO, "例外のスローを捕捉", e); } catch (SecurityException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
実行結果(Sample.log):
6月 26, 2018 11:40:18 午後 LoggerSample main 情報: INFO 6月 26, 2018 11:40:18 午後 LoggerSample main 警告: WARNING 6月 26, 2018 11:40:18 午後 LoggerSample main 重大: SEVERE 6月 26, 2018 11:40:18 午後 LoggerSample main 情報: 例外のスローを捕捉 java.lang.IllegalArgumentException at LoggerSample.main(LoggerSample.java:27)
logging.propertiesを読み込む場合は、LogManagerクラスを使います。readConfigurationメソッドを使ってlogging.propertiesを読み込みます。
Logging(ロギング)の際の留意点
Logging(ロギング)で履歴を残す際に留意するべき点についていくつか挙げておきます。
-
- ログファイルの出力先
ログには重要情報が出力されることもあるため、不特定のユーザーがアクセスできる場所に出力するかどうか注意しましょう。
-
- ログメッセージ
メッセージの内容は専用のファイルにまとめましょう。日本語などのマルチバイト文字は使用する環境によっては文字化けしますので、注意しましょう。内容がわかりやすいように簡潔に記述しましょう。
-
- フォーマット
ログの情報として実行時刻、ログ出力箇所、ログの種類、メッセージは出力表示するようにしましょう。
まとめ
ここでは、Loggerクラスの使い方について説明しました。Logging(ロギング)を使うことで、いつどんな処理が実行されどのような結果になったかさかのぼって確認することができます。
トラブルが発生した時にどんなエラーがどの箇所で発生したか把握できるので後々の対応がしやすくなり便利です。この便利な仕組みを使いこなすことができるように、この記事を何度も参考にして下さいね!