Programming with Java, part 10

記事
IT・テクノロジー

1.About log

I think that the purpose of outputting the log is as follows.
・To confirm whether the process was performed when
 testing the program.
・To log a message when an error occurs and use it
 for investigation.
・To record the processing date and time and access
 status to check for hacking.

"Log4j" is a representative Java log output, and it is
one of the Java logging frameworks. But I think the
Logger class in the java.util.logging package is more
suitable for beginners. So let's take a look at the
Logger class this time.


2.java.util.logging.Logger

The following program explains how to output logs
using the Logger class.

-------------------------- LogTest.java -------------------------------------
import java.util.logging.*;
public class LogTest {
    public static void main(String args[]){
        Logger log = Logger.getLogger(LogTest.class.getName());
        try {
            FileHandler fh = new FileHandler("test.log", true);
            fh.setFormatter(new SimpleFormatter());
            log.addHandler(fh);

            // Set log level.
            log.setLevel(Level.FINE);

            log.finest("This is a message of Level.FINEST.");
            log.finer("This is a message of Level.FINER.");
            log.fine("This is a message of Level.FINE.");
            log.config("This is a message of Level.CONFIG.");
            log.info("This is a message of Level.INFO.");
            log.warning("This is a message of Level.WARNING.");
            log.severe("This is a message of Level.SEVERE.");

            // Exception
            throw new ArrayIndexOutOfBoundsException();

        } catch(ArrayIndexOutOfBoundsException e) {
            log.log(Level.SEVERE, "Catch a exception. Detail:", e);
        } catch(Exception e) {
            log.severe(e.toString());
        }
    }
}
----------------------------------------------------------------------------------

First, in order to use the Logger class provided by Java,
write "import java.util.logging. *;". Next,

        Logger log = Logger.getLogger(LogTest.class.getName());

create a new logger with the getLogger method of the
Logger class.(If you have already created a logger,
it will be returned.)Pass the name of the logger as a
String type to a parameter. This time,
"LogTest.class.getName()" is passed, but you should
write the class name of the created program like
"class name.class.getName()".

            FileHandler fh = new FileHandler("test.log", true);

Next, create an object of FileHandler class. Pass the name
of the output file to a parameter. At this time, it is also
possible to include the output destination path of the file.
In addition, you can specify additional modes for the
output file with parameters. If true is passed, it will be added,
and if false is passed, it will be overwritten.

            fh.setFormatter(new SimpleFormatter());
            log.addHandler(fh);

You can specify the format of the output file by the
setFormatter method. Then pass the FileHandler object
to Logger's addHandler method. Next, set the log level.

            log.setLevel(Level.FINE);

Pass the log level to a parameter of the setLevel method.
As for the log level, SEVERE is the highest level and
FINEST is the lowest level as shown below. Since I set
the level to FINE this time, the log of FINE ~ SEVERE is
output.

■ Log level
・SEVERE (Use when you notify a serious failure)
・WARNING(In case of warning)
・INFO(Providing information)
・CONFIG(Providing configuration)
・FINE(Providing trace information)
・FINER(Providing detail trace information)
・FINEST(Providing extremely detailed trace information)


I am trying to output the log with the log.finest ~ log.severe
method, but because I set the log level to FINE, log.finest
and log.finer do not output the log.
Finally,

            throw new ArrayIndexOutOfBoundsException();

this intentionally raises an exception. I wrote it to check
if the following log output in catch is done.

            log.log(Level.SEVERE, "Catch a exception. Detail:", e);


And the log actually output by Logger is the following test.log.

-------------------------- test.log -------------------------------------
1 10, 2021 10:45:01 午前 LogTest main
普通: This is a message of Level.FINE.
1 10, 2021 10:45:01 午前 LogTest main
構成: This is a message of Level.CONFIG.
1 10, 2021 10:45:01 午前 LogTest main
情報: This is a message of Level.INFO.
1 10, 2021 10:45:01 午前 LogTest main
警告: This is a message of Level.WARNING.
1 10, 2021 10:45:01 午前 LogTest main
重大: This is a message of Level.SEVERE.
1 10, 2021 10:45:01 午前 LogTest main
重大: Catch a exception. Detail:
java.lang.ArrayIndexOutOfBoundsException
 at LogTest.main(LogTest.java:23)
---------------------------------------------------------------------------

In this way, the date and time when the log was output and
the name of the logger (class name) are output on the first
line. On the second line, the log level and the message
described in the program are output.


Next time, I will make a game of CUI with Java. With the
programming techniques I've introduced so far, I should
be able to complete it. I would appreciate it if it would be
helpful for people who have no programming experience.


[Japanese]

1.ログについて

ログを出力する目的は
・プログラムのテストで処理が行われたか(ロジックを通過したか)を
 確認するため。
・エラー発生時にメッセージをログに残して、調査に役立てるため。
・処理日時やアクセス状況を記録して、不正アクセスが無いか検査するため。
が考えられます。

Javaのログ出力は「log4j」が代表的で、Java logging frameworkの1つなのですが、初級編としてはjava.util.loggingパッケージのLoggerクラスの方が相応しいと思います。そのため、今回はLoggerクラスを見ていきましょう。


2.java.util.logging.Logger

Loggerクラスによるログ出力方法を、下記のプログラムで解説します。

-------------------------- LogTest.java -------------------------------------
import java.util.logging.*;
public class LogTest {
    public static void main(String args[]){
        Logger log = Logger.getLogger(LogTest.class.getName());
        try {
            FileHandler fh = new FileHandler("test.log", true);
            fh.setFormatter(new SimpleFormatter());
            log.addHandler(fh);

            // Set log level.
            log.setLevel(Level.FINE);

            log.finest("This is a message of Level.FINEST.");
            log.finer("This is a message of Level.FINER.");
            log.fine("This is a message of Level.FINE.");
            log.config("This is a message of Level.CONFIG.");
            log.info("This is a message of Level.INFO.");
            log.warning("This is a message of Level.WARNING.");
            log.severe("This is a message of Level.SEVERE.");

            // Exception
            throw new ArrayIndexOutOfBoundsException();

        } catch(ArrayIndexOutOfBoundsException e) {
            log.log(Level.SEVERE, "Catch a exception. Detail:", e);
        } catch(Exception e) {
            log.severe(e.toString());
        }
    }
}
----------------------------------------------------------------------------------

まずはJavaが提供しているLoggerクラスを利用するため、
「import java.util.logging.*; 」を記述します。続いて、

        Logger log = Logger.getLogger(LogTest.class.getName());

LoggerクラスのgetLoggerメソッドで、新しいロガーを作成します(既にロガーを作成済みの場合はそれが返されます)。パラメータにはロガーの名前をString型で渡します。今回は「LogTest.class.getName()」を渡していますが、「クラス名.class.getName()」のように、作成したプログラムのクラス名を書くと良いでしょう。次に、

            FileHandler fh = new FileHandler("test.log", true);

FileHandlerクラスのオブジェクトを作ります。パラメータには出力ファイルの名前(ファイルの出力先パスを含めてもOKです)を渡します。また、出力ファイルに対する追加モードをパラメータで指定できます。
trueを渡すと追記、falseを渡すと上書きで出力します。続いて、

            fh.setFormatter(new SimpleFormatter());
            log.addHandler(fh);

setFormatterメソッドで出力ファイルのフォーマットを指定しています。その後、LoggerのaddHandlerメソッドにFileHandlerオブジェクトを渡します。
次はログレベルを設定します。

            log.setLevel(Level.FINE);

setLevelメソッドのパラメータに、ログレベルを渡します。ログレベルは、下記のようにSEVEREが最も高いレベルで、FINESTが一番低いレベルです。今回はレベルをFINEに設定しましたので、FINE 〜 SEVEREのログが出力されます。(FINERとFINESTレベルのログは出力されません)

■ ログレベル
・SEVERE (重大な障害を通知する時に利用する)
・WARNING(警告する時)
・INFO(情報提供する時)
・CONFIG(構成情報を提供する時)
・FINE(トレース情報を提供する時)
・FINER(詳細なトレース情報を提供する時)
・FINEST(非常に詳細なトレース情報を提供する時)


log.finest 〜 log.severeメソッドでログ出力しようとしていますが、ログレベルをFINEに設定したため、log.finestとlog.finerメソッドではログ出力されません。最後に
            throw new ArrayIndexOutOfBoundsException();
によって、意図的に例外を発生させています。これは、catch内の
            log.log(Level.SEVERE, "Catch a exception. Detail:", e);
このログ出力が行われるかどうかを確認するために記述しました。


そして、Loggerによって実際に出力されたログが下記のtest.logです。

-------------------------- test.log -------------------------------------
1 10, 2021 10:45:01 午前 LogTest main
普通: This is a message of Level.FINE.
1 10, 2021 10:45:01 午前 LogTest main
構成: This is a message of Level.CONFIG.
1 10, 2021 10:45:01 午前 LogTest main
情報: This is a message of Level.INFO.
1 10, 2021 10:45:01 午前 LogTest main
警告: This is a message of Level.WARNING.
1 10, 2021 10:45:01 午前 LogTest main
重大: This is a message of Level.SEVERE.
1 10, 2021 10:45:01 午前 LogTest main
重大: Catch a exception. Detail:
java.lang.ArrayIndexOutOfBoundsException
 at LogTest.main(LogTest.java:23)
---------------------------------------------------------------------------

このように、1行目にログ出力された日時やロガーの名前(クラス名)が出力されます。2行目は、ログレベルやプログラムに記述したメッセージが出力されます。


次回は、いよいよJavaでCUIのゲームを作っていきます。今回までに紹介したプログラミングテクニックを駆使すれば概ね完成できるはずですので、1からプログラミングした経験が無い方の参考になればと思います。
サービス数40万件のスキルマーケット、あなたにぴったりのサービスを探す