Log4j2 timebased and sizebased rolling file appender - spring-boot

I want a strategy in log4j2 that log file should roll on timebased and sizebased both. Such that it should roll on daily basis and when size reaches max 10KB (For test purpose). For that i tried following example.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<Configuration status="warn">
<Appenders>
<RollingFile name="fileLogger" fileName="E:\\Aditya\LOGS\AppLog.log" filePattern="E:\\Aditya\LOGS\AppLog-%d{yyyy-MM-dd-HH-mm-ss}-%i.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="10KB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="debug">
<appender-ref ref="fileLogger" />
</Root>
</Loggers>
</Configuration>
The problem with above config is it is rolling file every second. To solve this problem i changed
<RollingFile name="fileLogger" fileName="E:\\Aditya\LOGS\AppLog.log" filePattern="E:\\Aditya\LOGS\AppLog-%%d{yyyy-MM-dd-HH-mm-ss}-%%i.log">
TO
<RollingFile name="fileLogger" fileName="E:\\Aditya\LOGS\AppLog.log" filePattern="E:\\Aditya\LOGS\AppLog-%%d{yyyy-MM-dd}-%%i.log">
Now another problem is my total log files are limiting to 7 files per day only. I dont know why this is happening as i have not provided such configuration. Can anyone help me to solve this issue? Thanks in advance.

I think the issue is with your pattern. Just try these patterns.
%d{HH:mm:ss,SSS} or %d{dd MMM yyyy HH:mm:ss,SSS}
Check this :
log4j patterns

Related

Logs in Spring Boot not showing in terminal

I have a project in Spring Boot where I am adding logs with the #Slf4j annotation, but I can't get them to show up in the terminal when starting the project.
This is the log: log.info("totalVacations: " + totalVacations);
When I run the command mvn spring-boot: run, in terminal I can't see the message.
Very likely you are missing the configuration of the appender, if you are also using LOG4J and you don't already have it, you can create a file named: log4j2.xml within the application's class path, and then create some basic configuration like:
<Configuration>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout
pattern="%style{%d{ISO8601}}{black} %highlight{%-5level }[%style{%t}{bright,blue}] %style{%C{1.}}{bright,yellow}: %msg%n%throwable" />
</Console>
<RollingFile name="RollingFile"
fileName="./logs/spring-boot-logger-log4j2.log"
filePattern="./logs/$${date:yyyy-MM}/spring-boot-logger-log4j2-%d{-dd-MMMM-yyyy}-%i.log.gz">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
<Policies>
<!-- rollover on startup, daily and when the file reaches
10 MegaBytes -->
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy
size="10 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!-- LOG everything at INFO level -->
<Root level="info">
<AppenderRef ref="Console" />
<AppenderRef ref="RollingFile" />
</Root>
<!-- LOG "com.baeldung*" at TRACE level -->
<Logger name="com.baeldung" level="trace"></Logger>
</Loggers>
</Configuration>
The key here is to set an appender to the console so that the logs are pushed there, and then at the logger section establish which level are you trying to get at the console appender, according to your example that should be INFO
If you are using just plain SLF4J with Logback go to src/main/resources/application.properties and add the following line:
logging.level.com=INFO
The ".com" is referencing the package to where this will apply, in this case is everything inside src/main/java/com.
and at the logback-spring.xml try this basic config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/base.xml"/>
<logger name="your.name" level="INFO" additivity="false">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE"/>
</logger>
</configuration>
You can find a very nice tutorial with more info here:
https://www.baeldung.com/spring-boot-logging
https://springframework.guru/using-logback-spring-boot/
Check whether #Slf4J import is from Lombok or some other library. I'm sure lombok #Slf4J default provides lowercase log and not LOG.

log4j2 RollingFileAppender after first rolling, each POD write exclusively current log file

I use log4j2 on a springboot web application with microservices deployed on openshift 3.11.
below the configuration of log4j2
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="${env:LOGGING_LEVEL}">
<Properties>
<Property name="log_path">/home/jboss/logs</Property>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{dd-MM-yyyy HH:mm:ss.SSS} %green{[${hostName}]} %magenta{[%thread]} %highlight{%-5level} %logger{36}.%M - %msg%n" />
</Console>
<RollingFile name="fileLogger" fileName="${log_path}/application.log" filePattern="${log_path}/application.%i.log.zip" filePermissions="rw-rw-r-" >
<PatternLayout pattern="%d{dd-MM-yyyy HH:mm:ss.SSS} [${hostName}] [%thread] %-5level%logger{36}.%M - %msg%n" />
<Policies>
<SizeBasedTriggeringPolicy size="200MB" />
</Policies>
<DefaultRolloverStrategy max="30"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console" level="${env:LOGGING_LEVEL}"/>
<AppenderRef ref="fileLogger" level="${env:LOGGING_LEVEL}"/>
</Root>
</Loggers>
</Configuration>
my problem is as follows:
multiple pods should write to the log file at the same time,
on the first application.log file there are no problems but when the rolling occurs and the application.log file becomes application.1.log.zip
the application.log file is written by a single pod and the same thing happens at subsequent rolling, is there a configuration that allows all pods to write the same file avoiding the situation described?
Writing multiple pods/nodes log4j logs to a single file is not a best practice or a good idea, as this creates an ambiguity problem for updating logs.

logs not printing the full stack trace of exception in log file

I am trying to print the whole stack trace of exception in my log file without adding log.error statement in code as i have to make this generic implementation throughout the application. Can anyone help in this Here are log4j2 configuration xml file.
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN">
<appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout pattern="%d{yyyy-mm-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</File>
</appenders>
<logger name="org.springframework" level="error" additivity="false">
<AppenderRef ref="MyFile"/>
</logger>
<root level="INFO">
<appender-ref ref="Console"/>
</root>
</configuration>
Without ever using a log.error statement it is not possible to pipe the output to a log-file via log4j2 xml configuration. However, there is one way to optimise this by handling you exceptions centrally at one place instead of doing this repeatedly in the code.
Write a separate class which will handle all exceptions ultimately, you can use
#ExceptionHandler(Exception.class), this will handle all exceptions, in this you can intercept the exception and log out the full stack-trace using a log.error(e). Annotating this class with #ControllerAdvice(<all_pckages_you_want_cover>) will ensure whenever an unhandled exception is raised it is finally intercepted at this point and logged.
Reference: https://dzone.com/articles/global-exception-handling-with-controlleradvice
PS: If you are asking about handled exceptions they are anyways going to be custom handled, so you add a single line for logging them in your catch block.

Removing Log4j2.xml from Tranisitive Dependecies and to use Log4j2-spring.xml instead in springboot project

I need to add file Appender in existing log4j2.xml of my existing spring-boot project. i did that and its generating two logs files for every logger specified i.e, i have only added Root level logger then also two files are getting generated.
When i searched for it i found that in spring projects log4j2-spring.xml should be used instead of Log4j2.xml which may be the cause of duplicates log files getting generated.
But when i am trying to run to change my log4j2.xml to log4j2-spring.xml its not even considering that file and is picking any other log4j2.xml that is available via classpath as i have added some external jar as dependency in this project the log4j2.xml of these exteranl dependemcies are being considered rather then my log4j2-spring.xml. Is there a way of telling it to use my log4j2-spring.xml instead of any log4j2.xml or may be is there a way to remove the usage of log4j2.xml from any dependency.
I tried doing the same with a simple spring-boot project and it worked as expected but when i am trying to do the same in my project which is multi-module maven project it does not works.
Can someone let me know what would be the way of doing above said asks.
Here is my pom.
`
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info" monitorInterval="60">
<Properties>
<Property name="log-path">${sys:app.log.path}</Property>
<Property name="archive">${log-path}/archive</Property>
<Property name="appName">${sys:spring.application.name}</Property>
<Property name="envName">${sys:app.env.name}</Property>
</Properties>
<Appenders>
<Console name="Console-Appender" target="SYSTEM_OUT">
<PatternLayout>
<pattern>
%d{yyyy-MM-dd HH:mm:ss.SSS}{GMT} [%-5level] [%t] %c{1} - %msg%n
</pattern>
<charset>US-ASCII</charset>
</PatternLayout>
</Console>
<File name="File" fileName="${log-path}/${appName}-${envName}--${date:yyyy-MM-dd-HH-mm-ss-SSS}.log" append="true">
<PatternLayout pattern="%d{yyyy-MMM-dd HH:mm:ss a} [%t] %-5level %logger{36} - %msg%n" />
</File>
</Appenders>
<Loggers>
<Root level="INFO" additivity="false">
<AppenderRef ref="Console-Appender" level="WARN" />
<AppenderRef ref="File" level="INFO" />
</Root>
<Logger name="com.tmo.eus" level="INFO" additivity="false">
<Appender-ref ref="Console-Appender" />
</Logger>
</Loggers>
</Configuration>
`

SpringBoot logging configuration based on logging level

Is it possible to specify in SpringBoot's appliaction.properties different logging configuration for different logging levels?
For example to log info to file but debug only to console and specify different format for them.
I searched in SpringBoot docs but couldn't find the answer.
You can try using the log4j2 logger and specifiying withing its configurating file multiple logger elements. If you have the log4j2 dependency set up in spring, it should pick up the configuration in the file log4j2-spring.xml. Take a look at their intro docs here, but i believe something like this in the log4j2 config file would suffice:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="%d [%t] %-5level %logger{36} - %msg%n%throwable"/>
</Console>
<File name="FileAppender" fileName="debug.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="ConsoleAppender"/>
</Root>
<Root level="DEBUG">
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
Add following config in your application.yml
logging:
level:
root: INFO
com:
somepackage: DEBUG
someotherpackage: TRACE
Here you have set default logging to INFO (root logger) and for package com.somepackage logging level is DEBUG, for com.someotherpackage logging level is TRACE.

Resources