因为经常需要debug一些realtime app,无法在debuger下操作,特别写了一组class,方便配合log4j将debug message写入file。
/*
* LogFormatter.java
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* ALSAN WONG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. ALSAN WONG
* SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT
* OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* Created on 2005-6-3
* Copyright 2005, alsan.home.net
*/
package net.alsan.jlib.util.log;
/**
*
* @author alsan
* @version 1.0
*/
public abstract class LogFormatter {
protected StringBuilder buf = new StringBuilder();
public String toString() {
String msg = buf.toString();
buf = new StringBuilder();
return msg;
}
public abstract LogFormatter print(String msg);
public abstract LogFormatter println(String msg);
public abstract LogFormatter println();
public LogFormatter append(String msg) {
buf.append(msg);
return this;
}
public LogFormatter appendln(String msg) {
buf.append(msg).append("\n");
return this;
}
}
/*
* PrefixLogFormatter.java
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* ALSAN WONG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. ALSAN WONG
* SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT
* OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* Created on 2005-6-13
* Copyright 2005, alsan.home.net
*/
package net.alsan.jlib.util.log;
/**
*
* @author alsan
* @version 1.0
*/
public class PrefixLogFormatter extends LogFormatter {
protected String prefix = "";
protected String _prefix = "";
public PrefixLogFormatter(String prefix) {
_prefix = prefix;
setPrefix(prefix);
}
public void setPrefix(String prefix) {
this.prefix = prefix + ": ";
}
public LogFormatter println(String msg) {
return print(msg).append("\n");
}
public LogFormatter print(String msg) {
return append(prefix).append(msg);
}
public LogFormatter println() {
return append(prefix).append("\n");
}
}
/*
* IndentLogFormatter.java
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* ALSAN WONG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. ALSAN WONG
* SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT
* OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* Created on 2005-6-13
* Copyright 2005, alsan.home.net
*/
package net.alsan.jlib.util.log;
import java.util.Stack;
/**
*
* @author alsan
* @version 1.0
*/
public class IndentLogFormatter extends PrefixLogFormatter {
private Stack stack = new Stack();
public IndentLogFormatter(String prefix) {
super(prefix);
}
private void setTabPrefix() {
byte[] pool = new byte[stack.size()];
for(int i=0; i<pool.length; i++) {
pool[i] ='\t';
}
prefix = _prefix + ": " + new String(pool);
}
public LogFormatter beginBlock(String block) {
String pfix = prefix;
stack.push(block);
setTabPrefix();
return append(pfix).append(block).appendln(" {");
}
public LogFormatter endBlock() {
String block = (String)stack.pop();
setTabPrefix();
return print("} //").appendln(block);
}
}
/*
* DebugLogFormatter.java
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies.
*
* ALSAN WONG MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. ALSAN WONG
* SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT
* OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* Created on 2005-6-3
* Copyright 2005, alsan.home.net
*/
package net.alsan.jlib.util.log;
import org.apache.log4j.Logger;
/**
*
* @author alsan
* @version 1.0
*/
public final class DebugLogFormatter extends IndentLogFormatter {
public DebugLogFormatter(String prefix) {
super(prefix);
}
public LogFormatter beginMethod(String method) {
return beginBlock(method);
}
public LogFormatter endMethod() {
return endBlock();
}
}
测试代码:
static final DebugLogFormatter debug = new DebugLogFormatter("debug");
static final PrefixLogFormatter info = new PrefixLogFormatter("info");
static final Logger log = Logger.getLogger(DebugLogFormatter.class);
public static void test1(String msg) {
debug.beginMethod("test1(String)");
if(msg.equals("hello")) {
debug.beginBlock("hello from boss");
log.info(info.println("i'm busy"));
debug.endBlock();
} else {
debug.beginBlock("zzz");
log.warn(info.println("the holiday is over!"));
debug.endBlock();
}
log.debug(debug.endMethod());
}
public static void test2() {
debug.beginMethod("test2()");
log.info("do somethings others\n");
log.debug(debug.endMethod());
}
public static void main(String[] args) {
test1("hello");
test2();
}
输出结果:
info: i'm busy
debug: test1(String) {
debug: hello from boss {
debug: } //hello from boss
debug: } //test1(String)
do somethings others
debug: test2() {
debug: } //test2()
注意:可以看到log.info的输出并不在debug的message内。因为正常程况下是不需要debug message的,所以需要配置log4j的debug输出与其它level的输出分开。另一个特点,是因为要区分print、println、append、appendln等换行行为,所以配置log4j的输出格式时,不在结尾加%n。又因为希望写出的coding比较optimize,所以其它level的结尾也不加%n,而使用其它level时,可使用PrefixLogFormatter。
个prifix是用来区分不同的thread,在多线程时非常有用,single thread时就可有可无。例如:DebugLogFormatter debug = new DebugLogFormatter(Thread.currentThread.getName());