Recently I've started to work with Spring Boot and have a following question:
We have different environments (like stage, development, production) and all of them can be run on windows or linux. So I've created application-stage.properties, application-prod.properties, application-devl.properties to specify stuff like db connections and so on because its OS agnostic (the same for windows and linux).
Now I would like to enable access logs for embedded Tomcat server.
So following various guides I used the following in my application.properties
file:
server.tomcat.accesslog.directory=logs
server.tomcat.accesslog.enabled=true
I was forced to specify a relative path because we use both linux and windows, however I would like the access log to be created in different places depending on the OS .
For example, we store logs in windows under c:\<product>\logs
and in linux we use /var/log/<product>/...
For usual logs we use logbacks and it allows stuff like this, but since access log is not actually logback driven and instead uses Valves, my question is: how we can achieve the same level of flexibility here?
I don't think I should provide additional profile for this and use it like:
--spring.profiles.active=windows / linux
Because I believe spring boot has some solution up on its sleeves for this :) Thanks a lot in advance
Here is the solution I've come up with. Maybe it will help someone.
There are 2 steps.
Step 1
I've created application-windows.properties
and application-linux.properties
files in src/main/resources
. These files hold the OS dependent configuration.
For example in Linux I specify something like this:
server.tomcat.accesslog.directory=/var/log/access_logs
For windows it can be (for example):
server.tomcat.accesslog.directory=C:\\Temp\\access_logs
Step 2
The spring boot application (the file with a main method) usually looks like this:
// maybe some additional annotations
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) throws Exception {
SpringApplication.run(..., args);
}
}
The documentation of spring boot in paragraph 25.2 states that profiles can be added programmatically So I've slightly changed the main class to allow this programmatic addition:
// maybe some additional annotations
@SpringBootApplication
public class MySpringBootApplication {
public static void main(String[] args) throws Exception {
SpringApplication myApp = new SpringApplication(...);
myApp.setAdditionalProfiles(getOSName());
myApp.run(args);
}
private static String getOSName() {
String os = System.getProperty("os.name");
if (os.toLowerCase().contains("win")) {
return "windows";
}
else {
return "linux";
}
}
}
That's it, now there is no need to specify the profiles in --spring.profiles.active
property (I usually use this to specify the environment, like staging, production, etc.
The point it that spring will load the relevant property file automatically now.
Thanks to all the people who have suggested their solutions!