Disable Logback log files in containers
We found the spring boot project running containers will keep restarting after some time, maybe 10 days, maybe 5 days. The root cause is spring logback is writing log files into /tmp/ directory as “”spring.log in the containers and the log files are growing extremely fast. Finally the log files will kill the container.
I have tried many ways to disable the output log file.
1. 1. Logback configure
such as Max Log File Size, Total Size of Log Files, Log Files Max History, they did not help.
1 2 3 4 |
logging.file.max-size=1MB logging.file.total-size-cap=10MB logging.file.max-history=30 logging.file.clean-history-on-start=true |
Also tried with properties enject via docker compose, does not help.
1 2 3 4 5 6 7 8 9 10 11 |
test-app: image: test/image environment: - _JAVA_OPTIONS=-Xmx512m -Xms256m - LOGGING_FILE=/tmp/app.log - LOGGING_FILE_MAX_HISTORY=1 - LOGGING_FILE_MAX_SIZE=1MB - LOGGING_FILE_TOTAL_SIZE_CAP=2MB - LOG_FILE_MAX_HISTORY=1 - LOG_FILE_MAX_SIZE=1MB - LOG_FILE_TOTAL_SIZE_CAP=2MB |
Reference :
codejava.net/frameworks/spring-boot/logback-rolling-files-example
https://docs.spring.io/spring-boot/docs/2.1.4.RELEASE/reference/html/boot-features-logging.html
https://www.baeldung.com/spring-boot-logging
2. 2. Use Cron job in contaienr
Tried many ways but no success. Maybe because the docker image is openjdk:8-jre-alpine, and the cron can not be run in this image.
There are a lot of example here: https://stackoverflow.com/questions/37458287/how-to-run-a-cron-job-inside-a-docker-container
https://github.com/nehabhardwaj01/docker-cron
3. 3. Use Spring Scheduler
This does work of course, but it is not a clean way.
1 2 3 4 5 6 |
package com.test.scheduler; public interface BacklogCleanScheduler { void cleanup(); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
package com.test.scheduler.impl; import com.test.scheduler.BacklogCleanScheduler; import lombok.SneakyThrows; import org.apache.commons.io.FileUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; import java.io.File; import java.nio.file.Files; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; import java.util.List; @Component public class BacklogCleanSchedulerImpl implements BacklogCleanScheduler { private final Logger log = LoggerFactory.getLogger(BacklogCleanSchedulerImpl.class); @SneakyThrows @Override @Scheduled(cron = "1 * * ? * *") public void cleanup() { log.info("Logback cleanup start"); findLogs("/tmp"); } @SneakyThrows public void findLogs(String filePath) { File dir = new File(filePath); String[] extensions = new String[]{"gz"}; List<File> files = (List<File>) FileUtils.listFiles(dir, extensions, true); log.debug("Logback cleanup size {}", files.size()); for (File file : files) { if (isLogExpired(file)) { deleteFile(file); } } } public void deleteFile(File file) { try { Files.delete(file.toPath()); } catch (Exception e) { log.error("Logback cleanup failed to delete {}", file); } } public boolean isLogExpired(File file) { ZonedDateTime fileDate = Instant.ofEpochMilli(file.lastModified()).atZone(ZoneId.of("Europe/Berlin")); ZonedDateTime oldDate = ZonedDateTime.now().minusDays(1L); return fileDate.isBefore(oldDate); } } |
4. 4. Lockback Configuration (Best)
Very easy.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration> <configuration scan="true"> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <include resource="org/springframework/boot/logging/logback/console-appender.xml"/> <root> <appender-ref ref="CONSOLE"/> </root> <!-- https://logback.qos.ch/manual/configuration.html#shutdownHook and https://jira.qos.ch/browse/LOGBACK-1090 --> <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/> <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator"> <resetJUL>true</resetJUL> </contextListener> </configuration> |
Such configuration will set all log output to console. This will not affect the debugger when you using :
1 |
docker logs -f --tail=1000 container_id |
If you have configured the logstash to Kibana directly, not via Filebeat with /tmp/spring.log. Such change will not affect the Kibina.