Logbackからjava.util.loggingへログ出力するAppender
Logback 0.9.24からjava.util.logging.Loggerへ出力するためのAppenderです。
旧ブログのこの記事で公開したものを最新の0.9.24に対応させたものです。
前回同様Apache License 2.0です。こちらからライセンスをダウンロードしてください。(いい加減、ちゃんとした方法考えないとなぁ。Google Codeを使うとか)
/* * Copyright 2010 PoaD. * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package tv.dyndns.poad.commons.logging.logback; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; import ch.qos.logback.classic.spi.LoggingEvent; import ch.qos.logback.core.Layout; import ch.qos.logback.core.UnsynchronizedAppenderBase; /** * <p> * 出力要求された内容を<code>java.util.logging.Logger</code>に出力するlogbackのAppender。 * </p> * logbackのAppenderだが、java.util.logging(以下、jul)に出力しているため、 * logbackの設定の他に、julの設定が必要となる。 </p> * <p> * 設定内容は、julのカテゴリー名(Logger名?)およびlogbackのAppenderに「tv.dyndns.poad.logging.logback * .JDKLogAppender」(このAppenderの名前)をする。<br /> * <code>tv.dyndns.poad.logging.logback.JDKLogAppender.level = ALL<br> * <appender name="STDOUT" class="tv.dyndns.poad.logging.logback.JDKLogAppender"></code> * といったように設定をし、他はlogbackの設定だけで動くはず。 * </p> * * @version $Rev$ * @author $Author$ * @param <E> **/ public class JDKLogAppender<E> extends UnsynchronizedAppenderBase<E> { @SuppressWarnings("serial") static Map<ch.qos.logback.classic.Level, Level> levelMap = new HashMap<ch.qos.logback.classic.Level, Level>() { { this.put( ch.qos.logback.classic.Level.ERROR, java.util.logging.Level.SEVERE); this.put( ch.qos.logback.classic.Level.WARN, java.util.logging.Level.WARNING); this.put( ch.qos.logback.classic.Level.INFO, java.util.logging.Level.INFO); this.put( ch.qos.logback.classic.Level.DEBUG, java.util.logging.Level.FINE); this.put( ch.qos.logback.classic.Level.TRACE, java.util.logging.Level.FINER); } }; protected Layout<E> layout; /** * This default constructor does nothing. **/ public JDKLogAppender() { // 何もしない } /** * Instantiate a JDKLogAppender and set the layout for this appender. * * @param layout **/ public JDKLogAppender(final Layout<E> layout) { this.setLayout(layout); } /** * @param layout **/ public void setLayout(final Layout<E> layout) { this.layout = layout; } /* * (非 Javadoc) * * @see * org.apache.log4j.AppenderSkeleton#append(org.apache.log4j.spi.LoggingEvent * ) */ @Override protected void append(final E event) { if (event instanceof LoggingEvent) { final LoggingEvent levent = (LoggingEvent) event; Logger.getLogger(JDKLogAppender.class.getName()).log( levelMap.get(levent.getLevel()), this.trimLineFeed(this.layout.doLayout(event))); } } /* * (非 Javadoc) * The last line-feed character of passed String is trimmed and it returns * it. * * @param string * * @return String to which the last line-feed character is trimmed. */ private String trimLineFeed(final String string) { if (string.charAt(string.length() - 1) == '\n') { return string.substring(0, string.length() - 2); } return string; } }
こんなのを作って使ったり、こんなの(log4jからjava.util.logging.Loggerへ出力するためのAppender)を作って使ったりしているのは、Google App Engineのコンソールにはき出されるログが、PDT(サマータイムから切り替わったらまた時差が変わるんだろうなぁ)だったりするので分かりづらい。
かといって、Logbackやlog4jのConsoleAppenderだと、今度はコンソール側でのログレベルが同じになってしまう(STDOUTやらSTDERRORにはき出されるからね)。
なので、どうしてもjava.util.logging.Loggerからはき出さないとならないのだけれどもPatternを設定しても動いてくれないから、log4jやlogbackを使って無理矢理JSTの時間をくっつけて吐き出させているわけです。
っていうか、管理コンソール側で表示を切り替えられたりすればいいのに…