Abh*_*h.M 4 java logging log4j logback slf4j
我有一个要求,其中我需要创建日志文件,以便基于标签(最好是文本)的所有日志都需要记录到相应的日志文件中。
例如,
我有关于苹果、橙子和芒果的日志。
logger.info("Apples: They are red in color");
logger.info("Oranges: They are orange in color");
logger.info("Mangoes: They are yellowish in color");
Run Code Online (Sandbox Code Playgroud)
根据我的要求,第一个日志应记录到Apples.log,第二个日志记录到Oranges.log,第三个日志记录到Mangoes.log
日志文件应该动态创建。
下面显示的是我的logback.xml文件
<statusListener class="ch.qos.logback.core.status.NopStatusListener"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<Pattern>
%d %-5p - %marker%m%n
</Pattern>
</encoder>
</appender>
<appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator>
<key>fruitName</key>
<defaultValue>Common_logs</defaultValue>
</discriminator>
<sift>
<appender name="FILE-${instanceName}" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>./Logs/${fruitName}/${instanceName}.log</fileNamePattern>
<maxHistory>50</maxHistory>
<cleanHistoryOnStart>false</cleanHistoryOnStart>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d %-5p - %m%n</pattern>
</encoder>
</appender>
</sift>
</appender>
<logger name="AssetInstanceService" level="info" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
<appender-ref ref="SIFT" />
</logger>
<root level="info">
<appender-ref ref="SIFT" />
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</root>
</configuration>
Run Code Online (Sandbox Code Playgroud)
下面给出的是我的LogManager.java文件
package Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.core.joran.spi.JoranException;
public class LogManager {
static String configFile = "./logback.xml";
private static Logger _logger = LoggerFactory.getLogger(LogManager.class);
private static boolean _isInitialized = false;
private LogManager() {
}
public static Logger Instance() {
if (_logger == null) {
_logger = LoggerFactory.getLogger(LogManager.class);
}
return _logger;
}
public static Logger Instance(String instanceName) {
if (!_isInitialized) {
if (!CommonMethods.CheckFileExist(configFile)) {
configFile = "../logback.xml";
if (!CommonMethods.CheckFileExist(configFile)) {
return null;
}
}
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
JoranConfigurator configurator = new JoranConfigurator();
lc.reset();
configurator.setContext(lc);
try {
configurator.doConfigure(configFile);
MDC.put("fruitName", instanceName);
} catch (JoranException e) {
System.out.println(e);
}
_isInitialized = true;
}
if (_logger == null) {
_logger = LoggerFactory.getLogger(LogManager.class);
}
return _logger;
}
}
Run Code Online (Sandbox Code Playgroud)
这里,当我在 main 方法中初始化记录器时运行 jar 文件时,会创建我的日志。
但我的需要是根据日志中的标签或 id 使用不同的名称创建不同的日志文件。
SLF4J 和 Log4j-API 都提供标记来完成您想要的操作。在 SLF4J 中,您可以使用以下命令创建标记:
\n\nMarker apples = MarkerFactory.getMarker("Apples");\nMarker oranges = MarkerFactory.getMarker("Oranges");\nMarker mangos = MarkerFactory.getMarker("Mangos");\n
Run Code Online (Sandbox Code Playgroud)\n\n此外,标记可以有一个父级,因此您可以执行以下操作:
\n\nMarker fruit = MarkerFactory.getMarker("Fruit");\nMarker apples = MarkerFactory.getMarker("Apples");\napples.add(fruit);\nMarker oranges = MarkerFactory.getMarker("Oranges");\napples.add(fruit);\nMarker mangos = MarkerFactory.getMarker("Mangos");\napples.add(fruit);\n
Run Code Online (Sandbox Code Playgroud)\n\n在配置中,您可以检查特定标记,或者如果您想检查属于水果的所有标记,则可以检查该标记。
\n\n然后,您可以在应用程序中使用这些标记:
\n\nlogger.info(apples, "They are red in color");\nlogger.info(oranges, "They are orange in color");\nlogger.info(mangoes, "They are yellowish in color");\n
Run Code Online (Sandbox Code Playgroud)\n\n最后,在您的配置中,您可以使用涡轮过滤器来执行以下操作:
\n\n <turboFilter class="ch.qos.logback.classic.turbo.MarkerFilter">\n <Marker>Apples</Marker>\n <OnMatch>NEUTRAL</OnMatch>\n <OnMismatch>DENY</OnMismatch>\n </turboFilter>\n
Run Code Online (Sandbox Code Playgroud)\n\n在全局级别进行过滤,或者您可以使用评估器过滤器之一在 Appender 上进行过滤。如果您编写自定义鉴别器,您还可以使用SiftingAppender动态创建 Appender。
\n\n使用 Log4j API 会使事情变得更容易一些。要创建没有父级的标记:
\n\nMarker apples = MarkerManager.getMarker("Apples");\nMarker oranges = MarkerManager.getMarker("Oranges");\nMarker mangos = MarkerManager.getMarker("Mangos");\n
Run Code Online (Sandbox Code Playgroud)\n\n或与家长一起:
\n\nMarker fruit = MarkerManager.getMarker("Fruit");\nMarker apples = MarkerManager.getMarker("Apples").setParents(fruit);\nMarker oranges = MarkerManager.getMarker("Oranges").setParents(fruit);\nMarker mangos = MarkerManager.getMarker("Mangos").setParents(fruit);\n
Run Code Online (Sandbox Code Playgroud)\n\n在 Log4j 中使用它们的代码完全相同:
\n\nlogger.info(apples, "They are red in color");\nlogger.info(oranges, "They are orange in color");\nlogger.info(mangoes, "They are yellowish in color");\n
Run Code Online (Sandbox Code Playgroud)\n\n最大的区别在于配置。Log4j 只有一种 Filter,它可以在全局级别(如 Turbo Filter)或 Logger、Appender 引用或 Appender 上使用。在您的情况下,您需要使用MarkerFilter:
\n\n<MarkerFilter marker="Apples" onMatch="NEUTRAL" onMismatch="DENY"/>\n
Run Code Online (Sandbox Code Playgroud)\n\n并将其添加到每个 Appender 引用或每个 Appender。
\n\n与 SiftingAppender 类似,Log4j 也提供了RoutingAppender。它使用查找来确定如何执行路由。开箱即用的 Log4j 不提供从日志事件中检索数据的方法,但编写一个或向 Log4j 添加一个很简单,或者您可以使用脚本从事件中检索标记。
\n\n您应该意识到使用 MarkerFilters 会产生一些开销,尽管不多。这是在我的 MacBook Pro 上运行 4 个线程时 log4j-perf 模块的基准测试。即使在最坏的情况下,Logback 根据包含子标记的事件检查父标记,每次比较平均仍然只需要 17 纳秒。
\n\nBenchmark Mode Cnt Score Error Units\nMarkerFilterBenchmark.baseline avgt 10 2.412 \xc2\xb1 0.088 ns/op\nMarkerFilterBenchmark.log4jParentMarker avgt 10 8.337 \xc2\xb1 0.186 ns/op\nMarkerFilterBenchmark.log4jSimpleMarker avgt 10 8.043 \xc2\xb1 0.145 ns/op\nMarkerFilterBenchmark.log4jTooFine avgt 10 2.825 \xc2\xb1 0.281 ns/op\nMarkerFilterBenchmark.logbackParentMarker avgt 10 17.865 \xc2\xb1 0.533 ns/op\nMarkerFilterBenchmark.logbackSimpleMarker avgt 10 10.471 \xc2\xb1 0.089 ns/op\nMarkerFilterBenchmark.logbackTooFine avgt 10 4.255 \xc2\xb1 0.014 ns/op\n
Run Code Online (Sandbox Code Playgroud)\n\n最后的想法。Ceki Gulcu 在创建 SLF4J 时发明了标记的概念,他值得赞扬,因为这是一个奇妙的想法。
\n 归档时间: |
|
查看次数: |
8602 次 |
最近记录: |