首先让我简单解释一下我正在使用的系统:
我们有一个作为守护进程运行的系统,在它们进入时运行工作单元。这个守护进程在给出一个新的工作单元时动态地创建一个新的Thread。对于这些工作单元中的每一个,我需要Log4J来创建要追加的新日志文件 - 必须在运行时提供文件名,此时必须创建新的日志文件。这个守护进程必须能够无限期地保持活着,我相信会引起一些记忆问题,正如我将要解释的那样。
我的第一个想法是为每个工作单元创建一个新的Logger,当然是在线程之后命名。工作单元的线程保留对该Logger的引用。当单元完成后,它将被垃圾收集,但问题是Log4J本身保留了对Logger的引用,这将永远不会再次使用。似乎所有这些记录器都会导致VM耗尽内存。
另一个解决方案:子类Filter,按线程名称过滤Appender,并将它们放在同一个Logger上。然后,在工作单元完成时删除Appender。当然,这需要添加代码来删除appender。这将是很多代码更改。
我研究过NDC和MDC,它们似乎是用来管理同一文件的交错输出。我已经考虑过将此作为一种解决方案,但我认为不会被接受。
我想说Log4J似乎是不以这种方式运行,也就是说,在运行时动态创建新的日志文件,因为它们是必需的(或需要的)。所以我不确定接下来要查看哪个方向 - 这里的log4j不是解决方案,还是我完全错过了什么?我对NDC的看法不够密切吗?或者我是否担心Log4J会因为我看不到的原因而将Loggers保留为Logiss?
答案 0 :(得分:0)
您可以创建一个包装正常日志方法的新日志方法,并附加线程ID。 像下面的东西(过于简单,但你明白了)。 Log4j已经是线程保存我相信,所以只要你没有记录吨,你应该没事。然后你可以轻松地在线程ID上进行grep。
public log(long id, String message)
{
logger.log("ThreadId: id + "message: " + message);
}
答案 1 :(得分:0)
ThreadLocal似乎是您的解决方案。