How to write logs to a file in Spring Boot
Tell Spring Boot to write logs to disk, instead of just the console
“Hey, why isn’t my Spring Boot application writing logs to a file?”
You probably noticed when you first started learning Spring Boot. You looked for a log file, but it wasn’t there.
All of the logs are just spewed out to the console, and nothing gets written to disk. How useful is that?
So you re-ran your app, and then copied the logs somehow, and pasted them into Notepad so you could explore them.
How do you get Spring Boot to write logs to a file?
As with most things in Spring Boot:
-
You should probably use Spring’s default behaviour, unless you really, really need something different
-
Try to write as little code as possible – this usually means setting some configuration properties or adding annotations
In this article I’m going to cover the quickest way to do write logs to a file, with minimum configuration. This means using Spring’s preferred logging framework, Logback.
How Spring Boot’s logging works
As with most features in Spring Boot, logging is configured in an opinionated manner.
This means that there is a “standard” Spring Boot way to do things, which is automatically implemented for you, unless you choose otherwise.
(Sometimes this can look a bit like sorcery.)
Logging gets added by spring-boot-starter-web
Logging is configured automatically when you add the spring-boot-starter-web
dependency to your project.
A new, freshly-generated Spring Boot application (e.g. with the Spring Initializr) doesn’t come with any explicit logging configuration, and uses Logback by default.
(Logback is a logging framework for Java, and a successor to the old log4j.)
How to customise Spring Boot’s logging configuration
You can customise the default logging configuration in one of these ways:
-
Setting some Spring Boot logging properties – which can go in your
application.properties
,application.yml
, or as environment variables in your shell -
Adding a
logback.xml
onto the classpath, which Spring Boot will detect, and use to configure Logback -
Adding a
logback-spring.xml
onto the classpath, which Spring Boot will detect, and use to configure Logback
How to write logs to a file with Spring Boot
To make Spring Boot write to a log file, you can set the logging.file.path property, either:
-
in your
application.properties
file -
or in another way, like in an environment variable
Let’s see how these look.
Configuring the file name and path
To make Spring Boot write its log to disk, set the path and filename.
You can set the path with logging.file.path
in your application.properties
file, e.g.:
# Examples for Spring Boot 2.x
logging.file.path=. # write logs to the current directory
logging.file.path=/home/logs # write logs to /home/logs
logging.file.path=/mnt/logdir # write logs to /mnt/logdir
# Or set logging.path if you're using Spring Boot 1.x
With this configuration, Spring Boot will write to the console and also to a log file called spring.log
, at the path you specify.
If you want to choose your own log filename instead of spring.log
, then you can set the property logging.file.name, in your application.properties
, e.g.:
# Example for Spring Boot 2.x
logging.file.name=myapp.log
# Or set logging.file if you're using Spring Boot 1.x
How do you rotate the log file?
If you want to rotate the log file (start a new log file when the current one gets too big), look at setting these properties in your app:
-
logging.file.max-size
-
logging.file.max-history
Configuring logging using environment variables
Just like most Spring Boot properties, you can set these properties using environment variables instead, if you like.
Just convert each property to upper-case, and change dots to underscores. So you can use environment variables like this:
# to change the log file path
LOGGING_FILE_PATH=/path/to/mylogs
# to change the log filename
LOGGING_FILE_NAME=myapp.log
How does this work?
How does this trick work? How can we find out information like this ourselves?
It’s nice to understand the “why” sometimes.
So let’s take a look:
In the source code of LogFile
, a class in Spring Boot, there’s a comment which explains the main behaviour:
“Log output files are specified using
logging.file
,logging.path
, or Environment properties. If thelogging.file
property is not specified"spring.log"
will be written in thelogging.path
directory.
The comment tells us exactly how Spring will configure logging, and the properties that we need to set.
How the magic works
How does Spring detect Logback and abstract it away from us?
Looking around the source code, I found these relevant clues (hunted down in Spring Boot v2.6.6):
-
Logback should appear on the classpath in most Spring Boot projects because…
spring-boot-starter-web
includes the dependencyspring-boot-starter-logging
, which includeslogback
as a dependency. -
Spring’s logging system detects Logback because… The abstract class
LoggingSystem
contains some code which detects and returns the logging system that’s currently in use. It checks which classes are present in the classloader. -
Spring knows how to write logs with Logback because… There’s a subclass of
LoggingSystem
, calledLogbackLoggingSystem
, which basically configures and works with Logback. -
We don’t need to configure Logback ourselves because… Inside
DefaultLogbackConfiguration
, Spring Boot does some programmatic auto-configuration of Logback for us, so we don’t need to configure it manually.
Magic? Perhaps. :-)
Shouldn’t Spring Boot just write logs to a file by default?
Good question.
The answer to that question might be explained by the fact that Spring Boot is designed to run in environments at large scale.
At scale, managing and maintaining log files starts to become a headache.
Once you start running even just a few of Spring Boot apps in your data centre, it’s going to become painful to rotate and search through hundreds of log files.
Having said that:
Not everyone is running super-scale Netflix-level microservices. And neither is everyone using bleeding-edge container platforms like Kubernetes.
Sometimes, you just want a good old log file which you can write to, and use to check your app is running.
And that’s okay!