排除默认的 logback 文件
Exclude default logback file
我的团队正在开发一个每秒调用率很高的电信实时应用程序。 我们使用 logback 根据键值匹配过滤日志(流量实时值,如主叫方等)。过滤后的日志文件已正确创建,一旦验证了实时值和数据库值的匹配,但是 我们将删除在没有匹配时充满日志的默认文件 。可能会发生在键值匹配发生之前需要监视流量节点一段时间的情况,因此与此同时,默认值可能会无限增加,并导致节点本身的性能和稳定性出现问题。 我应该在 logback.xml 中做什么来避免生成默认日志文件? 这可能吗?还有其他选择可以达到相同的结果吗?
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<property scope="context" name="LOG_LEVEL" value="INFO" />
<appender name="SIFT_LOGGER" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator class="com.ericsson.jee.ngin.services.log.ServiceKeyDiscriminator">
</discriminator>
<sift>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/var/log/tit/logback_${serviceKey}_%d{yyyy-MM-dd}_%i.log</fileNamePattern>
<maxFileSize>1MB</maxFileSize>
<maxHistory>10</maxHistory>
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>${LOG_LEVEL}</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern> %d{yyyy-MM-dd HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} %msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern> %d{yyyy-MM-dd HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} %msg%n</pattern>
</encoder>
</appender>
<turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter">
<key>serviceKey</key>
<defaultThreshold>DEBUG</defaultThreshold>
<onHigherOrEqual>ACCEPT</onHigherOrEqual>
<onLower>ACCEPT</onLower>
</turboFilter>
<root level="DEBUG">
<appender-ref ref="SIFT_LOGGER" />
<appender-ref ref="STDOUT" />
</root>
所提供的 FL class 仅适用于在 FL 模块中具有 java 鉴别器的 SK。
您已定义此根记录器:
<root level="DEBUG">
<appender-ref ref="SIFT_LOGGER" />
<appender-ref ref="STDOUT" />
</root>
这意味着 所有 级别 >= DEBUG 的日志事件将被定向到两个附加程序:
SIFT_LOGGER
STDOUT
如果我对你的问题的理解正确,那么你确实想要通过你的SIFT_APPENDER
写入日志,但你不想要任何其他日志输出。如果是这样,则只需删除此条目:
<appender-ref ref="STDOUT" />
STDOUT
附加程序是一个控制台附加程序,因此它实际上并不写入日志文件,而是写入 System.out
。我怀疑您在 some 文件中看到这些日志事件的原因是无论 运行 是什么,您的应用程序都将 System.out
重定向到一个文件。只要您在根记录器定义中只有 SIFT_APPENDER
,那么您就可以确信这将是唯一的附加程序。注意:一旦您从根记录器中删除了附加程序,您就可以从 logback.xml 中删除它,因为它未被使用。
更新 1: 根据您最后的评论,我现在了解到您想丢弃到达 SiftingAppender 但不符合给定条件的日志。我怀疑这里发生的事情是一些日志事件到达筛选附加程序时带有 serviceKey
的 'unknown' 值,然后这些事件被写入 /var/log/tit/logback_[unknownValue]_%d{yyyy-MM-dd}_%i.log
。这是问题的关键吗?如果是这样,那么您可以将过滤器添加到嵌套的附加程序中。以下是一些示例:
用Groovy表示'contains unknown serviceKey condition':
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<!-- GEventEvaluator requires Groovy -->
<evaluator
class="ch.qos.logback.classic.boolex.GEventEvaluator">
<expression>
serviceKey == null
</expression>
</evaluator>
<OnMismatch>NEUTRAL</OnMismatch>
<OnMatch>DENY</OnMatch>
</filter>
用Janino表达'contains unknown serviceKey condition':
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<!-- JaninoEventEvaluator requires Janino -->
<evaluator
class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>
serviceKey == null
</expression>
</evaluator>
<OnMismatch>NEUTRAL</OnMismatch>
<OnMatch>DENY</OnMatch>
</filter>
使用这些过滤器中的任何一个,任何到达筛选附加程序并具有 'unknown' serviceKey
的日志事件都将被忽略。注意:我将 'contains unknown serviceKey condition' 写为 serviceKey == null
您的逻辑可能有所不同,但上面的示例显示了您应该如何告诉 Logback 为您应用此过滤器。
只是为了通知@glitch(和所有其他感兴趣的人)这个问题的愉快结论:我已经设法使标签表达式工作是这样的:
<expression>mdc.get("servicekey") == null</expression>
多亏了这个表达式,我得到了想要的行为:当密钥与运行时流量不匹配时,不会生成默认文件“IS_UNDEFINED值。
原因是因为JaninoEventEvaluator中Event的类型是LoggingEvent,有一个reserve对象"mdc"(类型是Map)
此致,
皮尔路易吉
您必须将过滤器移动到通用筛选器。
<appender name="SIFT-TRACE"
class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator
class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
<Key>loggerFileName</Key>
<DefaultValue>unknown</DefaultValue>
</discriminator>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator
class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>
mdc.get("loggerFileName")!=null
</expression>
</evaluator>
<OnMismatch>DENY</OnMismatch>
<OnMatch>NEUTRAL</OnMatch>
</filter>
<sift>
<appender name="TRACE-${loggerFileName}"
class="ch.qos.logback.core.FileAppender">
<File>D:/U/${loggerFileName}.log</File>
<Append>true</Append>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d [%thread] %level %mdc %logger - %msg%n</Pattern>
</layout>
</appender>
</sift>
</appender>
<logger name="org.springframework" level="DEBUG" />
<root level="DEBUG">
<appender-ref ref="SIFT-TRACE" />
</root>
另外,为了使其正常工作,您必须在每个 Thread/file/marker/etc 之后。放置这些语句:
public void handle()
{
MDC.put("loggerFileName","some value");
...
MDC.remove("loggerFileName");
}
我的团队正在开发一个每秒调用率很高的电信实时应用程序。 我们使用 logback 根据键值匹配过滤日志(流量实时值,如主叫方等)。过滤后的日志文件已正确创建,一旦验证了实时值和数据库值的匹配,但是 我们将删除在没有匹配时充满日志的默认文件 。可能会发生在键值匹配发生之前需要监视流量节点一段时间的情况,因此与此同时,默认值可能会无限增加,并导致节点本身的性能和稳定性出现问题。 我应该在 logback.xml 中做什么来避免生成默认日志文件? 这可能吗?还有其他选择可以达到相同的结果吗?
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<property scope="context" name="LOG_LEVEL" value="INFO" />
<appender name="SIFT_LOGGER" class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator class="com.ericsson.jee.ngin.services.log.ServiceKeyDiscriminator">
</discriminator>
<sift>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<prudent>true</prudent>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/var/log/tit/logback_${serviceKey}_%d{yyyy-MM-dd}_%i.log</fileNamePattern>
<maxFileSize>1MB</maxFileSize>
<maxHistory>10</maxHistory>
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>${LOG_LEVEL}</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern> %d{yyyy-MM-dd HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} %msg%n</pattern>
</encoder>
</appender>
</sift>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are by default assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern> %d{yyyy-MM-dd HH:mm:ss.SSSZ} [%thread] %-5level %logger{36} %msg%n</pattern>
</encoder>
</appender>
<turboFilter class="ch.qos.logback.classic.turbo.DynamicThresholdFilter">
<key>serviceKey</key>
<defaultThreshold>DEBUG</defaultThreshold>
<onHigherOrEqual>ACCEPT</onHigherOrEqual>
<onLower>ACCEPT</onLower>
</turboFilter>
<root level="DEBUG">
<appender-ref ref="SIFT_LOGGER" />
<appender-ref ref="STDOUT" />
</root>
所提供的 FL class 仅适用于在 FL 模块中具有 java 鉴别器的 SK。
您已定义此根记录器:
<root level="DEBUG">
<appender-ref ref="SIFT_LOGGER" />
<appender-ref ref="STDOUT" />
</root>
这意味着 所有 级别 >= DEBUG 的日志事件将被定向到两个附加程序:
SIFT_LOGGER
STDOUT
如果我对你的问题的理解正确,那么你确实想要通过你的SIFT_APPENDER
写入日志,但你不想要任何其他日志输出。如果是这样,则只需删除此条目:
<appender-ref ref="STDOUT" />
STDOUT
附加程序是一个控制台附加程序,因此它实际上并不写入日志文件,而是写入 System.out
。我怀疑您在 some 文件中看到这些日志事件的原因是无论 运行 是什么,您的应用程序都将 System.out
重定向到一个文件。只要您在根记录器定义中只有 SIFT_APPENDER
,那么您就可以确信这将是唯一的附加程序。注意:一旦您从根记录器中删除了附加程序,您就可以从 logback.xml 中删除它,因为它未被使用。
更新 1: 根据您最后的评论,我现在了解到您想丢弃到达 SiftingAppender 但不符合给定条件的日志。我怀疑这里发生的事情是一些日志事件到达筛选附加程序时带有 serviceKey
的 'unknown' 值,然后这些事件被写入 /var/log/tit/logback_[unknownValue]_%d{yyyy-MM-dd}_%i.log
。这是问题的关键吗?如果是这样,那么您可以将过滤器添加到嵌套的附加程序中。以下是一些示例:
用Groovy表示'contains unknown serviceKey condition':
<filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <!-- GEventEvaluator requires Groovy --> <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator"> <expression> serviceKey == null </expression> </evaluator> <OnMismatch>NEUTRAL</OnMismatch> <OnMatch>DENY</OnMatch> </filter>
用Janino表达'contains unknown serviceKey condition':
<filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <!-- JaninoEventEvaluator requires Janino --> <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator"> <expression> serviceKey == null </expression> </evaluator> <OnMismatch>NEUTRAL</OnMismatch> <OnMatch>DENY</OnMatch> </filter>
使用这些过滤器中的任何一个,任何到达筛选附加程序并具有 'unknown' serviceKey
的日志事件都将被忽略。注意:我将 'contains unknown serviceKey condition' 写为 serviceKey == null
您的逻辑可能有所不同,但上面的示例显示了您应该如何告诉 Logback 为您应用此过滤器。
只是为了通知@glitch(和所有其他感兴趣的人)这个问题的愉快结论:我已经设法使标签表达式工作是这样的:
<expression>mdc.get("servicekey") == null</expression>
多亏了这个表达式,我得到了想要的行为:当密钥与运行时流量不匹配时,不会生成默认文件“IS_UNDEFINED值。
原因是因为JaninoEventEvaluator中Event的类型是LoggingEvent,有一个reserve对象"mdc"(类型是Map)
此致, 皮尔路易吉
您必须将过滤器移动到通用筛选器。
<appender name="SIFT-TRACE"
class="ch.qos.logback.classic.sift.SiftingAppender">
<discriminator
class="ch.qos.logback.classic.sift.MDCBasedDiscriminator">
<Key>loggerFileName</Key>
<DefaultValue>unknown</DefaultValue>
</discriminator>
<filter class="ch.qos.logback.core.filter.EvaluatorFilter">
<evaluator
class="ch.qos.logback.classic.boolex.JaninoEventEvaluator">
<expression>
mdc.get("loggerFileName")!=null
</expression>
</evaluator>
<OnMismatch>DENY</OnMismatch>
<OnMatch>NEUTRAL</OnMatch>
</filter>
<sift>
<appender name="TRACE-${loggerFileName}"
class="ch.qos.logback.core.FileAppender">
<File>D:/U/${loggerFileName}.log</File>
<Append>true</Append>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d [%thread] %level %mdc %logger - %msg%n</Pattern>
</layout>
</appender>
</sift>
</appender>
<logger name="org.springframework" level="DEBUG" />
<root level="DEBUG">
<appender-ref ref="SIFT-TRACE" />
</root>
另外,为了使其正常工作,您必须在每个 Thread/file/marker/etc 之后。放置这些语句:
public void handle()
{
MDC.put("loggerFileName","some value");
...
MDC.remove("loggerFileName");
}