Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot logback.xml creating .tmp Files

I am trying to persist the logs of a Spring Boot Application, however, since the logs generated are large I am trying to use the logback.xml to roll the file greater than 350MB into a compressed file.

I am able to roll a couple of MB's per day but midway the service starts writing to a temp file. I have tried both "TimeBasedRollingPolicy" and "Size AndTimeBasedRollingPolicy" with Triggering Policy of "SizeAndTimeBasedFNATP" but the results are unchanged. The .tmp files are generated every time.

My Logback.xml looks like this:

 <?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/home/xyz/logs/ProdLog.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/home/xyz/logs/log_%d{yyyy-MM-dd}_%i.log.zip</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 350MB -->
                <maxFileSize>350MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>5</maxHistory>
            <!--<maxFileSize>350MB</maxFileSize>-->
        </rollingPolicy>
        <encoder>
            <pattern>%date [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </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>
    <root level="INFO">
        <appender-ref ref="FILE"/>
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>

enter image description here

I see that the ticket for logback .tmp file issue is marked closed on Jira. Could someone help with what needs to be modified here to avoid generating the temp files?

like image 799
Akshay Avatar asked Aug 05 '19 10:08

Akshay


People also ask

How do I use Logback xml in spring boot?

To configure Logback for a Spring Boot project via XML, create the logback. xml or logback-spring. xml file under the src/main/resources folder. The configuration in XML file will override the logging properties in the application.

Does spring boot use Log4j instead of Logback?

Spring Boot supports Log4j 2 for logging configuration if it is on the classpath. If you are using the starters for assembling dependencies that means you have to exclude Logback and then include log4j 2 instead. If you aren't using the starters then you need to provide jcl-over-slf4j (at least) in addition to Log4j 2.

Where should the Logback xml be?

In a Spring Boot application, you can put the Logback. xml file in the resources folder. If your Logback. xml file is outside the classpath, you need to point to its location using the Logback.

Does spring boot use Logback by default?

By default, Spring Boot picks up the native configuration from its default location for the system (such as classpath:logback. xml for Logback), but you can set the location of the config file by using the "logging. config" property.

How to configure Logback in Spring Boot with XML?

For Logback configuration through XML, Logback expects a Logback.xml or Logback-test.xml file in the classpath. In a Spring Boot application, you can put the Logback.xml file in the resources folder. If your Logback.xml file is outside the classpath, you need to point to its location using the Logback.configurationFile system property, like this.

Where do I find the spring boot log file?

In the default structure of a Spring Boot web application, you can locate the application.properties file under the Resources folder. In the application.properties file, you can define log levels of Spring Boot, application loggers, Hibernate, Thymeleaf, and more.

How do I enable auto scan in Spring Boot Logback?

Logback Auto-Scan Issue with Spring Boot. In a logback-spring.xml file, you can enable auto-scan of the configuration by setting the scan="true" attribute. With auto-scan enabled, Logback scans for changes in the configuration file. For any changes, Logback automatically reconfigure itself with them.

What is the required dependency for logging in Spring Boot?

In the case of logging, the only mandatory dependency is Apache Commons Logging. We need to import it only when using Spring 4.x (Spring Boot 1.x) since it's provided by Spring Framework’s spring-jcl module in Spring 5 (Spring Boot 2.x).


1 Answers

I´m having the same issue using logback 1.2.3, apparently the bug is fixed in 1.3.0 version but I´ve found the lines of code in charge of generating those tmp files and managed to avoid it.

This is code from TimeBasedRollingPolicy.java:

public void rollover() throws RolloverFailure {

    // when rollover is called the elapsed period's file has
    // been already closed. This is a working assumption of this method.

    String elapsedPeriodsFileName = timeBasedFileNamingAndTriggeringPolicy.getElapsedPeriodsFileName();

    String elapsedPeriodStem = FileFilterUtil.afterLastSlash(elapsedPeriodsFileName);

    if (compressionMode == CompressionMode.NONE) {
        if (getParentsRawFileProperty() != null) {
            renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);
        } // else { nothing to do if CompressionMode == NONE and parentsRawFileProperty == null }
    } else {
        if (getParentsRawFileProperty() == null) {
            compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem);
        } else {
            compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);
        }
    }

    if (archiveRemover != null) {
        Date now = new Date(timeBasedFileNamingAndTriggeringPolicy.getCurrentTime());
        this.cleanUpFuture = archiveRemover.cleanAsynchronously(now);
    }
}

Future<?> renameRawAndAsyncCompress(String nameOfCompressedFile, String innerEntryName) throws RolloverFailure {
    String parentsRawFile = getParentsRawFileProperty();
    String tmpTarget = nameOfCompressedFile + System.nanoTime() + ".tmp";
    renameUtil.rename(parentsRawFile, tmpTarget);
    return compressor.asyncCompress(tmpTarget, nameOfCompressedFile, innerEntryName);
}

As you can see here, if you set a "fileName" into the appender, that method is called and generates a tmp file (which is not bad). I think the problem comes when there are threads that don´t stop logging on that tmp file, so at the end there are threads writing on tmp file and others writing on new "fileName" file.

If you just set fileNamePattern tag and not the file tag, then no tmp files should be generated.

I hope this helps you!

like image 84
Miguel Morata Avatar answered Sep 29 '22 19:09

Miguel Morata