我有一个可同时运行的代码,每次运行都需要在文件中记录一些内容。每次执行-具有唯一文件的新故事。
因此,我不能只获取记录器的类名,添加文件附加器,写入日志,关闭和删除附加器,因为运行并发代码时-记录器将包含两个附加器,并且日志将被写入两个文件。 / p>
因此,我可以为每个执行Logger.getLogger(classname + counter)创建一个新的记录器实例,但是工作完成后如何将其标记为垃圾?
P.S。而且...我需要打印一些thimeths才能从所有记录器中获得安慰。
也许我做错了,也许没有为此模式创建log4j,但我必须实现它。但是log4j-优先级为我选择,因为它已在此大型应用程序中广泛使用。
提前谢谢您,安德烈!
答案 0 :(得分:0)
You can't销毁/清理Appender实例。但是您可以使用Log4j2工具箱改进解决方案。
可以将内容路由到Log4j中的动态文件,但是大多数情况下,文件中的Marker
足够了,或者至少是更复杂路由的起点。
请仔细阅读其documentation。特别是最后一段对您的情况很重要:
使用标记时必须考虑一些重要的规则。
- 标记必须唯一。它们是通过名称永久注册的,因此应小心确保您的应用程序中使用的标记与应用程序的依赖项中的标记不同,除非需要这样做。
- 父标记可以动态添加或删除。但是,这样做相当昂贵。相反,建议如上例所示,在首次获得标记时识别父母。具体来说,set方法一次可以替换所有标记,而一次只能对单个标记进行添加和删除操作。
- 评估具有多个祖先的标记比没有父母的标记要昂贵得多。例如,在一组评估标记是否与其祖父母相匹配的测试中,其花费是评估标记本身的3倍。即使如此,与解析呼叫者的班级名称或行号相比,评估Markers还是便宜的。
然后,您可以在配置中使用标记,例如$${marker:}
。我没有在文件名中使用它,并且怀疑它是否有效,但是您可以基于create routing the Marker。
我使用了这个简单的测试脚本,请注意使用为扫描器中的每一行创建的Marker
。在您的情况下,它可以通过config或从Servlet输入或类似的容器中创建。
package toTest;
import java.util.Scanner;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
public class TestMe {
private final Logger myOneAndOnlyLogger = LogManager.getLogger("MyCentralName");
public static void main(String[] args) {
new TestMe().doMyThing();
}
private void doMyThing() {
Scanner input = new Scanner(System.in);
String line = "";
while(!line.equals("QUIT")) {
System.out.println("Line: ");
line = input.nextLine();
Marker forThisRound = MarkerManager.getMarker(line);
myOneAndOnlyLogger.log(Level.ERROR, forThisRound, "1");
myOneAndOnlyLogger.log(Level.ERROR, forThisRound, "2");
System.out.println("Line done.");
}
}
}
和这个log4j2.properties
(我手头上有一个滚动文件的示例,在模式中带有标记):
status = error
name = MarkerExample
#Make sure to change log file path as per your need
property.filename = /tmp/java/marker.log
filters = threshold
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appenders = rolling
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = /tmp/java/debug-backup-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} $${marker:} %-5p %c{1}:%L - %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=10MBONE
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 20
loggers = rolling
#Make sure to change the package structure as per your application
logger.rolling.name = MyCentralName
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile