我有一个应用程序,其中有许多ejb计时器方法,这些方法在不同的时间间隔触发,为了记录这些计划任务的性能,我编写了两个方法,记录每个任务的开始和结束,并记录一些信息,如名称、运行持续时间和每次触发计时器时的日志信息
使用日志信息的目的是截获从这些方法中引发的所有日志记录语句,输出到字符串并保存......我通过创建一个新的WriterAppender来实现这一点,为所有日志记录级别将其附加到Logger,然后在计时器完成时捕获字符串输出并删除appender
这样做效果很好,但似乎有两个不想要的效果:
1)它停止了出现在我们的普通文件附加器日志中的来自定时器类的任何日志记录,例如,日志消息被捕获,但它们现在不出现在我们的普通日志中(配置为显示所有内容〉INFO
2)来自不同计时器的日志语句重叠出现在彼此的日志中,我猜这是Logger在单个线程上工作的结果,不确定是否有解决这个问题的方法?
我不是log4j方面的Maven,所以我希望有人能指出一个简单的修复1、2或两者的方法
下面的代码显示了在每个作业开始和结束时调用的两个方法
private Writer w = new StringWriter();
private WriterAppender wa;
private Logger logOutput = Logger.getLogger(ScheduledActions.class);
private TimerEvent logStartTimerEvent(ScheduledTask task){
RedisActions redisActions = (RedisActions)Component.getInstance("redisActions");
TimerEvent event = new TimerEvent(task);
//Initialise a new log appender to intercept all log4j entries
w = new StringWriter();
Layout l = new PatternLayout("%m%n");
wa = new WriterAppender(l, w);
wa.setEncoding("UTF-8");
wa.setThreshold(Level.ALL);
wa.activateOptions();
// Add it to logger
logOutput = Logger.getLogger(ScheduledActions.class);
logOutput.addAppender(wa);
//Push this timer event to redis
redisActions.addToFixedLengthList(RedisItem.TIMER_HISTORY.getKey()+"_"+task.getName(), gson.toJson(event), 100L);
return event;
}
private void logEndTimerEvent(TimerEvent event){
try{
RedisActions redisActions = (RedisActions)Component.getInstance("redisActions");
event.setLogInfo(w.toString());
event.setEndTime(new Date());
redisActions.editLastMemberInList(RedisItem.TIMER_HISTORY.getKey()+"_"+event.getTask().getName(), gson.toJson(event));
w.flush();
} catch (IOException e) {
e.printStackTrace();
}finally{
//clean up the temp log appender
logOutput.removeAppender(wa);
wa.close();
}
}
3条答案
按热度按时间jjjwad0x1#
我在尝试做类似的事情时发现了这个老问题。现在,我的解决方案是创建一个独立的记录器/追加器,带有一个唯一的
loggerId
,如下所示:我遇到的问题是我需要传递这个
logger
变量,我不能使用经典的“静态记录器”。amrnrhlw2#
我正在考虑的另一个解决方案是向
rootLogger
添加一个AbstractAppender
,然后从那里对日志进行任何操作。我会更新这个答案,当我开发它多一点。
5t7ly7z53#
我的最终解决方案是将
Appender
与ThreadContextMapFilter
相加。