How to set logging.path for spring-boot apps? - java

spring-boot provides several logging.* settings that can be applied in application.properties, like:
logging.level.=DEBUG
logging.file=myfile.log
logging.path=d:/logs/
Problem: myfile.log is generated, BUT inside the classpath! Why isn't spring taking my absolute path into account?

The Spring Boot documentation states
By default, Spring Boot will only log to the console and will not
write log files. If you want to write log files in addition to the
console output you need to set a logging.file or logging.path property
(for example in your application.properties).
and then describes how the logging.file and logging.path properties work. You should only set one.
If logging.file is set, it will write to that specific file. The documentation states
Names can be an exact location or relative to the current directory.
So you're likely writing to your current directory, which happens to be the same as your classpath.
If you set logging.path, Spring Boot
Writes spring.log to the specified directory. Names can be an exact location or relative to the current directory.
Check that your current directory isn't your classpath, if you don't want them to mix, and adapt one of the logging.file and logging.path accordingly.

for Spring boot v2.3.4 and above for sure:
it is NOT logging.file=.... ,
it is logging.file.name=....

I don't know if this is still needed, but you can set the absolute path with following code according to your example
logging.path=D:\logs\logfile.txt
You can alter the filename and the path like this. If the folder doesn't exist it gets created. On Windows you have to work with \ as seperator, while on Linux and Mac you need / as seperator.
REMEMBER: You cannot have logging.file AND logging.path in your properties together. It is either .file OR .path ... in your case the path.
Tested 2 Minutes before posting

For spring-boot version 2.3.x and above:
logging:
level:
root: INFO
my.app: INFO
file:
path: './logs/${spring.application.name}'
name: ${logging.file.path}/my-app.log
logging.file.name :Log file name (for instance, myapp.log). Names can be an exact location or relative to the current directory.
logging.file.path: Location of the log file. For instance, /var/log.
Reference: Spring-Boot Core Properties

You can also have this configuration on your app.properties. Thats how it is working in one of my projects.
logging.path=../logs
logging.file=${logging.path}/fileName.log
So, you can have both properties and one refers to the other.

I have set logging.file=C:/usr/local/tomcat/logs/hib.log in the application.properties and the setting like below in class
private static final Logger logger = LogManager.getLogger(ChargeMasterController.class);
logger.info("Total time taken for is ---------------------------" + time + " ms");
Logs are getting printed fine in the path mentioned as logging.file.
Now I want to print my logs in 2 different files for 2 different classes(In same package), how can I set 2 logging.file in application.properties

Related

Externalized Configuration in Spring boot

I have a external configuration file(out side jar). I try to run and expected
that value in external file will override value in internal file(application.properties in \resource\ - in jar file).
I read Documentation and try this:
java -jar ccgame-1.0.jar --spring.config.location=classpath:/application.properties,file:/production.properties
This not working.
My jar file at \target\ directory and my production.properties too(at \target\)
How can I resolve my problem?
Where should I put external config file ?
And what I have to do ?
Starting from Spring Boot 2.0 it's possible to use property spring.config.additional-location. With this property, you can set external config file, but properties from that config will only override the corresponding ones from internal config, leaving other properties unchanged.
More about it in docs.
If you need to completely override the whole config, then continue to use spring.config.location property instead.
By convention, Spring Boot looks for an externalized configuration file – application.properties or application.yml – in 4 predetermined locations in the following order of precedence:
/config subdirectory of the current directory
The current directory
Classpath /config package
The classpath root
You can place your application.properties in any of the 4 locations without needing to give the location of application.properties while executing the jar. If you want to given any other custom location , then you will have to provide the path of the config location while executing the jar:
java -jar -Dspring.config.location=<path-to-file> myProject.jar
Source: https://www.baeldung.com/spring-properties-file-outside-jar

spring boot: add new yml files to application config

i want developers to be able to locally override some configuration properties. (let's say we work on google drive and everyone should test it on its own account).
i don't want to override properties using command line (because it has to be set inside every IDE configuration and on every CLI run).
what i want is: application should use all the standard spring boot config files (application.yml etc) and also look for e.g. local.yml (on the classpath) or some file inside user.home. and those additional files should override other settings.
how to add new yml resources and order them correctly?
edit: i know spring's default orders and locations. question is about adding new ones
If you look in the Spring Boot documentation about the locations for configuration files (http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config), you can see, that they are loaded from the following places (amongst others):
Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants)
Application properties outside of your packaged jar (application.properties and YAML variants).
There are two default locations where they are loaded from ( see http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-external-config-application-property-files):
A /config subdirectory of the current directory.
The current directory
Current directory in this case means the working directory for the Java process (Usually the directory where the JAR is located, or in case of running with in the IDE, usually the project root folder). So the developers just can place their own configuration files in that places and they are automatically loaded (and will override properties within the JARs). Add that files to .gitignore (or .svnignore or ...) and they won't accidentally committed into your repository.
There's a new way to do this, after Spring Boot v2.4, by using spring.config.import: https://spring.io/blog/2020/08/14/config-file-processing-in-spring-boot-2-4#importing-additional-configuration
By adding this part to your application.yml file, you should be able to import the additional configuration:
spring:
config:
import: local.yml
The article also has this section:
Imports can be considered as additional documents inserted just below the document that declares them. They follow the same top-down ordering as regular multi-document files: An import will only be imported once, no matter how many times it is declared.
So the contents of local.yml should be handled as if they were appended to the end of application.yml, thereby allowing you to override any property in application.yml.
From Spring Boot Documentation : Application property files:
SpringApplication will load properties from application.properties files in the following locations and add them to the Spring Environment:
A /config subdirectory of the current directory.
The current directory
A classpath /config package
The classpath root
The list is ordered by precedence (properties defined in locations higher in the list override those defined in lower locations).
This also goes for yaml, so you everyone can add application.yml under config directory, under the directory you run the spring boot jar from.
You can also customize the extra configuration file to be local.yml if you'd like by using spring.config.location:
--spring.config.location=classpath:/application.yml,classpath:/local.yml
Note however:
spring.config.name and spring.config.location are used very early to determine which files have to be loaded so they have to be defined as an environment property (typically OS env, system property or command line argument).
To provide the configuration from external config file in spring-boot application -
-Dspring.config.location=file:/home/vfroot/Workspace/project/MODULE_HOME/application.yaml
this command can be run with terminal:
mvn clean install -Dspring.config.location
= file:/home/vfroot/Workspace/MODULE_HOME/application.yaml
or need to set in Eclipse VM argument.
Also to set the active profiles :
-Dspring.profiles.active=dev
Well, since i am new in Spring Boot & Restfull Web Services. However, i managed to add a new .yml file to mange database and server port.
Instructions that i followed:
Project File.
Other Sources
src/main/resources
default package
right click on "default package"
add new YAML FILE
Or of YAML File option not available
5. right click on "default package"
6. then in categories: other --> File Types: YAML File

spring boot external config

I am trying to load an external properties file into my spring boot app.
initially I used #PropertySource in the config class.
but now I want to remove this annotation so the class is not dependent on the location.
so I tried to use:
java -jar my-boot-ws.war --SPRING_CONFIG_NAME=file:///Users/TMP/resources/
based on this http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html documentation but I get the following error:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder
using the annotation works fine but I would really like to move away from that.
any help on this would be great
Thanks
****** CORRECTION *******
Sorry copy paste error the above command was supposed to be:
java -jar my-boot-ws.war --spring.config.location=file:///Users/TMP/resources/
I'm not trying to change the name of the config file just add an additional location.
As explained here:
If spring.config.location contains directories (as opposed to files)
they should end in / (and will be appended with the names generated
from spring.config.name before being loaded).
I interpreted this as saying that the file ${spring.application.name}.properties would be loaded from the --spring.config.location passed in from the command line
After some more googeling I found this Spring Boot and multiple external configuration files indicating that the following is the correct usage:
java -jar my-boot-ws.war --spring.config.location=file:///Users/TMP/resources/myFile.properties
I was under the impression that the --spring.config.location would load other properties files in the directory specified. according to the post at the link I mentioned this is not the case. based on the link if the directory is specified then that is where the application.properties is searched for. but again the documentation here http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html seems to insinuate that the spring boot app will look on the class path first and if available grab the app name to get additional properties files based on that name.
however once I specified a file name everything worked fine so I guess I was mistaken.
In command line you should use below property to mention an additional boot configuration file:
--spring.config.location="file:/path/to/application.properties"
An alternative would be:
-Dspring.config.location="file:/path/to/application.properties"
Note that characters are lower case and the word separator is a period ..
Otherwise you can use an environment variable with key you used already:
In a *nix system:
export SPRING_CONFIG_NAME=file:/path/to/application.properties
In Windows OS:
set SPRING_CONFIG_NAME=file:/path/to/application.properties
It might not be a common issue, but I faced it. You also must have an application.properties inside your classpath even when you replace it with --spring.config.name (I had mine in gitignore due to sensitive information).
1) Makesure args pass inside of run method
public class GemFireTestLoaderApplication {
public static void main(String[] args) {
SpringApplication.run(GemFireTestLoaderApplication.class, args);
}
}
2) If you have configureed in xml comment or remove first
<!-- <context:property-placeholder location="classpath:config.properties" /> -->
<!-- <context:property-placeholder location="file:/data/xxx/vaquarkhan/dataLoader/config.properties" /> -->
Following command you can use to pass properties name
3.1)
java -jar GemfireTest-0.0.1-SNAPSHOT.jar --spring.config.location=file:///C:/data/xxx/vaquarkhan/dataLoader/test/config.properties
3.2)
java -jar GemfireTest-0.0.1-SNAPSHOT.jar --spring.config.location=file:///C:/data/xxx/vaquarkhan/dataLoader/test/config.properties
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html
spring.config.name=spring
spring.config.location=classpath:/config/
in side the config folder spring.properties file is available, while running the server the this properties file is not loading

Issue overriding application properties in Spring-boot (profile-specific) application launched with PropertiesLauncher

I'm having difficulty trying to override a property declared in a profile-specific application properties file on the classpath with another value declared in an overrides file on the file system.
I have an auto-configured Spring-boot application (that is, using #EnableAutoconfiguration) that has multiple profiles, which I launch using PropertiesLauncher rather than JarLauncher (the reason having to do with deployment constraints - I need to deploy an exploded directory rather than an archive into a read-only filesystem.)
Within the root of my application, I have some profile-specific application properties, for example:
application-dev.properties
application-qa.properties
application-prd.properties
And let's say, for the sake of argument that application-dev.properties contains:
foo.bar=baz
foo.baz=other
For any environment, it may be necessary to override an existing property, as well as supply an absent one (like a production password, for example), and the issue I'm seeing is with overriding properties already declared in an application-${profile}.properties file on the classpath. (Supplying properties not present in the classpath file works fine, this is not the issue.)
Say I have an overrides properties file in a file system location such as:
/local/appname/dev/overrides/application.properties
and I want to override the property, foo.bar, as well as declare a new property, foo.password.
Therefore the contents of the overrides file are:
foo.bar=overridden-value
foo.password=something
When I launch the application, I use a command line something like this:
java -Dspring.config.location=file:/local/appname/dev/overrides/
-Dspring.profiles.active=dev
org.springframework.boot.loader.PropertiesLauncher
--debug &
The issue I am seeing is that although foo.password, the property not declared in the application-dev.properties file is picked up, the override of foo.bar is ignored - I still see the value, baz from application-dev.properties rather than the value, overridden-value from /local/appname/dev/overrides/application.properties.
With the --debug option enabled, I can see the ConfigFileApplicationListener logging that it has loaded both the overrides file (from the filesystem) and the profile-specific file (from the classpath), in that order.
I'm tempted into the perhaps naïve conclusion that because the overrides file is listed first, it is being loaded first then overridden by the 'default' profile-specific file from the classpath, which is listed later. I do appreciate however, that order of listing in the log doesn't necessarily correlate with behaviour. And I have tried varying the order of paths declared on the spring.config.location property, so that classpath: is listed before file:... but this hasn't helped and I't not convinced it would anyway, given that the Spring-boot documentation clearly states that the default properties locations are always searched even if you supply a value for spring.config.location.
The Spring-boot documentation is very specific about the order that properties are resolved for a Spring-boot executable JAR, in descending order of precedence:
Command line arguments.
Java System properties (System.getProperties()).
OS environment variables.
JNDI attributes from java:comp/env
A RandomValuePropertySource that only has properties in random.*.
Application properties outside of your packaged jar (application.properties including YAML and profile variants).
Application properties packaged inside your jar (application.properties including YAML and profile variants).
#PropertySource annotations on your #Configuration classes.
Default properties (specified using SpringApplication.setDefaultProperties).
Take note of lines 6 and 7 - properties outside over properties inside your jar.
What's not stated, as far as I can see, and which may be the source of my confusion/issue, is what happens when you're not using a JAR but an exploded directory (and therefore PropertiesLauncher.)
If the behaviour of an exploded directory were consistent with what's stated for a JAR, I'd expect that the values of properties declared in /local/appname/dev/overrides/application.properties would override any of the same name declared in classpath:application-dev.properties, but this doesn't seem to be the case.
Also noted from the Spring-boot documentation (appendix C.4 on PropertiesLauncher) is mention of the loader.home property, which is described as '... [the] Location of additional properties file, e.g. /opt/app (defaults to ${user.dir})'.
So I tried using loader.home instead of spring.config.location, but to no avail.
(Update: I also tried using loader.config.location and I have two notes: it seems to want a file rather than a directory (so its behaviour is not analogous with spring.config.location), and when I did supply a file path rather than the parent directory, it still didn't help.)
Can anyone spot what I'm doing wrong, or what incorrect assumption(s) I'm making?
Thanks, Dave, your suggestion was 100% correct.
If I rename the properties file in /local/appname/dev/overrides to application-dev.properties then the property values from that file do override the ones in classpath:application-dev.properties.
I was sure I had tried this combination yesterday, but I think what must have stopped it working was when I was playing around with specifying the spring.config.location and got that wrong so it wasn't looking for the override file in the right place.

How to configure my log4j ( using Glassfish ) to log in the logs directory, not in config?

I have the following line in my log4j.properties file:
log4j.appender.logfile.File=MyApplication.log
My log file appears in MyDomain/config directory, but I would like it to land in the MyDomain/logs directory. How can I achieve that? I am not allowed to modify the startserv script.
Thanks in advance for your help!
In fact, it is log4j who resolves the variable ${catalina.home}, Glassfish declares ${catalina.home} as ${com.sun.aas.instanceRoot} that points to path/to/MyDomain/
You can declare any variable in GF environment and put it on log4j.properties, log4j will parse them when log4j is configured.
That is really useful to set server based logging configuration parameters, using same log4.properties for test and deployment
You can set the appender to use the ${com.sun.aas.instanceRoot}, but unlike some other comments it should be:
log4j.appender.logfile.File=${com.sun.aas.instanceRoot}/logs/MyApplication.log
This is the correct location for logs in the ../domains/domain{x}/logs directory.
The following is possible in Tomcat, perhaps Glassfish sets a similar environment variable pointing to it's filesystem location:
log4j.appender.logfile.File=${catalina.home}/logs/MyApplication.log
${catalina.home} is an environment/system property set by Tomcat pointing to it's install directory. Log4j is capable of expanding these, at least in the PropertyConfigurer.
You need to specify an absolute path, not a relative one (assuming Unix paths):
log4j.appender.logfile.File=/path/to/MyDomain/logs/MyApplication.log
Since in GlassFish the file lands in config and logs is its sibling, instead of
log4j.appender.logfile.File=MyApplication.log
use
log4j.appender.logfile.File=../logs/MyApplication.log
Tested on GlassFish 3.1.1 and it works.

Categories

Resources