Is there a way to pass data or setting to log4j before it loads and then use that property within the config file.
I was assuming there is a system properties I could use:
log4j.appender.R.File=/usr/local/pfs/logs/${ws.host}/log4j.log
Where ws.host is the property I want to use.
But how can I set that value?
Also, I am in a web environment. How can I know at what point to set the property setting before log4j loads.
The default log4j PropertiesConfigurator supports variable substitution.
http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/PropertyConfigurator.html
So, you could pass system properties like this "-DmyProject.logFile="/temp/test.log" to your Java startup, and then in the properties files have "log4j.appender.R.File=${myProject.logFile}".
If working from a web environment, you might want to check out Spring's Log4jConfigListener. It uses a listener (Servlet API 2.4+) to initialization log4j ahead of other components. Even if not using Spring, you should be able to use the source as an example to easily create your own listener.
Related
I need to load a configuration property fully into java.util.Properties file in my spring boot project and then need to pass this wherever needed. With Spring boot I can load the full file and can get the access of the values though keys. But how I can load the whole configuration file into Properties object or pass the spring loaded property (not a single value rather all the values) wherever required?
My current code:
Properties myProps= new Properties();
myProps.load(resourceAsStream);
If you're looking for specific ways of loading them using Spring-boot I'd suggest looking into:
Binding properties to an object by using the #Configuration, #ConfigurationProperties and #PropertySource annotations if you want to enforce and implicitly manage type-safety at all times
The Environment interface you can #AutoWire to your classes, if you don't need to enforce type-safety at all times (you can still do it, but you're not forced to). #PropertySource can be used in this case as well to load properties outside the default default-loaded application.properties, although they'll be loaded only when the application context refreshes (e.g. they won't be available while the application is booting up)
The PropertiesLoaderUtils class, as suggested in the comments, if you want to selectively load a configuration file at runtime for example
I usually recommend the first. The result is the same as using an #AutoWired Environment, with the advantages of implicit type-safety and improved readability. You can then get the properties and write them inside your java.util.properties if you need them to be there.
However, there is more than one way to do that, both using Spring-Boot or not. Loading properties like that is also perfectly fine, although arguably not the best practice since you're using Spring-boot.
I want to have different property values in a bootstrap.yml file depending on a spring profile passed to a starting application (the same way as it works for application-{profile-name}.yml).
How is it possible?
According to the documentation it should work pretty much the same.
Changing the Location of Bootstrap Properties:
If there is an active profile (from spring.profiles.active or through the Environment API in the context you are building), properties in that profile get loaded as well, the same as in a regular Spring Boot app — for example, from bootstrap-development.properties for a development profile.
That is it should be possible to suffix the bootstrap yaml with the environment name to make it take effect.
I have few properties common to all environments (Ex. spring.jpa.properties.hibernate.ejb.interceptor) which I have kept in application.properties under resource directory.
I have DB properties defined in environment based properties file which I pass externally through command line while starting the app:
java -jar -Dspring.config.location=<path-to-file> mySpringBootProject.jar
However, spring.jpa.properties.hibernate.ejb.interceptor is not being set when I am passing properties file externally.
Do I need to define common properties even in external file?
Or is there a way I can define them in a single place which is reused when not overridden?
You can use multiple profiles to do this. For example, create property files:
application-dev.properties
application-prod.properties
application.properties
Place your environment-specific properties in the application-${env}.properties file and your common properties in application.properties.
There are multiple ways to tell spring which profiles to use, for example the --spring.profiles.active flag.
See the Spring Boot documentation for more details about the property file search order.
application.properties will normally be overridden by Boot projects. Instead, you can add a properties file in a non-conflicting location (such as src/main/resources/my/package/foo.properties) and use #PropertySource on your autoconfiguration file to add it.
Properties is a file extension for files mainly used in Java related technologies to store the configurable parameters of an application. The advantage of using properties file is, we can configure things which are environment specific (or are prone to change over a period of time) without the need of changing anything in code. Hence inheriting common properties is not a good approach. If a property seems to be static for all e.g. environments, then it shouldn't be a property.
But, it could be we have multiple development environments and production, where we would share same properties in the environments meant for development purposes and different properties for production. In this case we could create a common properties file and inherit it in all our environment specific properties files. Another scenario could be, that at the moment of development the property is same for all environments, but we would like to provide the option of changing it in the future, when required.
While accessing log4j2 Mbeans using jvisualvm, I see that the type (contextName) inside log4j2 package is a number (for me it is 1482868390). Since this goes in as 'type' while specifying Object in query, I would like to specify it to a more recognizable name that I prefer. Is there a way to set the contextName in xml configuration.
I think there is a way to do it for web applications, but I would like to set this for a standalone java application.
Yes this is possible but not in configuration. You can achieve this by subclassing one of Log4j's ContextSelectors and overriding its defaultContextName() method.
You then tell Log4j to use your ContextSelector by starting your application with system property -DLog4jContextSelector=com.yourpackage.YourContextSelector.
If you're making all loggers async, you want to subclass AsyncLoggerContextSelector, otherwise ClassLoaderContextSelector.
I need to load an environment-specific property file, and I'd like to be able to both set it from the JVM (using -D) and to provide a default value in the main properties file or, failing that, somewhere else (like the applicationContext.xml)
I'm using the new hotness Spring 3.1 with its unified property management, but I can't find a lot of info on the property system.
UPDATE:
To clarify:
<context:property-placeholder location="/WEB-INF/myapp.properties,
/WEB-INF/myapp-${deploy.env}.properties"/>
You can do it using Spring 3.1, JVM property will be put into placeholders and you can define default values using ":", for example:
${property1:defValue}
where defValue is default value, it can be overridden by JVM option -Dproperty1=newValue
You should read this API - it is pretty informative. Example here.
EDIT
As the example points to outdated version of Spring the more modern approach is illustrated here