如何"filter" Akka INFO logging输出到不同的文件?

how to "filter" Akka INFO logging output to different files?

我在 "orders" 上记录信息,在 "transactions" 上记录信息,这些信息由我使用 Scala/Akka 开发的交易应用程序生成。目前所有输出都进入一个日志文件,但我希望信息进入单独的文件。

我已经指定我的 application.conf 如下...

akka {
  loggers = ["akka.event.slf4j.Slf4jLogger"]
  loglevel = "INFO"
  logging-filter = "akka.event.slf4j.Slf4jLoggingFilter"
}

...这是我的 logback.xml 文件...

<configuration>
    <appender name="TRANSACTIONS" class="ch.qos.logback.core.FileAppender">
        <file>log/transactions.log</file>
        <append>true</append>
        <encoder>
            <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="TRANSACTIONS" />
    </root>

    <appender name="ORDERS" class="ch.qos.logback.core.FileAppender">
        <file>log/orders.log</file>
        <append>true</append>
        <encoder>
            <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="ORDERS" />
    </root>
</configuration>

我已尝试修改我的 logback.xml 文件以包含如下过滤器

<configuration>
    <appender name="TRANSACTIONS" class="ch.qos.logback.core.FileAppender">
        <filter class="domain.trading.DoubleAuctionMarket"/>
        <file>log/transactions.log</file>
        <append>true</append>
        <encoder>
            <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="TRANSACTIONS" />
    </root>

    <appender name="ORDERS" class="ch.qos.logback.core.FileAppender">
        <filter class="domain.trading.Exchange"/>
        <file>log/orders.log</file>
        <append>true</append>
        <encoder>
            <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="ORDERS" />
    </root>
</configuration>

但是,这会产生运行时错误...

14:11:38,361 |-ERROR in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Could not create component [filter] of type [domain.trading.DoubleAuctionMarket] java.lang.ClassNotFoundException: domain.trading.DoubleAuctionMarket
at java.lang.ClassNotFoundException: domain.trading.DoubleAuctionMarket

14:11:38,417 |-ERROR in ch.qos.logback.core.joran.action.NestedComplexPropertyIA - Could not create component [filter] of type [domain.trading.Exchange] java.lang.ClassNotFoundException: domain.trading.Exchange
at java.lang.ClassNotFoundException: domain.trading.Exchange

想法?

[编辑:解决方案] 为了完整起见,我根据下面答案中提供的 link 创建了两个过滤器 TransactionsFilterOrdersFilter并将它们放在我项目的 src/main/java/ 目录中。示例过滤器看起来像...

package filters;

import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.filter.Filter;
import ch.qos.logback.core.spi.FilterReply;

public class OrdersFilter extends Filter<ILoggingEvent> {

    @Override
    public FilterReply decide(ILoggingEvent event) {
        boolean isAskOrder = event.getFormattedMessage().contains("AskOrder");
        boolean isBidOrder = event.getFormattedMessage().contains("BidOrder");
        if ( isAskOrder || isBidOrder) {
            return FilterReply.ACCEPT;
        } else {
            return FilterReply.DENY;
        }
    }
}

然后我编辑了我的 logback.xml 文件以引用新创建的过滤器...

<configuration>
    <appender name="TRANSACTIONS" class="ch.qos.logback.core.FileAppender">
        <filter class="filters/TransactionFilter"/>
        <file>log/transactions.log</file>
        <append>true</append>
        <encoder>
            <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="TRANSACTIONS" />
    </root>

    <appender name="ORDERS" class="ch.qos.logback.core.FileAppender">
        <filter class="filters/OrderFilter"/>
        <file>log/orders.log</file>
        <append>true</append>
        <encoder>
            <pattern>%date{yyyy-MM-dd} %X{akkaTimestamp} %-5level[%thread] %logger{1} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="ORDERS" />
    </root>
</configuration>

您在过滤器标签中指定的 class 不是您要接受的文件类型,而是过滤器 class 的 class 路径(可能是自定义的) 你想用来过滤你的日志。

所以我猜你会得到那个错误,因为你的 classes 没有实现过滤器。

您应该将过滤器 class 构建为可读 here,每个过滤器一个,然后引用它们。