Can i do custom logging in spring boot application? - spring-boot

In my enterprise application, i have several background jobs to fulfill various business requirement.
eg :- Bill generation job,Activate package job etc.
Here i need to specific custom logging to validate the job status,job input,if fails then reason etc.
How can i achieve above requirement , i don't need other application logs, just need logs related to jobs.
I need something like this in code.
For eg.
log.info ("Job inputs")
log.info(Job success status)
In log file output should be like:-
Info : Job inputs
Info : Job success

Create a file logback-spring.xml in resources folder with content:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="./logs"/>
<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="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- LOG everything at INFO level -->
<root level="info">
<appender-ref ref="Console"/>
</root>
<logger name="desired-package-name" level="info" additivity="false">
<appender-ref ref="RollingFile"/>
</logger>
</configuration>

Related

Write specfic logs to syslog using logback in springboot

I have a spring boot microservice application. logback.xml is configured to write the logs to a location on the server. In addition to this, I want to write logs from a particular java class to Syslog. I do not want logs from all other classes to be written to syslog but to a rolling file appender. Is there a way to configure this using logback.
below is my logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="DEV_HOME" value="logs"></property>
<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="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/data/storage/log/cms.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- roll over daily and when the file reaches 10 MB, max of 7 days or 3GB threshold -->
<fileNamePattern>/data/storage/log/cms.%d{yyyy-MM-dd}.%i.Logs.gz
</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>7</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
</appender>
<appender name="SPECIFIC_CLASS" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/sizeTimeOutputlogFile.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>[%d{yyyy-MM-dd HH:mm:ss}] %p %c{1.} [%t]- %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${DEV_HOME}/archived/sizeTimeOutputlogFile.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!--Max Size of file to start Archive -->
<maxFileSize>10KB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- Days till log history to keep -->
<maxHistory>3</maxHistory>
</rollingPolicy>
</appender>
<!--syslog appender-->
<appender name="SYSLOG" class="ch.qos.logback.classic.net.SyslogAppender">
<syslogHost>localhost</syslogHost>
<facility>LOCAL0</facility>
<port>514</port>
<throwableExcluded>true</throwableExcluded>
<suffixPattern>%thread: %-5level %logger{36} - %msg%n</suffixPattern>
</appender>
<!-- LOG everything at ERROR level -->
<root level="ERROR">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
</root>
<!-- LOG "com.myproject*" at ERROR level -->
<logger name="com.myproject" level="ERROR" additivity="false">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
</logger>
<logger name="com.myproject.ActivityLogAspect" level="DEBUG" additivity="false">
<appender-ref ref="SYSLOG"/>
<appender-ref ref="SPECIFIC_CLASS"/>
</logger>
</configuration>
From the above XML, SYSLOG and SPECIFIC_CLASS appenders are used to write logs from ActivityLogAspect class. When I run my application I see that only SPECIFIC_CLASS is working. I don't see any logs written to /var/log/messages. But if I add the SYSLOG appender along with the console appender, I see the messages written to /var/log/messages.
I do not want logs from all classes written to syslog but only from one particular class.
Please advise.

Camel (Spring Boot) custom log

Is there a way to log different routes in a single (human readable) log?
I need to log some routes in spring boot (using camel) in a txt file. These routes do some unmarshall/marshall stuff and i need to track that
Logback.xml is the easiest way to implement a human readable logger in springboot. It comes out of the box with Spring Boot and no configurations are required.
Create a logback.xml file in the resources folder and paste the following in it. You are set.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="logs" />
<!--Console Appender-->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{dd-MM-yyyy HH:mm:ss.SSS} %green([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n
</pattern>
</encoder>
</appender>
<!--Rolling File Appender-->
<appender name="File-Logger" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/myLog.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{dd-MM-yyyy HH:mm:ss.SSS} [%thread] %-5level %logger{36}.%M - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>
${LOG_PATH}/archived/log_%d{dd-MM-yyyy}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>60</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
<appender-ref ref="File-Logger"/>
</root>
</configuration>

log message print twice with java logback

I use logback to print log in my SpringBoot application. When I check out the log file, I found that, all log message print twice! It is so strange .
Yeah, I have found some answer similar to my issue. But maybe they are not what I want.
here is my logback.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<property name="LOG_HOME" value="${user.home}/app/logs"/>
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}-[%thread]-%-5level-%logger{50}: %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${LOG_HOME}/cloud-sync-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each file should be at most 10MB, keep 3 days worth of history, but at most 1GB -->
<maxFileSize>10MB</maxFileSize>
<maxHistory>3</maxHistory>
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">
<discardingThreshold >0</discardingThreshold>
<queueSize>256</queueSize>
<includeCallerData>true</includeCallerData>
<appender-ref ref ="FILE"/>
</appender>
<root level="INFO">
<appender-ref ref="Console"/>
<appender-ref ref="FILE"/>
<appender-ref ref="ASYNC"/>
</root>
</configuration>
How can I make sure log messages appear only once. Thank you.
It is because you have added ASYNC and FILE for INFO.
Please remove one of them based on your requirement.

Spring boot startup logs to file

Is it anyway to send startup logs to file, right now all logs up to the statement "Started Application in...." goes to stdout, I want all logging to file.
My logback config:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<property name="LOG_FILE" value="logs/app${PID}.log"/>
<appender name="AI-APPENDER"
class="com.microsoft.applicationinsights.logback.ApplicationInsightsAppender">
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder>
<pattern>${FILE_LOG_PATTERN}</pattern>
</encoder>
<file>${LOG_FILE}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
<maxFileSize>${LOG_FILE_MAX_SIZE:-10MB}</maxFileSize>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
<appender-ref ref="AI-APPENDER"/>
</root>
</configuration>
You need to configure your logging framework. Assuming you're just using the default from spring-boot then that's LogBack. So have a look at their docs or have a search, there are many useful resources (like this one)
If you add a logback.xml file with the following content to your resources folder you should get logging to both console and file (called application.log) in the same format as you now see for just console.
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>application.log</file>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="FILE" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
You probably want to use a RollingFileAppender as this will allow you to create new files when the log file gets big.

how to specify specific logger level for each of file writing and console writing

I want to maintain a log of only WARN, ERROR and FATAL in my logfile.log whereas want all above INFO to be written to console in my spring boot application. I see that when I do log.level.root=WARN, in application.properties file it sets a log level of WARN for the whole application. What can I do for displaying all log messages in console but writing only ones above WARN in the file?
Also!!!!
Is there a way to set level to INFO and write only certain specified logs in the file. For eg. I want to trace each and every logins/logouts/filechanges (say business logic related) in log with INFO level but don't want to see the default INFO messages that pop up during the start of the application like
2018-07-11 10:19:00.554 INFO 11190 --- [ main] c.v.guruji.GurujiApplication : Started GurujiApplication in 10.307 seconds (JVM running for 11.029)
.
The answer depends on which actual logging framework are you planning to use,
spring boot has integrations with most of them.
In general, if you opt for "zero configuration", specify the level of events in spring boot configuration files (application.properties / yaml) with the following line:
logging.level.com.myorg=DEBUG
logging.level.root=INFO
If you want to write to files, or in general provide more flexible configurations, you'll need to configure something called appender, but it's not a spring boot notion, but a logging framework term.
So the actual configuration will depend on a specific logging framework, usually, people put an XML configuration file (like logback.xml if you use logback) into src/main/resources folder and it works. Another modern option is log4j2 framework.
From the question it seems like you better first understand how to use these frameworks and then try to integrate them into spring boot, each of them is really flexible and will provide a solution you're looking for
Here is a link to the tutorial on how to use each of those frameworks with spring boot
Here is a logging chapter of official documentation of spring boot
Well , I went through some logback documentations and pretty much figured out what to do.
I'm posting this code for others who'll be having such problems as me for quick reference.
But I'll suggest to go through a proper documentation at first to understand it clearly.
logback.xml(for logging each level log in a separate file and to show all at console)
<?xml version="1.0" encoding="UTF-8"?>
<property name="DEV_HOME" value="logs" />
<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>
<appender name="FILE-ERROR"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/error.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/error.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="FILE-INFO"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/info.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/info.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="FILE-FATAL"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/fatal.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>FATAL</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/fatal.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<appender name="FILE-WARN"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${DEV_HOME}/warn.log</file>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>
%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${DEV_HOME}/archived/warn.%d{yyyy-MM-dd}.%i.log
</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- Send logs to both console and file audit -->
<logger name="com.vaidiksanatansewa.guruji" level="fatal"
additivity="false">
<appender-ref ref="FILE-FATAL" />
</logger>
<logger name="com.vaidiksanatansewa.guruji" level="error"
additivity="false">
<appender-ref ref="FILE-ERROR" />
</logger>
<logger name="com.vaidiksanatansewa.guruji" level="warn"
additivity="false">
<appender-ref ref="FILE-WARN" />
</logger>
<logger name="com.vaidiksanatansewa.guruji" level="info"
additivity="false">
<appender-ref ref="FILE-INFO" />
</logger>
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>

Resources