我的团队正在开发一种具有高每秒呼叫率的电信实时应用。 我们正在使用logback根据键值匹配(流量实时值,如主叫方等)过滤日志。正确创建过滤后的日志文件,一旦验证了实时值和db值的匹配,但是我们将摆脱默认文件,当没有匹配时填充日志。可能会发生在发生键值匹配之前需要监视流量节点一段时间,因此同时默认值可能会无限增加并导致节点本身的性能和稳定性出现问题。 我应该在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>
ATTACHMENTS:FILTERED LOGBACK CLASS
提供的FL类仅适用于在FL模块中具有java Discriminator的SK。
答案 0 :(得分:1)
您必须将过滤器移至常规的筛选附加程序。
<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>
为使其正常工作,还必须在每个线程/文件/标记/等之后。把这些陈述:
public void handle()
{
MDC.put("loggerFileName","some value");
...
MDC.remove("loggerFileName");
}
答案 1 :(得分:0)
您已定义此根记录器:
<root level="DEBUG">
<appender-ref ref="SIFT_LOGGER" />
<appender-ref ref="STDOUT" />
</root>
这意味着具有Level&gt; = DEBUG的所有日志事件将定向到两个appender:
SIFT_LOGGER
STDOUT
如果我正确理解了您的问题,那么执行希望通过SIFT_APPENDER
写入日志,但您不希望任何其他日志输出。如果是这样,那么只需删除此条目:
<appender-ref ref="STDOUT" />
STDOUT
appender是一个控制台appender,因此它实际上不会写入日志文件而是写入System.out
。我怀疑您在某些文件中看到这些日志事件的原因是,运行您的应用程序的任何内容都是将System.out
重定向到文件。只要您在根记录器定义中只有SIFT_APPENDER
,那么您可以确信这将是唯一正在使用的追加者。注意:从根记录器中删除appender后,可以将其从logback.xml中删除,因为它未被使用。
更新1:根据您的上一条评论我现在明白您要丢弃到达SiftingAppender但与给定条件不匹配的日志。我怀疑这里发生的事情是,某些日志事件到达筛选appender并且serviceKey
具有“未知”值,然后这些事件被写入/var/log/tit/logback_[unknownValue]_%d{yyyy-MM-dd}_%i.log
。这是问题的关键吗?如果是这样,那么您可以在嵌套的appender中添加一个过滤器。以下是一些例子:
使用Groovy表达'包含未知的serviceKey条件':
<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表示'包含未知的serviceKey条件':
<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>
使用这些过滤器中的任何一个,将忽略任何到达筛选追加器并具有“未知”serviceKey
的日志事件。注意:我已将'包含未知的serviceKey条件'写为serviceKey == null
,您的逻辑可能会有所不同,但上面的示例显示了如何告诉Logback为您应用此过滤器。
答案 2 :(得分:0)
只是通知@glitch(以及所有其他感兴趣的人)这个问题的快乐结论:我设法使标签表达工作是这样的:
<expression>mdc.get("servicekey") == null</expression>
感谢这个表达式,我得到了想要的行为:当密钥与运行时流量值不匹配时,不会生成默认文件“ IS_UNDEFINED 。”
原因是因为JaninoEventEvaluator中的Event类型是LoggingEvent,它有一个保留对象“mdc”(类型是Map)。
此致 皮耶路易吉