排除默认的 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>

附件:FILTERED LOGBACK CLASS

所提供的 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");
}