Im usign log4j2 for logging. I need daily logging with keeping a backup of 5 days logs. My log4j2.xml looks as below. My backup files keep on increasing in number eventhough ive limited the number to 5. Where did i go wrong??
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" monitorInterval="300">
<Appenders>
<RollingFile name="roll-by-time-and-size"
fileName="C:\\Users\\ann\\logs\\testing.log"
filePattern="C:\\Users\\ann\\logs\\testing.%d{MM-dd-yyyy}.log.gz"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
<DefaultRolloverStrategy max="5"/>
<!-- <DefaultRolloverStrategy>
<Delete basePath="C:\\Users\\ann\\logs" maxDepth="1">
<IfFileName glob="C:\\Users\\ann\\logs\\test.*.log.gz" />
<IfLastModified age="3" />
</Delete>
</DefaultRolloverStrategy> -->
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n">
</PatternLayout>
</Console>
</Appenders>
<Loggers>
<Root level="ALL">
<AppenderRef ref="roll-by-time-and-size"/>
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
Instead of the max consider using the delete rule.
Related
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class AzulMain {
private static final Logger LOGGER = LogManager.getLogger(AzulMain.class.getName());
public static void main(String[] args){
LOGGER.info("Maybe my first Logger works?");
}
}
The imports work fine. I use these jar-files:
log4j-1.2-api-2.17.2.jar
log4j-api.2.17.2.jar
log4j-core-2.17.2.jar
And this is how my XML-file (log4j2.xml) looks. It is in the same folder as my AzulMain:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="log-path">log/${date:yyyy-MM-dd HH-mm-ss-SSS}</Property>
<Property name="archive">${log-path}/archive</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>
</PatternLayout>
</Console>
<File name="File-Appender-AzulMain" fileName="${log-path}/Azul.log">
<PatternLayout>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>
</PatternLayout>
</File>
<RollingFile name="RollingFile-Appender"
fileName="${log-path}/rollingfile.log"
filePattern="${archive}/rollingfile.log.%d{yyyy-MM-dd#HH-mm}.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="30 MB"/>
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="AzulMain" level="trace" additivity="false">
<AppenderRef ref="File-Appender-AzulMain" level="all"/>
<AppenderRef ref="Console-Appender" level="info"/>
</Logger>
<Root level="debug" additivity="false">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>
When I use JavaUtilLogger everything works quite fine so far, I can make it create a file and print to console, however, with log4j nothing works.
I tested deleting the XML file and adding BasicConfigurator.configure() into my main-method, but it still didn't work. If I start my main-method all I get is:
Process finished with exit code 0
What is strange to me is that when I use the command java -Dlog4j.debug -cp AzulMain, it does not show me my configuration as I would expect it, but just what seems to be a very generic help message.
It is my first time, I am using a logger. Does anyone know what the problem might be?
Update:
This helped me as a first step:
BasicConfigurator replacement in log4j2
I deleted the XML-file and used the new
Configurator.initialize(new DefaultConfiguration());
Configurator.setRootLevel(Level.INFO);
And now it works at least in so far as it prints to the console. However, I am still not able to make it use the log4j2.xml file. I tried naming it log4j2-test.xml, too. (Source) It did not make a difference.
Now it works. This is how I did it.
I set up a new project, with just a main-class and added a new xml-file with a file logger only at first, then added a logger to the console, too. I deleted cache in IntelliJ and deleted the Configurator-lines in the code.
This is the new XML-file log4j2.xml that made it work:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">log/${date:yyyy-MM-dd HH-mm-ss-SSS}</Property>
</Properties>
<!-- File Logger -->
<Appenders>
<!-- Console appender configuration -->
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n
</pattern>>
</PatternLayout>
</Console>
<RollingFile name="fileLogger"
fileName="${basePath}/Azul.log"
filePattern="${basePath}/app-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
<!-- Max 10 files will be created everyday -->
<DefaultRolloverStrategy max="10">
<Delete basePath="${basePath}" maxDepth="10">
<!-- Delete all files older than 30 days -->
<IfLastModified age="30d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<appender-ref ref="fileLogger" />
<appender-ref ref="Console-Appender" level="info"/>
</Root>
</Loggers>
</Configuration>
It seems to me to have been a mistake somewhere in the xml-file that I just couldn't figure out where it is.
I am trying to write my log into different files depending on the logger name...
is it even possible?
how I can use the logger name in the target file name?
this is the XML file I use:
<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>
i have tried to use: <Property name="file-name" value="%logger"/> like in the use in PatternLayout and <Property name="file-name" value="%c{10}"/> witout secssus...
You can't do it like that with the RollingFileAppender. The appender receives log events as configured by your <Loggers> block, if log4j sends it log events with different LoggerNames they will be appended to whatever file is open. A RollingFileAppender writes to one file at a time and rolls when the configured policy tells it to.
You could write to different files by setting up multiple Loggers that target different appenders. Like this:
<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>
To route each event to a different RollingFileAppender based on some pattern you can use a 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.
Here is how you could route based on 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>
Also, out of interest, if you really want to you can implement your own Appender that does whatever you want with the LogEvent.
Here's a very rough start. It's an Appender that creates a RollingFileAppender per LoggerName. It only works if you use a SizeBasedTriggeringPolicy. You should be able to drop a class like that into your project and use XML like:
<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>
and see log files created with $LOGGER$ replaced with your logger names.
Currently, my logs are generating 1 file per day.
But I want to compress the log files older than 5 days and delete them after 10 days.
how can I achieve this?
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/server.log"
filePattern="logs/server_%d{date:yyyy-MM-dd}.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
I'm new to using log4j 2. I just started, and prepared the following log4j2.xml configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%msg%n" />
</Console>
<File name="MyFile" fileName="manager.log" immediateFlush="true" append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
What is the default logging behavior and file size in my xml? Is it rolling file, or once per day, or just a single huge file that grows a default size?!
If not, how can I change it to 2 rolling files with max of 10mb?
The File appender doesn’t have rollover behavior, it just appends to the specified file. When append = "false", it will overwrite any existing file when the application is restarted.
The Rolling File Appender is probably what you’re looking for.
The manual has many examples, but this may be close to what you have in mind:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <Configuration status="warn" name="MyApp" packages="">
3 <Appenders>
4 <RollingFile name="RollingFile" fileName="logs/app.log"
5 filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
6 <PatternLayout>
7 <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
8 </PatternLayout>
9 <Policies>
10 <TimeBasedTriggeringPolicy />
11 <SizeBasedTriggeringPolicy size="10 MB"/>
12 </Policies>
13 <DefaultRolloverStrategy max="2"/>
14 </RollingFile>
15 </Appenders>
16 <Loggers>
17 <Root level="error">
18 <AppenderRef ref="RollingFile"/>
19 </Root>
20 </Loggers>
21 </Configuration>
I've implemented async logging with log4j 2, but now I need to change log filename every hour, eg 2015-11-19/log-12.00.log, 2015-11-19/log-13.00, etc. (Soulutions I've found didn't work, may be I did something wrong).
I have following log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- Don't forget to set system property
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
to make all loggers asynchronous. -->
<Configuration status="WARN">
<Appenders>
<!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
<RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="true">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
</PatternLayout>
</RandomAccessFile>
</Appenders>
<Loggers>
<Root level="info" includeLocation="false">
<AppenderRef ref="RandomAccessFile"/>
</Root>
</Loggers>
</Configuration>
How to achive this?
You should have a look at TimeBasedTriggeringPolicy. Basically it causes a rollover once the date/time pattern no longer applies to the active file.
Have't tried this but this should work for you.
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN" >
<appenders>
<Async name="Async">
<AppenderRef ref="logfile" />
</Async>
<RollingRandomAccessFile name="logfile" fileName="async.log" filePattern="log-%d{HH}.00.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy max="24"/>
</RollingRandomAccessFile>
</appenders>
<loggers>
<root level="INFO" includeLocation="false">
<AppenderRef ref="Async"/>
</root>
</loggers>
</configuration>
The TimeBasedTriggeringPolicy interval attribute controls how often a rollover should occur based on the most specific time unit in the date pattern. In you case it is hours that is %d{HH} from file pattern.