- uk
- ぬし
- 会議室デビュー日: 2003/05/20
- 投稿数: 1155
- お住まい・勤務地: 東京都
|
投稿日時: 2005-03-16 17:00
まず、これだとlognameが同じであればobjectのクラスが異なっても同じLoggerのインスタンスを
返すことになりますが、それは目的に合っていますか? それから、Category#getInstanceが
新しいLoggerのインスタンスを生成して返す、と思われているようですがそれは間違いです。
APIドキュメントを読めばわかるとおり、Logger#getLoggerと同じく、同じ引数に対しては
同じLoggerのインスタンスを返します。もしLoggerのインスタンスを自分で生成したいので
あれば、以下のようなクラスを作れば可能です。
public class CustomLogger extends Logger {
public CustomLogger(String name) {
super(name);
}
}
引用: |
|
hiroさんの書き込み (2005-03-16 13:42) より:
自己スレです。
共通関数で以下のようにCategoryを新規作成することで実現できそうです。
・共通関数(LogManager.java)
--------------------------------------------------------------------------------
private static HashMap logger_map = null;
/**
* log4jのLogger獲得
*
* @param obj:呼出元オブジェクト
* @param logname:ログ名称
* @return 準備済みのLogger
*/
public static Logger setupLog(Object obj, String logname) {
try {
// Loggerキャッシュなし?
if( null==logger_map ) logger_map = new HashMap();
// 作成済みであればそれを返す
if( null!=logger_map.get(logname) ) return (Logger)logger_map.get(logname);
// CommonsのLog取得
Log log = LogFactory.getLog(obj.getClass());
// Log4Jを利用しているかチェック
if(log instanceof org.apache.commons.logging.impl.Log4JLogger){
//log.debug("Log4Jです log="+log);
try{
// DefaultのLogger取得
Logger nlogger = Logger.getLogger("DefaultLogger");
//log.debug("nlogger="+nlogger);
// デフォルトのAppenderを取得
// コンソール用
Appender A1 = nlogger.getAppender("A1");
// ファイル出力用
RollingFileAppender A2 = (RollingFileAppender) nlogger.getAppender("A2");
// 対象ファイル用のAppenderを新規作成
RollingFileAppender rfapd = new RollingFileAppender();
// デフォルトのAppenderオプション設定
rfapd.setMaximumFileSize(A2.getMaximumFileSize());
rfapd.setMaxBackupIndex(A2.getMaxBackupIndex());
rfapd.setAppend(A2.getAppend());
rfapd.setLayout(A2.getLayout());
// 出力先設定
rfapd.setFile(Param.getInstance().log_path + logname + ".log");
// オプションを有効化
rfapd.activateOptions();
// 対象Loggerを作成
Logger obj_logger = (Logger) Logger.getInstance(obj.getClass());
// ログ出力レベルを設定
obj_logger.setLevel(nlogger.getLevel());
// Appenderを追加
obj_logger.addAppender(A1);
obj_logger.addAppender(rfapd);
//log.info("setupLog: ログ出力先設定完了: "+Param.getInstance().log_path + logname + ".log");
// ヘッダを出力
String sep = System.getProperty("line.separator");
obj_logger.info(sep + sep + "<< ログ出力開始[" + Param.getInstance().log_path + logname + ".log" + "]>>");
// Loggerをキャッシュする
logger_map.put(logname,obj_logger);
// Log4JのLoggerをreturn(正常)
return obj_logger;
}catch(Exception ee){
System.out.println("エラー: ログが出力できません: log4j.propertiesがCLASSPATH上に見つかりません");
ee.printStackTrace();
}
}
} catch (Exception e) {
System.out.println("エラー: ログが出力できません: その他のエラー: "+e.toString());
e.printStackTrace();
}
//System.out.println("仮のLoggerを新規作成");
Logger logger = Logger.getLogger(obj.getClass());
return logger;
}
--------------------------------------------------------------------------------
LoggerはCategoryを継承しているので以上のような実現方法でも問題ないでしょうか?
またこの時、任意作成したLoggerをキャッシュして再利用するようにしているのですが、
log4jがスレッドセーフであるので共通関数で排他処理は実施していません。
|
|