I am new in Log4j2 and want to use the RollingFileAppender. Further as rollover I want to use the TimeBaseTriggeringPolicy:
The TimeBasedTriggeringPolicy causes a rollover once the date/time pattern no longer applies to the active file.
On the site above there is an example for such an TimeBasedTriggeringPolicy:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
Where is in the configuration above the "date/time pattern" defined, that determines if the active file applies to it or not?
Thanks for your help!
That is the filePattern. In your config:
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
The most granular time unit in the above is dd (days) so it will rollover daily at midnight.
Related
I am trying to change log levels programmatically for a given keyword. For example If I have the log level set to OFF but want to see logs that contain "database" keyword, how can I do that? Is there a way to to that via java?
#fatCop's answer is mostly correct. You can start with log4j2.xml configured as
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="AppName" packages="">
<RegexFilter regex="*database*" onMatch="DENY" onMismatch="DENY"/>
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
Because this is using a global filter it will cause nothing to be logged. When you are ready to enable logging do
final LoggerContext loggerContext = LoggerContext.getContext(false);
final Configuration config = loggerContext.getConfiguration();
Filter filter = RegexFilter.createFilter("database", null, false, Result.ACCEPT, RESULT.DENY);
config.setFilter(filter);
When you want it disabled then replace the filter with a new one that is set back to DENY on a match.
Note that the logging level on the root logger is irrelevant since the filter is only accepting or denying events.
As per Log4j Filter Manual, you can use RegexFilter. Snippet referring to manual, the configuration for you can be like:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="AppName" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
<RegexFilter regex="*database*" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
I changed my logging from sync to async but I am not sure how to put policies on it. I want to apply my sync logging settings to async logging. Please see below.
// I switched from this
<RollingFile name="fileLogger" fileName="${logPath}/log.log"
filePattern="${logPath}/log-%d{yyyy-MM-dd-hh}-%i.log">
<PatternLayout>
pattern="${logPattern}"/>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="10 MB"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>
</Appenders>
//to this
<File name="prodLog" fileName="${logPath}/log.log">
<PatternLayout
pattern="${logPattern}"/>
</File>
<Async name="asyncLogger" includeLocation="true">
<AppenderRef ref="prodLog"/>
<ArrayBlockingQueue/>
</Async>
I dont think you can use the same policies for the File appender.
To achieve an asynchronous behavior for a rolling file, you could use the RollingRandomAccessFile, just like the following example:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>>
</PatternLayout>
</Console>
<RollingRandomAccessFile name="Rolling-Random-Access-File-Appender"
fileName="logs/rollingrandomaccessfile.log"
filePattern="archive/logs/rollingrandomaccessfile.log.%d{yyyy-MM-dd-hh-mm}.gz">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"/>
<Policies>
<SizeBasedTriggeringPolicy size="1 KB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<AsyncLogger name="guru.springframework.blog.log4j2async" level="debug">
<AppenderRef ref="Rolling-Random-Access-File-Appender"/>
</AsyncLogger>
<Root level="debug">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>
More on this in this post: https://springframework.guru/asynchronous-logging-with-log4j-2/
Regards
can anyone see what's is wrong with this xml configuration? It's to setup 2 different log files then log trace to 1 file and info to another:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingRandomAccessFile name="LogTrace" fileName="../logs/Trace.log" filePattern="../logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="LogInfo" fileName="../logs/Info.log" filePattern="../logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Logger name="monitor" level="info">
<AppenderRef ref="LogInfo" level="info"/>
</Logger>
<Root level="trace">
<AppenderRef ref="LogTrace" level="trace"/>
</Root>
</Loggers>
</Configuration>
The LogTrace is working but not the LogInfo...
In your code, do you use the monitor logger like this:
Logger logger = LogManager.getLogger("monitor");
logger.info("test info message");
The above should work since your config declares the info level logger with name "monitor".
Using the configuration below along with the code supplied by Remko in his answer did exactly what I am looking for:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingRandomAccessFile name="LogTrace" fileName="../logs/Trace.log" filePattern="../logs/$${date:yyyy-MM}/tracelog-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
</RollingRandomAccessFile>
<RollingRandomAccessFile name="LogInfo" fileName="../logs/Info.log" filePattern="../logs/$${date:yyyy-MM}/infolog-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %m %ex%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="25 MB"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<Logger name="monitor" level="all">
<AppenderRef ref="LogInfo" level="info"/>
<AppenderRef ref="LogTrace" level="trace"/>
</Logger>
</Loggers>
</Configuration>
It's about as simple as it can be... once you have spent a few DAYS mulling over the various configuration options!
I was using log4j2 and it was logging statements for me with no issues. I might have made some changes (moved from info to debug and back) but its quite possibly I might have messed up the config in some other fashion. I am copying my config file below (I have not moved any log4j2 and slf4j jar files from my project). Any thoughts?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="TestApp" packages="">
<Appenders>
<RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/test.log" immediateFlush="false" append="false"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="500 MB"/>
</Policies>
</RollingRandomAccessFile>
</Appenders>
<Loggers>
<AsyncLogger name="FATAL_LOGGER" level="fatal" includeLocation="true" additivity="false">
<AppenderRef ref="RollingRandomAccessFile"/>
</AsyncLogger>
<Root level="debug" includeLocation="false">
<AppenderRef ref="RollingRandomAccessFile"/>
</Root>
</Loggers>
</Configuration>
I tested the config in a test project and it works without any issues. Ensure that you do not have any locks on the file and have correct read/write privileges on the file/directory.
Now I'm using structure like this:
Appender:
<RollingFile name="user.log" append="true" fileName="users/%MDC{USERNAME}.txt"
filePattern="users/archive/%MDC{USERNAME}-%d{MM-dd-yyyy}-%i.txt.gz">
<PatternLayout pattern="%-5p %d{MMMM-dd HH:mm:ss} %X: %c - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="50 MB"/>
</Policies>
</RollingFile>
Logger:
<appender-ref ref="user.log">
<ThreadContextMapFilter onMatch="ACCEPT" onMismatch="DENY" operator="or">
<KeyValuePair key="USERNAME" value="%X{USERNAME}"/>
<KeyValuePair key="IP" value="%X{IP}"/>
</ThreadContextMapFilter>
</appender-ref>
But it doesn't work with MDC keys. How could I use MDC keys in xml to config RollingFileAppender?
Take a look at RoutingAppender. Maybe this can get you started:
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="DEBUG" name="MyApp" packages="">
<appenders>
<Routing name="Routing">
<Routes pattern="$${ctx:USERNAME}">
<Route>
<RollingFile name="user.log" append="true" fileName="users/${ctx:USERNAME}.txt"
filePattern="users/archive/${ctx:USERNAME}-%d{MM-dd-yyyy}-%i.txt.gz">
<PatternLayout>
<pattern>%d{ISO8601} [%t] %p %c %L - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="50 MB"/>
</Policies>
</RollingFile>
</Route>
</Routes>
</Routing>
</appenders>
<loggers>
<root level="TRACE">
<appender-ref ref="Routing" level="DEBUG" />
</root>
</loggers>
</configuration>