I have the following logback.xml file for my spring boot application where I intend to create daily log files:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>./logs/my-log-file.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>15</maxHistory>
<totalSizeCap>15MB</totalSizeCap>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d [%-5thread] [%-1p] [%logger{35}] - %msg%n</Pattern>
</layout>
</appender>
<root level="WARN">
<appender-ref ref="rollingFile"/>
</root>
<root level="INFO">
<appender-ref ref="rollingFile"/>
</root>
</configuration>
The files are created like this:
my-log-file.2018-11-10.log
my-log-file.2018-11-11.log
my-log-file.2018-11-12.log
I am looking to have the current active log file without the date so it is generic name like my-log-file.log and only when the date rolls to a new day, the file is renamed with date.
What change is required on the logback.xml to enable this configuration?
Add a <file> to the <appender>, like so:
<appender name="rollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>./logs/my-log-file.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>./logs/my-log-file.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>15</maxHistory>
<totalSizeCap>15MB</totalSizeCap>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d [%-5thread] [%-1p] [%logger{35}] - %msg%n</Pattern>
</layout>
</appender>
From the Logback documentation:
Note that the file property in RollingFileAppender (the parent of
TimeBasedRollingPolicy) can be either set or omitted. By setting the
file property of the containing FileAppender, you can decouple the
location of the active log file and the location of the archived log
files. The current logs will be always targeted at the file specified
by the file property. It follows that the name of the currently active
log file will not change over time. However, if you choose to omit the
file property, then the active file will be computed anew for each
period based on the value of fileNamePattern.
Related
I have configured logback xml for a spring boot project.
I want to configure another appender based on the property configured. We want to create an appender either for JSON logs or for text log, this will be decided either by property file or by environment variable.
So I am thinking about the best approach to do this.
Using filters to print logs to 1 of the file (either to JSON or to Txt). But this will create both of the appenders. I want to create only 1 appender.
Use "If else" blocks in logback XML file. To put if else around appenders, loggers seems untidy and error prone. So will try to avoid as much as possible.
So now exploring options where I can add appender at runtime.
So I want to know if it is possible to add appender at runtime. And will it be added before spring boots up or it could be done anytime in the project.
What could be the best approach to include this scenario.
As you're already using Spring, I suggest using Spring Profiles, lot cleaner than trying to do the same programmatically. This approach is also outlined in Spring Boot docs.
You can set an active profile from either property file:
spring.profiles.active=jsonlogs
or from environment value:
spring_profiles_active=jsonlogs
of from startup parameter:
-Dspring.profiles.active=jsonlogs
Then have separate configurations per profile:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="stdout-classic" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{dd-MM-yyyy HH:mm:ss.SSS} %magenta([%thread]) %highlight(%-5level) %logger{36}.%M - %msg%n</pattern>
</encoder>
</appender>
<appender name="stdout-json" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<timestampFormat>yyyy-MM-dd'T'HH:mm:ss.SSSX</timestampFormat>
<timestampFormatTimezoneId>Etc/UTC</timestampFormatTimezoneId>
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
</layout>
</encoder>
</appender>
<!-- begin profile-specific stuff -->
<springProfile name="jsonlogs">
<root level="info">
<appender-ref ref="stdout-json" />
</root>
</springProfile>
<springProfile name="classiclogs">
<root level="info">
<appender-ref ref="stdout-classic" />
</root>
</springProfile>
</configuration>
As the previous answer states, you can set different appenders based on Spring Profiles.
However, if you do not want to rely on that feature, you can use environments variables as described in the Logback manual. I.e.:
<appender name="json" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
<layout class="ch.qos.logback.contrib.json.classic.JsonLayout">
<jsonFormatter class="ch.qos.logback.contrib.jackson.JacksonJsonFormatter">
<prettyPrint>true</prettyPrint>
</jsonFormatter>
<appendLineSeparator>true</appendLineSeparator>
</layout>
</encoder>
</appender>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%cyan(%d{HH:mm:ss.SSS}) %gray([%thread]) %highlight(%-5level) %magenta(%logger{36}) - %msg%n
</pattern>
</encoder>
</appender>
<root level="info">
<!--
! Use the content of the LOGBACK_APPENDER environment variable falling back
! to 'json' if it is not defined
-->
<appender-ref ref="${LOGBACK_APPENDER:-json}"/>
</root>
My requirement is to print logs in current date directory and logs needs to be rollover in current date directory with below conditions :
Either hit max file size
Or date has changed
So today date is 16/07/2019 so directory structure should be
16_07_2019/fde.log (current log)
16_07_2019/fde.1.log (due to max size)
16_07_2019/fde.2.log (due to max size)
15_07_2019/fde.log (yesterday log)
15_07_2019/fde.1.log (yesterday log due to max size)
my logback.xml is :
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true">
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/VVV/AA/%d{yyyy_MM_dd}/fde.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>/VVV/AA/%d{yyyy_MM_dd}/fde.%i.log
</fileNamePattern>
<maxFileSize>2MB</maxFileSize>
</rollingPolicy>
<encoder>
<pattern>%d{MM:dd HH:mm:ss.SSS} [%t] [%level] [%logger{36}] - %msg%n
</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE"/>
</root>
</configuration>
Instead of creating current date directory it is create %d{yyyy_MM_dd} directory. I am not sure why?
Also, Is this xml looks fine based on my requirement?
Using SpringBoot : 2.0.5 version
Try this:
<file>/VVV/AA/logs/fde.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>/VVV/AA/logs/fde-%d{yyyy_MM_dd}.%i.log</fileNamePattern>
<maxFileSize>2MB</maxFileSize>
</rollingPolicy>
As in roll only over the file name rather than log file directory.
First of all, I don't like this solution... but it works...
Declare a "timestamp" property before starting Spring Boot.
public static void main(String[] args) {
System.setProperty("timestamp", Constants.ISO_YYYY_MM_DD_FORMAT.format(System.currentTimeMillis()));
SpringApplication app = new SpringApplication(MainConfig.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
In application.properties
logging.path=${folder.deploy}/logs/${timestamp}
In logback.xml, you import the property
<springProperty scope="context" name="LOG_PATH" source="logging.path" />
And off you go...
I still think there has to be an application.properties ONLY solution...
I wrote a TimeBasedRollingPolicy logback.xml, and while the log file is created succesfully, it seems to be reading it from the application.properties instead. Here is my setup:
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml"/>
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<appender name="ROLLING-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.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>${LOG_FILE}-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="ROLLING-FILE"/>
</root>
</configuration>
application.properties
logging.path=/path/to/log/folder/
logging.file=${logging.path}myLog
logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
When I run my application, the log is successfully saved in the correct path, but only as myLog. I would want it to be appended with the date (as in the logback.xml). Note I do want to keep taking the logging.path and logging.file from the application.properties because I have multiple depending on the environment.
Thanks
1) You need to set a logging.file or logging.path property, not both.
So logging.file=/path/to/log/folder/myLog should be enough to get a myLog log file in the specified path.
The spring boot documentation mentions that.
2) This is the format pattern for the log rolling, not for the current log :
<fileNamePattern>${LOG_FILE}-%d{yyyy-MM-dd}.log</fileNamePattern>
You get this format automatically for the current log file when it is rolled/archived because the time limit defined by the pattern is reached. In your case, it means everyday.
In my application-properteis, i have set spring.profiles.active=dev, but when i pass from command line via gradle clean -Dspring.profiles.active=stg build, it is taking by default dev profile only. how ot overwrite the default value set in application.properteis.
You can use below configuration using profile. Active profiles can be set using command line argument -Dspring.profiles.active="abc". For multiple profiles, you can include profile names comma separated.
<?xml version="1.0" encoding="UTF-8"?>
<appender name="rootappender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<springProfile name="abc">
<file>${LOG_ROOT}/abc.log</file>
</springProfile>
<springProfile name="xyz">
<file>${LOG_ROOT}/xyz.log</file>
</springProfile>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover. Make sure the path matches the one in the file element
or else the rollover logs are placed in the working directory. -->
<fileNamePattern>${LOG_ROOT}/system_%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>10MB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
I am Configured Logger For my application And Give the Logfilename as Current Time Stamp So It Expected to create one log File with the name as current Time stamp BuT INSTEDE IT CREATE ONE LOGFILE WITH CURRENT TIMESTAMP AND ANOTHER FILE WHICH IS BLANK CANT FIGURE OUT WHY IT CREATING EXTRA FILE??
I am using Logback logger in my application and Here is my logback.xml looks like My application is simple core java application. where i user logger to log the statements
<?xml version="1.0" encoding="UTF-8"?>
<configuration>`enter code here`
<timestamp key="byDay" datePattern="yyyy'-'MM'-'dd'''AT'''HH'-'mm'-'ss"/>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file> Myapplication${byDay}.txt </file>
<append>FALSE</append>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>