この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Javaでログ出力するなら Apache log4j を使いたくなります。AMF通信やサーバプッシュで有名な BlazeDS において、この Log4j を使おうと思っても標準機能では上手くいきません。
BlazeDS には flex.messaging.log パッケージにある AbstractTarget クラスを基底とする独自のロギングの仕組みが提供されています。そしてこれらの設定は WEB-INF/flex/services-config.xml で定義されています。
<services-config>
(・・・省略・・・)
<logging>
<target class="flex.messaging.log.ConsoleTarget" level="INFO">
<properties>
<prefix>[BlazeDS] </prefix>
<includeDate>true</includeDate>
<includeTime>true</includeTime>
<includeLevel>true</includeLevel>
<includeCategory>true</includeCategory>
</properties>
<filters>
</filters>
</target>
</logging>
</services-config>
標準のコンソール出力は上記のとおりです。要するに Log4j で出力するターゲットクラスを作って指定すれば、期待する実装が可能になります。
そしていきなりですが、作成したクラスは下記のとおりになります。flex.messaging.log.LineFormattedTarget クラスをベースに、ログレベルとタイムスタンプの機能を除いて作りました。これらは Log4j で制御するためです。
package jp.cm.log;
import org.apache.log4j.Logger;
import flex.messaging.log.AbstractTarget;
import flex.messaging.log.LogEvent;
import flex.messaging.config.ConfigMap;
import flex.messaging.util.ExceptionUtil;
import flex.messaging.util.StringUtils;
public class BlazeLog4jTarget extends AbstractTarget {
protected Logger logger = Logger.getRootLogger();
protected boolean includeCategory;
protected String prefix = null;
public BlazeLog4jTarget() {
super();
}
/**
* Initializes the target with id and properties. Subclasses can overwrite.
*
* @param id
* id for the target which is ignored.
* @param properties
* ConfigMap of properties for the target.
*/
public void initialize(String id, ConfigMap properties) {
super.initialize(id, properties);
includeCategory = properties.getPropertyAsBoolean("includeCategory",
false);
prefix = properties.getPropertyAsString("prefix", null);
}
/**
* Returns includeCategory property.
*
* @return <code>true</code> if category is included; <code>false</code>
* otherwise.
*/
public boolean isIncludeCategory() {
return includeCategory;
}
/**
* Sets includeCategory property.
*
* @param includeCategory
*/
public void setIncludeCategory(boolean includeCategory) {
this.includeCategory = includeCategory;
}
/**
* Returns prefix property.
*
* @return The prefix for log messages.
*/
public String getPrefix() {
return prefix;
}
/**
* Sets prefix property.
*
* @param prefix
*/
public void setPrefix(String prefix) {
this.prefix = prefix;
}
/**
* This method handles a <code>LogEvent</code> from an associated logger. A
* target uses this method to translate the event into the appropriate
* format for transmission, storage, or display. This method will be called
* only if the event's level is in range of the target's level.
*/
@Override
public void logEvent(LogEvent event) {
StringBuffer result = new StringBuffer();
if (prefix != null) {
result.append(prefix);
}
if (includeCategory) {
result.append("[" + event.logger.getCategory() + "] ");
}
result.append(event.message);
if (event.throwable != null) {
result.append(StringUtils.NEWLINE).append(
ExceptionUtil.toString(event.throwable));
}
switch (event.level) {
case LogEvent.ALL:
if (logger.isTraceEnabled()) {
logger.trace(result.toString());
}
case LogEvent.DEBUG:
if (logger.isDebugEnabled()) {
logger.debug(result.toString());
}
break;
case LogEvent.INFO:
if (logger.isInfoEnabled()) {
logger.debug(result.toString());
}
break;
case LogEvent.WARN:
logger.warn(result.toString());
break;
case LogEvent.ERROR:
logger.error(result.toString());
break;
case LogEvent.FATAL:
logger.fatal(result.toString());
break;
}
}
}
この BlazeLog4JTarget クラスを定義する services-config.xml は下記のようになります。
<services-config>
<logging>
<target class="jp.cm.log.BlazeLog4jTarget" level="INFO">
<properties>
<prefix>[BlazeDS] </prefix>
<includeCategory>true</includeCategory>
</properties>
<filters>
</filters>
</target>
</logging>
</services-config>