带有通配符的Logback记录器名称

pet*_*ory 7 logging logback

是否可以使用通配符作为匹配不同包的记录器名称,因此我们不必单独指定它们?所以不要写作

<logger name="com.package1.web" level="debug"   
<logger name="com.package2.web" level="debug"  
<logger name="com.package3.web" level="debug"  
Run Code Online (Sandbox Code Playgroud)

我只想指定一个类似这样的条目:

<logger name="com.*.web" level="debug"  
Run Code Online (Sandbox Code Playgroud)

如果有人知道某种方式,或者只是因为它不可能我非常欣赏它

gly*_*ing 7

TL; DR

Logback不支持记录器名称中间级的通配符。

详情

Logback(隐式)在记录器名称的末尾支持通配符,因此<logger name="com.package1.web" ...>有效表示:

  • 的任何子包中com.package1.web 中的类com.package1.web

Logback通过创建记录器的层次结构来做到这一点;为记录器com.package1.web通过记录器父为com.package1这是由记录器对父com其中由是父ROOT记录器。

因此,如果您声明<logger name="com.package1.web" level="debug">并尝试在com.package1.web.foo.barLogback 上为记录器发出调试日志消息,它将沿该记录器的层次结构前进,直到找到DEBUG启用了该级别的记录器为止,它将在此找到com.package1.web并因此将发出DEBUG日志事件。

但是,Logback不会在记录器名称的中间级别基于通配符创建层次结构。所以这 ...

<logger name="com.*.web" level="debug">
Run Code Online (Sandbox Code Playgroud)

...将不会导致Logback创建以下记录器:

  • com.package1.web
  • com.package2.web
  • com.package3.web

当通配符出现在记录器名称的中间级别时,将不应用Logback的层次结构行为。

可能的解决方案

这种层次结构行为的一个好处是,它允许您将记录器配置应用于程序包和该程序包下的所有类,即,它基于记录器实例的关联在记录器实例之间创建关联。您可以通过提供一个明确的记录器名称来建立这种关联,而不是将其默认为当前的类名称。

例如:

<logger name="DEBUG_LOGGER" level="debug">
Run Code Online (Sandbox Code Playgroud)

然后,要使用调试记录器的任何地方都只需创建一个Logger实例,如下所示:

private final Logger logger = LoggerFactory.getLogger("DEBUG_LOGGER");
Run Code Online (Sandbox Code Playgroud)

显然,这种方法也有弊端,我在这里仅提及它是为了表明还有另一种方式(除了完全限定的类名)来关联记录器实例并为其应用级别。


ris*_*kop 6

您可以使用appender中的Filters执行此操作.基本上你必须为DEBUG级别的"com.*"设置一个记录器,并应用一个DENY所有DEBUG(或爱人)事件的过滤器,这些事件不是"com.*.web".

我承认它很复杂.

在性能方面,它也很差:为所有 "com.*"事件创建调试事件,并且只在它们被抛弃或保留的appender上创建.

无论如何,示例logback.xml:

<configuration scan="true" debug="true">
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <filter class="ch.qos.logback.core.filter.EvaluatorFilter">
            <evaluator class="ch.qos.logback.classic.boolex.GEventEvaluator">
                <expression>
                    !(e.loggerName ==~ "com\\..*\\.web") &amp;&amp;
                    DEBUG.toInt() >= e.level.toInt()
                </expression>
            </evaluator>
            <OnMismatch>NEUTRAL</OnMismatch>
            <OnMatch>DENY</OnMatch>
        </filter>
        <encoder>
            <pattern>%p [%d{HH:mm:ss,SSS}] %c - %m\n</pattern>
        </encoder>
    </appender>

    <logger name="com" level="DEBUG" />

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
    </root>
</configuration>
Run Code Online (Sandbox Code Playgroud)

测试代码:

public void test() throws Exception{
    getLogger("com.package1.web").debug("some debug onto com.package1.web");
    getLogger("com.package2.web").debug("some debug onto com.package2.web");
    getLogger("com.package3.web").debug("some debug onto com.package3.web");
    getLogger("com.package1.web").info("some info onto com.package1.web");
    getLogger("com.package2.web").info("some info onto com.package2.web");
    getLogger("com.package3.web").info("some info onto com.package3.web");
    getLogger("com.package3.notweb").debug("some debug onto com.package3.notweb");
    getLogger("com.package3.notweb").info("some info onto com.package3.notweb");
}

public Logger getLogger(String loggerName) {
    return LoggerFactory.getLogger(loggerName);
}
Run Code Online (Sandbox Code Playgroud)

结果:

DEBUG [12:30:46] com.package1.web - some debug onto com.package1.web
DEBUG [12:30:46] com.package2.web - some debug onto com.package2.web
DEBUG [12:30:46] com.package3.web - some debug onto com.package3.web
INFO [12:30:46] com.package1.web - some info onto com.package1.web
INFO [12:30:46] com.package2.web - some info onto com.package2.web
INFO [12:30:46] com.package3.web - some info onto com.package3.web
INFO [12:30:46] com.package3.notweb - some info onto com.package3.notweb
Run Code Online (Sandbox Code Playgroud)

如您所见,调试日志仅针对"com.*.web"编写