log4j - 写入文件名作为记录器名称

log4j - write to file name as the logger name

我正在尝试根据记录器名称将我的日志写入不同的文件...

有可能吗?

如何在目标文件名中使用记录器名称?

这是我使用的 XML 文件:

<Configuration status="info">
<Properties>
    <Property name="log-path" value="logs/"/>
    <Property name="file-name" value="server"/>
    <Property name="file-type" value=".log"/>
</Properties>
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
    </Console>
    <RollingFile name="File" fileName="${log-path}${file-name}${file-type}"
                 filePattern="${file-name}-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
        <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
        <SizeBasedTriggeringPolicy size="1 MB"/>
    </RollingFile>
</Appenders>
<Loggers>
    <Root level="info">
        <AppenderRef ref="File"/>
        <AppenderRef ref="Console"/>
    </Root>
</Loggers>

我尝试使用:<Property name="file-name" value="%logger"/> 就像在 PatternLayout 中的使用和 <Property name="file-name" value="%c{10}"/> witout secssus...

你不能用 RollingFileAppender 那样做。 appender 接收由 <Loggers> 块配置的日志事件,如果 log4j 向它发送具有不同 LoggerNames 的日志事件,它们将被附加到任何打开的文件。 RollingFileAppender 一次写入一个文件,并在配置的策略告诉它时滚动。

您可以通过设置多个针对不同附加程序的记录器来写入不同的文件。像这样:

<Configuration status="info">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
        </Console>
        <RollingFile name="FileA"
                     filePattern="/tmp/A-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
            <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
            <SizeBasedTriggeringPolicy size="1 MB"/>
        </RollingFile>
        <RollingFile name="FileB"
                     filePattern="/tmp/B-%d{yyyy.MM.dd_HH.mm.ss}-%i.log">
            <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
            <SizeBasedTriggeringPolicy size="1 MB"/>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Logger name="org.example.App" level="info" additivity="false">
            <AppenderRef ref="FileA"/>
        </Logger>
        <Logger name="org.example.App2" level="info" additivity="false">
            <AppenderRef ref="FileB"/>
        </Logger>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

要根据某种模式将每个事件路由到不同的 RollingFileAppender,您可以使用 RoutingAppender.

The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target Appender may be an appender previously configured and may be referenced by its name or the Appender can be dynamically created as needed. The RoutingAppender should be configured after any Appenders it references to allow it to shut down properly.

You can also configure a RoutingAppender with scripts: you can run a script when the appender starts and when a route is chosen for an log event.

下面是如何根据 LoggerName 进行路由:

<Configuration status="info">
    <Properties>
        <Property name="log-path" value="logs/"/>
        <Property name="file-name" value="server"/>
        <Property name="file-type" value=".log"/>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
        </Console>
        <Routing name="Routing">
            <Routes pattern="$${event:Logger}">
                <Route>
                    <RollingFile name="Rolling-${event:Logger}" fileName="${log-path}${file-name}-${event:Logger}${file-type}"
                                 filePattern="${file-name}-%d{yyyy.MM.dd_HH.mm.ss}-%i-${event:Logger}.log">
                        <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
                        <SizeBasedTriggeringPolicy size="1 MB"/>
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Routing"/>
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

此外,出于兴趣,如果您真的想要,您可以 implement your own Appender 它可以使用 LogEvent 做任何您想做的事情。

这是一个 very rough start。它是一个 Appender,为每个 LoggerName 创建一个 RollingFileAppender。它仅在您使用 SizeBasedTriggeringPolicy 时有效。您应该能够将这样的 class 放入您的项目中并使用 XML 如:

<Configuration status="info">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
        </Console>
        <FilePerLoggerNameAppender name="File"
                     filePattern="/tmp/log-%d{yyyy.MM.dd_HH.mm.ss}-%i-$LOGGER$.log">
            <PatternLayout pattern="%d{dd.MM.yyyy HH:mm:ss.SSS} %-5level %logger - %msg%n"/>
            <SizeBasedTriggeringPolicy size="1 MB"/>
        </FilePerLoggerNameAppender>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="File"/>
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

并查看用 $LOGGER$ 创建的日志文件替换为您的记录器名称。