我想在我的应用程序(Spring Integration)中有两个日志文件,debug.log和main.log。 我想在INFO级别运行main.log,在DEBUG级别运行debug.log。 这可以通过追加程序上的过滤器完成。 我想根据源将不同级别记录到附加程序。 换一种说法

总结一下:

弹簧记录器

主要->错误

调试->调试

com.myapp记录器

主要->信息

调试->调试

因此,我必须使记录器在DEBUG上运行,并且追加器上的阈值过滤器不够精细。

更新为问题增加了清晰度

创建一个ThresholdLoggerFilter类,可以将其放置在附加器上,例如:

INFO
org.springframework
ERROR

以下代码有效

package com.myapp;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;
public class ThresholdLoggerFilter extends Filter {
private Level level;
private String logger;
@Override
public FilterReply decide(ILoggingEvent event) {
if (!isStarted()) {
return FilterReply.NEUTRAL;
}
if (!event.getLoggerName().startsWith(logger))
return FilterReply.NEUTRAL;
if (event.getLevel().isGreaterOrEqual(level)) {
return FilterReply.NEUTRAL;
} else {
return FilterReply.DENY;
}
}
public void setLevel(Level level) {
this.level = level;
}
public void setLogger(String logger) {
this.logger = logger;
}
public void start() {
if (this.level != null && this.logger != null) {
super.start();
}
}
}

简单干净的答案!! 这个例子非常适合我的需求!!!

无需自己实现,请使用ch.qos.logback.classic.filter.ThresholdFilter

ThresholdFilter仅对阈值进行过滤。 我想同时过滤记录器和阈值

@JohnOxley这是应该包含在登录中的功能! 您是否考虑过贡献?

我相信它原本打算使用正过滤器,所以如果(!event.getLoggerName()。startsWith(logger))return FilterReply.DENY;应该是这样。

Scala版本:gist.github.com/kushti/4b1f10030882413ed5a4

对于大多数用例," startsWith(logger)"就足够了,但并不完全正确。 例如,如果事件记录器名称为" com.examples",则配置的记录器" com.example"将错误地匹配。

如果您愿意从root记录器继承,也可以更简单地执行此操作,例如在这里,我们添加了一个额外的错误记录器,该记录器将记录到stderr。仅对特定的记录器启用。

System.out
%d %-5level [%thread] %logger{0}: %msg%n
ERROR
System.err
%d %-5level [%thread] %logger{0}: %msg%n

感谢@artbristol,但这不能给出我想要的控制粒度。 我已经更新了问题,请说明原因。

添加比这里已有的解决方案更简单的其他解决方案

这些解决方案都不适合我,因为我没有使用Spark或Spring这样的框架。所以我做了一些简单的事情,看起来似乎很好用。尽管此解决方案可能不适用于OP,但对于想要不那么笨重的东西的人来说可能有用。

/path/to/your/program.log
true
${pattern}
System.out
INFO
${pattern}

通过这种配置,我可以在将DEBUG语句输出到日志文件的同时保持控制台的整洁。

刚刚找到了一种使用logback元素的实用解决方案,该解决方案仅工作得很好,本质上,您需要有两个追加程序,一个带有默认配置,另一个带有过滤器(在我的示例中,我使用控制台):

%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
WARN
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
a threshold filter on an appender isn't fine grained enough

您可以使用EvaluatorFilter。 JaninoEventEvaluator将需要对janino(.jar)的引用,logback.xml示例将是:

INFO
level <= ERROR && logger.equals("com.myapp.ThresholdLoggerFilter")
DENY
NEUTRAL

此方法在expression标记中使用Java表达式(必须转义xml)来评估日志记录事件,并且不需要编写自定义Java类。

对不同的消息使用多个记录器将是这样的:

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
public class ConfigureLogBack
{
public static void programmaticConfiguration()
{
Logger camel = getLogger("MyRoute", C:\\Users\\amrut.malaji\\Desktop\\Oracle\\logback\\camel-Log.txt");
Logger services = getLogger("webservices","C:\\Users\\amrut.malaji\\Desktop\\Oracle\\logback\\services-log.txt");
}
private static Logger getLogger(String string, String file) {
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
PatternLayoutEncoder ple = new PatternLayoutEncoder();
ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n");
ple.setContext(lc);
ple.start();
FileAppender fileAppender = new FileAppender();
fileAppender.setFile(file);
fileAppender.setEncoder(ple);
fileAppender.setContext(lc);
fileAppender.start();
Logger logger = (Logger) LoggerFactory.getLogger(string);
logger.addAppender(fileAppender);
logger.setLevel(Level.INFO);
logger.setAdditive(false); /* set to true if root should log too */
return logger;
}