How to print logs for 2 classes in 2 different files in spring boot - spring-boot

I have set logging.file=C:/usr/local/tomcat/logs/hib.log in application.properties and setting like below in class
private static final Logger logger = LogManager.getLogger(ChargeMasterController.class);
logger.info("Total time taken for is ---------------------------" + time + " ms");
Logs are getting printed fine in the path mentioned as logging.file.
Now I want to print my logs in 2 different files for 2 different classes(In same package), how can I set 2 logging.file in application.properties

You can't do that with the configuration Spring provides. But since spring-boot-starter-logging uses Logback by default, you can use a Logback configuration in stead and define multiple appenders, for example:
<appender name="FILE1" class="ch.qos.logback.core.FileAppender">
<file>log1.log</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<appender name="FILE2" class="ch.qos.logback.core.FileAppender">
<file>log2.log</file>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</layout>
</appender>
After that, you could use the FILE1 appender for your first class, FILE2 appender for your second class, and STDOUT for all other classes. This can be done by defining the loggers:
<logger name="com.example.pkg.ClassName1" additivity="false" level="info">
<appender-ref ref="FILE1" />
</logger>
<logger name="com.example.pkg.ClassName2" additivity="false" level="info">
<appender-ref ref="FILE2" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
As you can see, there are two loggers next to the root logger, called com.example.pkg.ClassName1 and com.example.pkg.ClassName2. These should match the names of the classes that should log to separate files.
The additivity="false" is important to make sure that logs that go to log1.log or log2.log aren't also sent to the console since they would also match the root logger.
This configuration can be placed within a logback.xml file on your classpath (eg. src/main/resources). Alternatively, you can also configure the location by using the logging.config property within application.properties. For example:
logging.config=file:/path/to/logback.conf
Or if you want to use an arbitrary location on your classpath:
logging.config=classpath:my/logback.conf

Related

How to clear log file before executing spring boot app?

I have been using the default spring logging configuration where I only specify filename in the application.properties file.
logging.file.name=app.log
But this by default appends logs when I start the application from cmd line "java -jar abc.jar"
I tried to search for the property which clears the file before starting application every time but couldn't find it. How should I clear the log file before starting the app?
Spring Boot uses Logback framework as as a default Logger.
You can use environnement variable via application.properties file to set some logging properties but logback xml configuration provides more powerfull features.
When a file in the classpath has one of the following names, Spring Boot will automatically load it over the default configuration:
logback-spring.xml
logback.xml
logback-spring.groovy
logback.groovy
So You can just put the code snippet below in src/main/resources/logback-spring.xml file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
</Pattern>
</layout>
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>app.log</file>
<append>false</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="FILE" />
<appender-ref ref="Console" />
</root>
</configuration>
The line <append>false</append> does the job.
if you wanna log more information than those avaible with the encoder pattern <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern> please check logback documention https://logback.qos.ch/manual/layouts.html#logback-access

Create new Spring log file every day

I want to configure Spring to write the log messages into file:
logging.file=/my-logs/app.log
logging.path=/my-logs/spring.log
Is it possible to rotate the file every day? I want to create a new file every day.
From the doc:
Log files rotate when they reach 10 MB and, as with console output, ERROR-level, WARN-level, and INFO-level messages are logged by default. Size limits can be changed using the logging.file.max-size property. Previously rotated files are archived indefinitely unless the logging.file.max-history property has been set.
Also, if you just want to log to "/my-logs/app.log", delete logging.path and change logging.file to:
logging.file=/my-logs/app.log
Edit: about rotating the log every day, Spring default logger does not support it, you can use Logback. Create a file called logback-spring.xml in src/main/resources with the following content:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}[%M:%L] - %msg%n</pattern>
</encoder>
</appender>
<appender name="ROTATE_FILE_DAILY" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/my-logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>app-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{0}[%M:%L] - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ROTATE_FILE_DAILY"/>
</root></configuration>

Custom log file for specific packages in Spring boot

I have a java package with specialized operations. Specialized in the sense that they are rarely used and i don't want to have them be mixed with normal logging.
I know that adding logging.file=myapplication.log will redirect the logging to this file but is there a way to specify only logging from specific packages to another file? Like logging.file.my.package=special.log ?
It's not possible with the logging configuration Spring Boot provides. However, you can fall back upon the configuration that the logging framework provides. By default, this is Logback, which can be configured to log to multiple logging files.
To do that, you need to add a logback.xml file to your classpath and configure multiple appenders. For example:
<appender name="FILE1" class="ch.qos.logback.core.FileAppender">
<file>log1.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE2" class="ch.qos.logback.core.FileAppender">
<file>log2.log</file>
<append>true</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
And now you can define a separate logger in case you want to log to a different file. Make sure to add the additivity="false" otherwise, the log message will still be printed in both log files:
<logger name="com.example.apps.special-package" level="INFO" additivity="false">
<appender-ref ref="FILE2" />
</logger>
<root level="INFO">
<appender-ref ref="FILE1" />
</root>
In this case, all logs will be written to log1.log (FILE1 appender), while logs from the package com.example.apps.special-package will be written to log2.log (FILE2 appender).
Spring uses Logback as default logger. According to the official doc you can setup logback.xml yourself to add to the default logging mechanism your 'special' behavior:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
<include resource="org/springframework/boot/logging/logback/file-appender.xml" />
<include resource="org/springframework/boot/logging/logback/console-appender.xml" />
<property name="SPECIAL_FILE_NAME" value="special"/>
<appender name="SPECIAL_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%-10.10thread] %-5level %30.30logger{29}:%-4line %msg%n</pattern>
<charset>utf8</charset>
</encoder>
<file>logs/${SPECIAL_FILE_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>logs/${SPECIAL_FILE_NAME}-%i.log</fileNamePattern>
</rollingPolicy>
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>
<logger name="logging.file.my.package" level="debug" additivity="false">
<appender-ref ref="SPECIAL_FILE"/>
</logger>
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="CONSOLE" />
</root>
</configuration>
Here we use Spring default FILE and CONSOLE appenders to log app info as usual (except logging.file.my.package), and use SPECIAL_FILE appender to log info from this package to file log/special.log.

Logging pattern in spring boot application

How do I set the logging file pattern to something like server.log.2017-12-22.gz?
As of now in my application.properties file, I have set the logging pattern to:
logging.pattern.file= "%d{yyyy-MM-dd } [%thread] %-5level %logger{36} - %msg%n"
logging.file=/var/opt/VS_Logs/server.log
But I need to store the files in the following format: server.log.2017-12-22.gz
As soon as you want custom rolling and triggering policies, you can no longer rely on Spring boot's logging configuration, and you have to use the vendor specific logging configuration. Here is an example using Logback and a TimeBasedRollingPolicy:
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>server.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>server.log.%d{yyyy-MM-dd}.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd } [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
Logback will automatically gzip it when you use the .gz extension. If you save this file as logback.xml and put it on your classpath, Spring boot will automatically detect it, otherwise, you can use the logging.config property:
logging.config=classpath:logback.xml

Logging with slf4j, and 'logback', but not creating specified log file which is in configuration. (using maven, jetty)

As specified in title I'm using Maven, and Jetty. For logging using SLF4J and Logback. I have 'logback.xml' at 'src/main/resources'.
<configuration>
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
</layout>
</appender>
<appender name="FILE"
class="ch.qos.logback.core.FileAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%-4relative [%thread] %-5level %class - %msg%n</pattern>
</layout>
<File>myLog.log</File>
</appender>
<logger name="org.mortbay">
<level value="debug" />
</logger>
<root>
<level value="error" />
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
But my problem is its not creating the file 'myLog.log' if I run/debug the project. What's the solution to get the log file.
Is there any way to get the log file only with SLF4J?
Sorry! I misunderstood the usage of 'Logback'. I got solution from http://www.mail-archive.com/user#slf4j.org/msg00661.html
i.e.
It appears that you have misunderstood
the purpose of SLF4J. If you place
slf4j-jdk14-1.5.6.jar then slf4j-api
will bind with java.util.logging.
Logback will not be used. Only if you
place logback-core.jar and
logback-classic.jar on your class path
(but not slf4j-jdk14-1.5.6.jar) will
SLF4J API bind with logback. SLF4J
binds with one and only one underlying
logging API (per JVM launch).
HTH,
Thanks to Ceki Gulcu. Now I can able to get logs in my file.
If you are using JBoss 5.1 and you are having the same problem[logback not writing to file] then add the following in jboss-web.xml.
<class-loading>
<loader-repository>
com.hp:classloader=logback-slf4j
<loader-repository-config>java2ParentDelegation=false</loader-repository-config>
</loader-repository>
</class-loading>
This should solve your problem.

Resources