Defer evaluation of FileAppender filename until file is opened?

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Defer evaluation of FileAppender filename until file is opened?

Doug Wegscheid
 
I am trying to have log4j2 write log files with names YYYYmmdd-HHMMSS.log, but not start writing the file until we have a good system time (>year 1986). I have an application running on a system that boots up, and takes a while to get the correct time; until that happens, the system thinks it's back in 1970, and there really is no point to writing a log file with a bum date.

Using a custom filter, I can get the FileAppender to not write any events until the system time is set. I can get the FileAppender to not open the file until the first event is passed by the custom filter (createOnDemand="true"). Using Log4J2 - assigning file appender filename at runtime, I can get the file named YYYYmmdd-HHMMSS.log, but the YYYYmmdd-HHMMSS.log in the configuration XML seems to get evaluated when log4j2 is initialized (not when the file is opened), so my file name is still 19700101-000000.log.

Is there a way to defer evaluation of the name for a log4j2 FileAppender until the file is actually opened? Alternatively, is there a sneaky way to use RollingFileAppender to do this? (I don't see a way to change the filename of the current file there, just old files)

I could do a custom appender (FileAppender/FileManager just are not all that long), but I'm trying to avoid that if possible.
 
Reply | Threaded
Open this post in threaded view
|

Re: Defer evaluation of FileAppender filename until file is opened?

Ralph Goers
The FileAppender has an option named createOnDemand. If you set it to true then the file will only be created when a log event is written to it. See http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender <http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender>.

Ralph

 

> On Feb 4, 2020, at 2:10 PM, Doug Wegscheid <[hidden email]> wrote:
>
>
> I am trying to have log4j2 write log files with names YYYYmmdd-HHMMSS.log, but not start writing the file until we have a good system time (>year 1986). I have an application running on a system that boots up, and takes a while to get the correct time; until that happens, the system thinks it's back in 1970, and there really is no point to writing a log file with a bum date.
>
> Using a custom filter, I can get the FileAppender to not write any events until the system time is set. I can get the FileAppender to not open the file until the first event is passed by the custom filter (createOnDemand="true"). Using Log4J2 - assigning file appender filename at runtime, I can get the file named YYYYmmdd-HHMMSS.log, but the YYYYmmdd-HHMMSS.log in the configuration XML seems to get evaluated when log4j2 is initialized (not when the file is opened), so my file name is still 19700101-000000.log.
>
> Is there a way to defer evaluation of the name for a log4j2 FileAppender until the file is actually opened? Alternatively, is there a sneaky way to use RollingFileAppender to do this? (I don't see a way to change the filename of the current file there, just old files)
>
> I could do a custom appender (FileAppender/FileManager just are not all that long), but I'm trying to avoid that if possible.
>

Reply | Threaded
Open this post in threaded view
|

Re: Defer evaluation of FileAppender filename until file is opened?

Doug Wegscheid
 yes, that works as designed, but does not resolve my problem. The filename is not evaluated when the first event is written (after we have a good date/time), it's evaluated when log4j2 is configured (which is before when we have a good date/time set).
    On Tuesday, February 4, 2020, 08:19:16 PM EST, Ralph Goers <[hidden email]> wrote:  
 
 The FileAppender has an option named createOnDemand. If you set it to true then the file will only be created when a log event is written to it. See http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender <http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender>.

Ralph

 

> On Feb 4, 2020, at 2:10 PM, Doug Wegscheid <[hidden email]> wrote:
>
>
> I am trying to have log4j2 write log files with names YYYYmmdd-HHMMSS.log, but not start writing the file until we have a good system time (>year 1986). I have an application running on a system that boots up, and takes a while to get the correct time; until that happens, the system thinks it's back in 1970, and there really is no point to writing a log file with a bum date.
>
> Using a custom filter, I can get the FileAppender to not write any events until the system time is set. I can get the FileAppender to not open the file until the first event is passed by the custom filter (createOnDemand="true"). Using Log4J2 - assigning file appender filename at runtime, I can get the file named YYYYmmdd-HHMMSS.log, but the YYYYmmdd-HHMMSS.log in the configuration XML seems to get evaluated when log4j2 is initialized (not when the file is opened), so my file name is still 19700101-000000.log.
>
> Is there a way to defer evaluation of the name for a log4j2 FileAppender until the file is actually opened? Alternatively, is there a sneaky way to use RollingFileAppender to do this? (I don't see a way to change the filename of the current file there, just old files)
>
> I could do a custom appender (FileAppender/FileManager just are not all that long), but I'm trying to avoid that if possible.
>
 
Reply | Threaded
Open this post in threaded view
|

Re: Defer evaluation of FileAppender filename until file is opened?

Ralph Goers
Yes, so your best bet is to use the RoutingAppender and only supply a default Route. The Appender itself will only be created when something is logged to the Route.

Ralph

> On Feb 4, 2020, at 6:55 PM, Doug Wegscheid <[hidden email]> wrote:
>
> yes, that works as designed, but does not resolve my problem. The filename is not evaluated when the first event is written (after we have a good date/time), it's evaluated when log4j2 is configured (which is before when we have a good date/time set).
>    On Tuesday, February 4, 2020, 08:19:16 PM EST, Ralph Goers <[hidden email]> wrote:  
>
> The FileAppender has an option named createOnDemand. If you set it to true then the file will only be created when a log event is written to it. See http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender <http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender>.
>
> Ralph
>
>
>
>> On Feb 4, 2020, at 2:10 PM, Doug Wegscheid <[hidden email]> wrote:
>>
>>
>> I am trying to have log4j2 write log files with names YYYYmmdd-HHMMSS.log, but not start writing the file until we have a good system time (>year 1986). I have an application running on a system that boots up, and takes a while to get the correct time; until that happens, the system thinks it's back in 1970, and there really is no point to writing a log file with a bum date.
>>
>> Using a custom filter, I can get the FileAppender to not write any events until the system time is set. I can get the FileAppender to not open the file until the first event is passed by the custom filter (createOnDemand="true"). Using Log4J2 - assigning file appender filename at runtime, I can get the file named YYYYmmdd-HHMMSS.log, but the YYYYmmdd-HHMMSS.log in the configuration XML seems to get evaluated when log4j2 is initialized (not when the file is opened), so my file name is still 19700101-000000.log.
>>
>> Is there a way to defer evaluation of the name for a log4j2 FileAppender until the file is actually opened? Alternatively, is there a sneaky way to use RollingFileAppender to do this? (I don't see a way to change the filename of the current file there, just old files)
>>
>> I could do a custom appender (FileAppender/FileManager just are not all that long), but I'm trying to avoid that if possible.
>>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: Defer evaluation of FileAppender filename until file is opened?

Doug Wegscheid
 That looks promising, but I am having an issue with the RoutingAppender throwing an NPE when the first event gets past the filter on the RoutingAppender:
2020-02-05 02:38:08,798 Log4j2-TF-1-AsyncLogger[AsyncContext@2cdf8d8a]-1 ERROR An exception occurred processing Appender MyRoute java.lang.NullPointerException
    at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
    at org.apache.logging.log4j.core.appender.routing.RoutingAppender.getAppender(RoutingAppender.java:286)
    at org.apache.logging.log4j.core.appender.routing.RoutingAppender.getControl(RoutingAppender.java:249)
    at org.apache.logging.log4j.core.appender.routing.RoutingAppender.append(RoutingAppender.java:228)
    at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
    at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543)
    at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:473)
    at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:98)
    at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:485)
    at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:161)
    at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:46)
    at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:29)
    at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
    at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
    at java.base/java.lang.Thread.run(Thread.java:834)

I suspect I am missing something in my configuration?

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG" packages="org.wegscd">
    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <Routing name="MyRoute">
            <TimeIsSetFilter/>
            <Routes>
                <Route>
                    <File name="MyFile" createOnDemand="true" fileName="log-${date:yyyy_MM_dd HH.mm.ss}.log">
                        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
                    </File>
                </Route>
            </Routes>
        </Routing>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="MyRoute"/>
        </Root>
    </Loggers>
</Configuration>


    On Wednesday, February 5, 2020, 12:14:13 AM EST, Ralph Goers <[hidden email]> wrote:  
 
 Yes, so your best bet is to use the RoutingAppender and only supply a default Route. The Appender itself will only be created when something is logged to the Route.

Ralph

> On Feb 4, 2020, at 6:55 PM, Doug Wegscheid <[hidden email]> wrote:
>
> yes, that works as designed, but does not resolve my problem. The filename is not evaluated when the first event is written (after we have a good date/time), it's evaluated when log4j2 is configured (which is before when we have a good date/time set).
>    On Tuesday, February 4, 2020, 08:19:16 PM EST, Ralph Goers <[hidden email]> wrote: 
>
> The FileAppender has an option named createOnDemand. If you set it to true then the file will only be created when a log event is written to it. See http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender <http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender>.
>
> Ralph
>
>
>
>> On Feb 4, 2020, at 2:10 PM, Doug Wegscheid <[hidden email]> wrote:
>>
>>
>> I am trying to have log4j2 write log files with names YYYYmmdd-HHMMSS.log, but not start writing the file until we have a good system time (>year 1986). I have an application running on a system that boots up, and takes a while to get the correct time; until that happens, the system thinks it's back in 1970, and there really is no point to writing a log file with a bum date.
>>
>> Using a custom filter, I can get the FileAppender to not write any events until the system time is set. I can get the FileAppender to not open the file until the first event is passed by the custom filter (createOnDemand="true"). Using Log4J2 - assigning file appender filename at runtime, I can get the file named YYYYmmdd-HHMMSS.log, but the YYYYmmdd-HHMMSS.log in the configuration XML seems to get evaluated when log4j2 is initialized (not when the file is opened), so my file name is still 19700101-000000.log.
>>
>> Is there a way to defer evaluation of the name for a log4j2 FileAppender until the file is actually opened? Alternatively, is there a sneaky way to use RollingFileAppender to do this? (I don't see a way to change the filename of the current file there, just old files)
>>
>> I could do a custom appender (FileAppender/FileManager just are not all that long), but I'm trying to avoid that if possible.
>>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]
 
Reply | Threaded
Open this post in threaded view
|

Re: Defer evaluation of FileAppender filename until file is opened?

Doug Wegscheid
 Found it: need to make sure we have a key for the route, even if it won't be used. Added pattern="x" to <Routes>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG" packages="org.wegscd">
    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <Routing name="MyRoute">
            <TimeIsSetFilter/>
            <Routes pattern="x">
                <Route>
                    <File name="MyFile" createOnDemand="true" fileName="log-${date:yyyy_MM_dd HH.mm.ss}.log">
                        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
                    </File>
                </Route>
            </Routes>
        </Routing>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="MyRoute"/>
        </Root>
    </Loggers>
</Configuration>Works perfectly!

    On Wednesday, February 5, 2020, 2:48:30 AM EST, Doug Wegscheid <[hidden email]> wrote:  
 
  That looks promising, but I am having an issue with the RoutingAppender throwing an NPE when the first event gets past the filter on the RoutingAppender:
2020-02-05 02:38:08,798 Log4j2-TF-1-AsyncLogger[AsyncContext@2cdf8d8a]-1 ERROR An exception occurred processing Appender MyRoute java.lang.NullPointerException
    at java.base/java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:936)
    at org.apache.logging.log4j.core.appender.routing.RoutingAppender.getAppender(RoutingAppender.java:286)
    at org.apache.logging.log4j.core.appender.routing.RoutingAppender.getControl(RoutingAppender.java:249)
    at org.apache.logging.log4j.core.appender.routing.RoutingAppender.append(RoutingAppender.java:228)
    at org.apache.logging.log4j.core.config.AppenderControl.tryCallAppender(AppenderControl.java:156)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender0(AppenderControl.java:129)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppenderPreventRecursion(AppenderControl.java:120)
    at org.apache.logging.log4j.core.config.AppenderControl.callAppender(AppenderControl.java:84)
    at org.apache.logging.log4j.core.config.LoggerConfig.callAppenders(LoggerConfig.java:543)
    at org.apache.logging.log4j.core.config.LoggerConfig.processLogEvent(LoggerConfig.java:502)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:485)
    at org.apache.logging.log4j.core.config.LoggerConfig.log(LoggerConfig.java:473)
    at org.apache.logging.log4j.core.config.AwaitCompletionReliabilityStrategy.log(AwaitCompletionReliabilityStrategy.java:98)
    at org.apache.logging.log4j.core.async.AsyncLogger.actualAsyncLog(AsyncLogger.java:485)
    at org.apache.logging.log4j.core.async.RingBufferLogEvent.execute(RingBufferLogEvent.java:161)
    at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:46)
    at org.apache.logging.log4j.core.async.RingBufferLogEventHandler.onEvent(RingBufferLogEventHandler.java:29)
    at com.lmax.disruptor.BatchEventProcessor.processEvents(BatchEventProcessor.java:168)
    at com.lmax.disruptor.BatchEventProcessor.run(BatchEventProcessor.java:125)
    at java.base/java.lang.Thread.run(Thread.java:834)

I suspect I am missing something in my configuration?

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG" packages="org.wegscd">
    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
        <Routing name="MyRoute">
            <TimeIsSetFilter/>
            <Routes>
                <Route>
                    <File name="MyFile" createOnDemand="true" fileName="log-${date:yyyy_MM_dd HH.mm.ss}.log">
                        <PatternLayout pattern="%d %p %c{1.} [%t] %m%n"/>
                    </File>
                </Route>
            </Routes>
        </Routing>
    </Appenders>
    <Loggers>
        <Root level="trace">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="MyRoute"/>
        </Root>
    </Loggers>
</Configuration>


    On Wednesday, February 5, 2020, 12:14:13 AM EST, Ralph Goers <[hidden email]> wrote: 
 
 Yes, so your best bet is to use the RoutingAppender and only supply a default Route. The Appender itself will only be created when something is logged to the Route.

Ralph

> On Feb 4, 2020, at 6:55 PM, Doug Wegscheid <[hidden email]> wrote:
>
> yes, that works as designed, but does not resolve my problem. The filename is not evaluated when the first event is written (after we have a good date/time), it's evaluated when log4j2 is configured (which is before when we have a good date/time set).
>    On Tuesday, February 4, 2020, 08:19:16 PM EST, Ralph Goers <[hidden email]> wrote: 
>
> The FileAppender has an option named createOnDemand. If you set it to true then the file will only be created when a log event is written to it. See http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender <http://logging.apache.org/log4j/2.x/manual/appenders.html#FileAppender>.
>
> Ralph
>
>
>
>> On Feb 4, 2020, at 2:10 PM, Doug Wegscheid <[hidden email]> wrote:
>>
>>
>> I am trying to have log4j2 write log files with names YYYYmmdd-HHMMSS.log, but not start writing the file until we have a good system time (>year 1986). I have an application running on a system that boots up, and takes a while to get the correct time; until that happens, the system thinks it's back in 1970, and there really is no point to writing a log file with a bum date.
>>
>> Using a custom filter, I can get the FileAppender to not write any events until the system time is set. I can get the FileAppender to not open the file until the first event is passed by the custom filter (createOnDemand="true"). Using Log4J2 - assigning file appender filename at runtime, I can get the file named YYYYmmdd-HHMMSS.log, but the YYYYmmdd-HHMMSS.log in the configuration XML seems to get evaluated when log4j2 is initialized (not when the file is opened), so my file name is still 19700101-000000.log.
>>
>> Is there a way to defer evaluation of the name for a log4j2 FileAppender until the file is actually opened? Alternatively, is there a sneaky way to use RollingFileAppender to do this? (I don't see a way to change the filename of the current file there, just old files)
>>
>> I could do a custom appender (FileAppender/FileManager just are not all that long), but I'm trying to avoid that if possible.
>>



---------------------------------------------------------------------
To unsubscribe, e-mail: [hidden email]
For additional commands, e-mail: [hidden email]