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

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.

Related

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.

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>
`

Log4j2 timebased and sizebased rolling file appender

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

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.

Spring Boot Logging Properties vs Log4J 2 Properties

In a Spring Boot Web app, I have the following logging properties in application.properties.
logging.level.guru.springframework.controllers=DEBUG
logging.level.org.springframework.web=DEBUG
logging.file=logs/spring-boot-logging.log
Things work fine - DEBUG messages of both internal Spring Boot and the application gets logged to logs/spring-boot-logging.log. But, even if I add log4j2-spring.xml with different logging levels, the levels of application.properties still get picked.
My log4j2-spring.xml is this:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="60">
<Properties>
<Property name="log-path">applogs</Property>
</Properties>
<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>
<File name="File-Appender" fileName="${log-path}/app_log.log" >
<PatternLayout>
<pattern>
[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="org.springframework.web" level="info">
<AppenderRef ref="File-Appender"/>
</Logger>
<Logger name="guru.springframework.controllers" level="info">
<AppenderRef ref="File-Appender"/>
</Logger>
<Root level="info">
<AppenderRef ref="Console-Appender"/>
</Root>
</Loggers>
</Configuration>
With these settings, debug (Defined in application.properties) messages are sent to applogs/app_log.log(Defined in log4j2-spring.xml)
On commenting out the logging.level.* in application properties, the log levels (info) in log4j2-spring.xml are used. I assume that by default properties of application.properties have precedence over log4j2-spring.xml. Is there any way I can configure Spring Boot to use log4j2-spring.xml properties instead of application.properties. Also, If application.properties have greater precedence, why the file appender of log4j2-spring.xml is getting used instead of the one in logging.file?
It should use your config file if you define it via this Spring Boot property:
logging.config= # Location of the logging configuration file. For instance `classpath:logback.xml` for Logback

Resources