sjava-config, sjava-logging 라이브러리가 1.4버전으로 업데이트 되었습니다.
sjava-config(1.4) : http://sjava-config.googlecode.com/files/sjava-config-1.4.zip
sjava-logging(1.4) : http://sjava-logging.googlecode.com/files/sjava-logging-1.4.zip
태그: sjava-logging
addShutdownHook() problem with java.util.Timer instance
java.util.Timer를 Logging 라이브러리에서 사용을 하고 있고, Logging라이브러리를 사용하고 있는 로깅서버에서 addShutdownHook() 메서드를 사용해서 등록한 쓰레드가 실행이 안 된다.. ^^;;
Java API 문서를 보면, 아래와 같은 내용이 있다.
Timer 객체의 마지막 라이브 참조가 종료해, 미 처리의 태스크가 모두 실행되면, 타이머의 태스크 실행 thread도 동시에 완료해, 가비지 컬렉트됩니다. 다만, 이것에는 한없고 긴 시간이 걸리는 경우가 있습니다. 디폴트에서는 태스크의 실행 thread는 「demon thread」로서는 실행되지 않기 때문에 어플리케이션이 종료하지 않게 할 수 있습니다. 타이머의 태스크 실행 thread를 즉시 완료시키는 경우, 호출측은 타이머의 cancel 메서드를 호출할 필요가 있습니다.
흠, 그렇다, 종료가 안된다..^^;;
그래서, Timer() 대신 daemon으로 Timer객체를 생성하면, addShutdownHook() 메쏘드에 등록된 쓰레드의 run() 메쏘드가 잘 동작한다. ^^;;
Timer()
새로운 타이머를 작성한다.
Timer(boolean isDaemon)
demon로서 실행되도록 지정할 수 있는 관련 thread를 가지는 새로운 타이머가 작성됩니다.
sjava-logging 1.0 Level
sjava-logging library는 level에 따른 로깅 가능여부를 체크하고 있지는 않습니다.
아래의 Level은 로깅파일의 분류 및 파일의 내용에 기입을 하기 위한 클래스입니다.
그리고, Level에 대한 사용을 위해서는 LevelFactory를 사용하면 됩니다.
LevelFactory.java
import java.util.Map;
import java.util.HashMap;
/**
*
* @author mcsong@gmail.com
* @since 2009. 7. 1.
*/
public class LevelFactory {
/** map of levels */
private Map<String, Level> levelMap;
/** singleton instance */
private static LevelFactory instance = new LevelFactory();
/** constructor */
private LevelFactory() {
this.levelMap = new HashMap<String, Level>();
this.levelMap.put(“all”, new Level(0, “all”));
this.levelMap.put(“fatal”, new Level(1, “fatal”));
this.levelMap.put(“error”, new Level(2, “error”));
this.levelMap.put(“warn”, new Level(3, “warn”));
this.levelMap.put(“info”, new Level(4, “info”));
this.levelMap.put(“debug”, new Level(5, “debug”));
this.levelMap.put(“trace”, new Level(6, “trace”));
this.levelMap.put(“system”, new Level(7, “system”));
}
/**
*
* @return
*/
public static LevelFactory getInstance() {
return instance;
}
/**
*
* @param level
* @return
*/
public Level getLevel(int level) {
switch (level) {
case 1:
return this.getLevel(“fatal”);
case 2:
return this.getLevel(“error”);
case 3:
return this.getLevel(“warn”);
case 4:
return this.getLevel(“info”);
case 5:
return this.getLevel(“debug”);
case 6:
return this.getLevel(“trace”);
case 7:
return this.getLevel(“system”);
default:
return this.getLevel(“all”);
}
}
/**
*
* @param name
* @return
*/
public Level getLevel(String name) {
if (name == null)
return null;
if(!this.levelMap.containsKey(name.toLowerCase()))
return (Level)this.levelMap.get(“all”);
return (Level)this.levelMap.get(name.toLowerCase());
}
}
Level.java
/**
*
* @author mcsong@gmail.com
* @since 2009. 6. 19.
*/
public class Level {
/** level number */
public int level;
/** level name */
public String name;
/**
* Constructor
*
* @param level
* @param name
*/
public Level(int level, String name) {
this.level = level;
this.name = name;
}
/**
* @return the level
*/
public int getLevel() {
return level;
}
/**
* @param level the level to set
*/
public void setLevel(int level) {
this.level = level;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return “name is ” + this.name + “, level is ” + this.level;
}
}
sjava-logging 1.0
java logging library 입니다.
file에 write 하는 BufferedWriter의 성능을 높이기 위한 tip이 적용되어 있습니다.
config 처리는 sjava-config 코드를 복사해서 패키지 이름만 바꿨습니다. ^^;;
아래 예제는 설정파일과 sjava-logging-1.0.jar를 클래스 패스가 잡힌 위치에 복사를 하시고 돌리시면 됩니다.
예제
package net.sjava.logging.test;
import net.sjava.logging.Logger;
import java.util.Date;
import java.text.SimpleDateFormat;
public class LoggingTest {
private static SimpleDateFormat format = new SimpleDateFormat(“yyyy.MM.dd HH:mm:ss SSS”);
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//load();
// add shutdown hook
Runtime.getRuntime().addShutdownHook(new Thread() {
public void run() {
net.sjava.logging.util.BufferedWriterCacheUtility.shutdown();
}
});
System.out.println(“s – ” + format.format(new Date()));
for(int i=0; i < 1000000; i++) {
Logger.getInstance().log(“aaaaaaaaaaaaaaa”);
Logger.getInstance().log(“aaaaaaaaaaaaccccccccccccccccccaaa”);
Logger.getInstance().log(“metoo”, “푸푸푸푸푸박.. “);
Logger.getInstance().log(“abcded”, “abcde”, “aaaa b aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa”);
}
System.out.println(“e – ” + format.format(new Date()));
}
}
설정파일
<sjava-logging>
<!– array variable delimeter is “,” –>
<!– do not delete –>
<sjava-service name=”config”>
<key name=”watch” value=”false” /> <!– true, false –>
<key name=”period” value=”60″ /> <!– 60 seconds –>
</sjava-service>
<!– 로그서버 설정 –>
<sjava-service name=”logging”>
<key name=”baseDir” value=”d:\sjava-logging” />
<key name=”serviceDir” value=”default” />
<key name=”fileName” value=”default” />
<key name=”fileExt” value=”log” />
<key name=”bufferSize” value=”1024″ />
<!– dayily(1), hourly(2), minutes(3) –>
<key name=”strategy” value=”2″ />
</sjava-service>
</sjava-logging>
바이너리 & 소스
cfile21.uf.175436194A55461107BB1D.zipcfile1.uf.17538C194A55461100FD89.zip