Javaに関する様々な情報をご紹介します。

Javaに関する様々な情報をご紹介します。
評価

0

java.util.logging.Loggerでのログ出力について

初めて書込みさせていただきます。よろしくお願いいたします。

java.util.logging.Loggerでログファイルを出力しようとしているのですが、
1日ごとに1ファイルずつのログを出そうとして上手くいかず困っています。

-----------------以下、ソース-----------------
        Date date = new Date();
        Format sdf = new SimpleDateFormat("yyyyMMdd");
        String now = sdf.format(date);

        Logger logger = Logger.getLogger("test");
        FileHandler fh = new FileHandler(now + ".log",true);  //←ここがtrueなのでログファイルに追記
        fh.setFormatter(new SimpleFormatter());

        String logText = "HogeHoge";

        logger.addHandler(fh);
        logger.setLevel(Level.ALL);
        logger.log(Level.ALL , logText);
-----------------ここまで-----------------

簡略化しましたが、実際はある問い合わせフォームからボタンを押すとログが残るような
作りを目指しています。
自分の考えでは、上のコードで、
20070131.logという1ファイルに追加でログが残ると思っていましたが、
実際に動かしてみると、
20070131.log
20070131.log.1
20070131.log.2
などと問い合わせを押すたびに新たなファイルが残ってしまいます。
一番上の、数字なしのファイルにはちゃんとログが追加されているので、
この1ファイルのみ書き出されればいいのですが…。
さらに
20070131.log.lck
20070131.log.1.lck
20070131.log.2.lck
などと(おそらく)ロックファイルまで出力され、
ファイルの量が肥大化してしまいました。
lckファイルはTomcatを止めれば消えてくれるようですが、
実際は常時動かし続けていたいので現実的ではありません。
「日付.log」の1ファイルのみ書き出す方法をどなたか教えていただけませんでしょうか。
一応、自分でもそれなりに調べてみたつもりですが…
なかなかいい資料を見つけられませんでした。
恐縮ですが、よろしくお願いいたします。

5

回答

12602

閲覧

5件の回答

評価

0

こんにちは
FileHandlerを渡してやるところ
logger.addHandler(fh);
は繰り返し実行されてたと思います。
これを初回起動時しか実行しないようにすると
ファイルはいくつも作られないと思います。

評価

0

nuさん、素早い回答ありがとうございました。

>これを初回起動時しか実行しないようにすると
すいません、まだ未熟者で見当違いのことを言ってるかもしれませんが、
ソースから
FileHandler fh = new FileHandler(now + ".log",true);
fh.setFormatter(new SimpleFormatter());
logger.addHandler(fh);
を削除し、
JDKインストールディレクトリの
/jre/lib/配下のlogging.propertiesを
変更することによって回避できました。
しかし、別の問題が…。
上記ソースでは Date date = new Date();でその日の日付を取っていますが、
propertiesファイル内では/java%u.logという特殊な書き方で
(実際にはjava0.log、java1.logと出力されるようです)
一日ごとに出力する方法が分からなくなってしまいました…。
それとも、propertiesファイルに記述するというやり方からして間違っているのでしょうか。


評価

0

>変更することによって回避できました。

実際には logger.addHandler(fh);を複数回実行しなくなったので回避できています。

>20070131.log.1
このようにログが出力される原因は次の理由によります。
LoggerはaddHandlerによって追加された、ハンドラ全てに対してログ出力を試みます、つまり
Logger logger = Logger.getLogger("test");
以降に、実行されたaddHandler()のハンドラに全部出力を試みます。
2回、3回と繰り返すとその分ハンドラが追加されます。

このとき複数のハンドラは同じファイル名を保持しているので、ロガーが二つ目に書き込もうとしても制御を奪えずエラーになります。
エラーになってもログを残すべくファイル名に番号を追加してログを記録します。

なので、Logger logger = Logger.getLogger("test");後1回だけlogger.addHandler(fh);を実行すれば問題は解決するはずです。
ロジックを検討してみましょう。

評価

0

tamaさん、ご回答ありがとうございます。
先ほどのnuさんにもご回答いただきましたが…
恐縮ですが、「初回起動時のみ、1回だけ」実行する、という
やり方が分からないのです…。
ビジネスロジックには書かずにTomcatの設定かなにかをいじるのでしょうか。
それとも、
if(!execcute){
        logger.addHandler(fh);
        execcute = true;
}
のようにif文で囲んでboolean execcuteをBeanか何かに格納して
Tomcat起動時からずっと保持させておく、というような
ことなのでしょうか?
何分、初回起動時のみ実行するというようなコードを書いたことがないもので…
初歩的な質問ですいません。

評価

0

なるほど、ちゃんと見てませんでしたがTomcatなのですね。
java.util.logging.Loggerを利用して独自にログを残したいということでよろしいでしょうか?

Logger logger = Logger.getLogger("test");
によって適切に新しいロガーまたは既設のロガーを取得した後に。
getHandlers()を利用して登録されているHandler[]を取得します。
取得した中に例えば今回だとFileHandlerが既に登録されていれば、addHandlerせず、無ければaddHandlerするという感じでいいと思います。

あ、日付が変わった場合の処理も自力のようですね、この場合一旦removeHandler()してaddHandler()が必要ですね。

logging.propertiesのpatternがもっと柔軟であれば、なにも考える必要は無いのでしょうけどね・・
Log4Jを使うという選択肢はないのでしょうか?

もっといい方法があるかもしれませんが、この辺にあまり明るくないので・・

質問から6ヶ月以上経過しているので、回答を書き込むことはできません。