Not able to load LOG4J2.xml File from system environment variable - log4j2

I am doing a web application using Tomcat in eclipse and I kept the log4j2.xml file in environment variable location.
using System environment variable
Variable name : sys_logroot
Variable value : D:\user\gouse
In this directory I have my log4j2.xml file.I am trying to use this log4j2.xml file in my application I am not able to load this xml file and no log files are created to my application.
How can I load an Log4j2.xml file into my application to get logs for my application?

Apache says (from here):
How do I specify the configuration file location?
By default, Log4j looks for a configuration file named log4j2.xml (not
log4j.xml) in the classpath.
You can also specify the full path of the configuration file with this
system property:
-Dlog4j.configurationFile=path/to/log4j2.xml
i.e. you have to set the system property at runtime to let log4j use it. Something like this:
String value = System.getenv("sys_logroot");
value = "file:" + value;
System.setProperty("log4j.configurationFile", value);
Important is to call this part before using classes logging. Here is my test code:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Main {
private static final Logger logger = LogManager.getLogger(Main.class.getName());
public void doSomething() {
logger.debug("Do something");
}
}
Tester:
public class Tester {
public static void main(String[] args) {
String value = System.getenv("sys_logroot");
value = "file:" + value;
System.setProperty("log4j.configurationFile", value);
new Main().doSomething();
}
}

Related

How to pass configuration to a module

What's the right way to pass some configuration parameters to a module that I wrote for neo4j + GraphAware? I believe there should be a way that I can put some config entries in neo4j.conf and read them in my module's code but so far I could not find it.
There is definitely a possibility to pass configuration parameters to your module.
The best way is to look at other modules that use such configuration, GraphAware not being shy to open source modules (https://github.com/graphaware?utf8=%E2%9C%93&q=&type=&language=java) you can find plenty of it.
Let's take the uuid-module as an example :
In the bootstrapper class, you will find the logic for reading configuration parameters from the config file :
String uuidProperty = config.get(UUID_PROPERTY);
if (StringUtils.isNotBlank(uuidProperty)) {
configuration = configuration.withUuidProperty(uuidProperty);
LOG.info("uuidProperty set to %s", configuration.getUuidProperty());
}
https://github.com/graphaware/neo4j-uuid/blob/master/src/main/java/com/graphaware/module/uuid/UuidBootstrapper.java#L55
The found parameters are used to create an immutable Configuration class :
https://github.com/graphaware/neo4j-uuid/blob/master/src/main/java/com/graphaware/module/uuid/UuidConfiguration.java
The end of the module bootstrapping will then pass the configuration object to the constructor of the module :
return new UuidModule(moduleId, configuration, database);
https://github.com/graphaware/neo4j-uuid/blob/master/src/main/java/com/graphaware/module/uuid/UuidBootstrapper.java#L89
You can then use this module with the configuration :
public UuidModule(String moduleId, UuidConfiguration configuration, GraphDatabaseService database) {
super(moduleId);
this.uuidConfiguration = configuration;
this.uuidGenerator = instantiateUuidGenerator(configuration, database);
this.uuidIndexer = new LegacyIndexer(database, configuration);
}
https://github.com/graphaware/neo4j-uuid/blob/master/src/main/java/com/graphaware/module/uuid/UuidModule.java

Override property in application.groovy with external config in grails 3

There is no grails.config.locations property in grails 3 anymore, now Grails 3 uses Spring's property source concept instead, but how can I achieve the same behavior in grails 3 as it was in previous versions? Suppose I want to override some property property.to.be.overridden in application.grovy file with my external configuration file. How can I do it?
The equivalent of grails.config.locations is spring.config.location
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-application-property-files
Here is an example specifying configuration locations while launching a jar from the command line(These same arguments can be used inside of your ide)
java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties
Also since you mention wanting to override properties it's useful to learn the way Spring Boot handles profile specific property files(Multiple profiles may also be specified)
http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties
I solved this a slightly different way, so I could load an external YAML file.
Application.groovy
package com.mycompany.myapp
import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean
import org.springframework.context.EnvironmentAware
import org.springframework.core.env.Environment
import org.springframework.core.env.PropertiesPropertySource
import org.springframework.core.io.FileSystemResource
import org.springframework.core.io.Resource;
class Application extends GrailsAutoConfiguration implements EnvironmentAware {
static void main(String[] args) {
GrailsApp.run(Application)
}
#Override
void setEnvironment(Environment environment) {
String configPath = System.properties["myapp.config.location"]
if (configPath) {
Resource resourceConfig = new FileSystemResource(configPath);
YamlPropertiesFactoryBean propertyFactoryBean = new YamlPropertiesFactoryBean();
propertyFactoryBean.setResources(resourceConfig);
propertyFactoryBean.afterPropertiesSet();
Properties properties = propertyFactoryBean.getObject();
environment.propertySources.addFirst(new PropertiesPropertySource("myapp.config.location", properties))
}
}
}
Then I specify the YAML file when I run it
command line
java -jar -Dmyapp.config.location=/etc/myapp/application.yml build/libs/myapp-0.1.war

How to populate parameter "defaultValue" in Maven "AbstractMojoTestCase"?

I have a Maven plugin that I am attempting to test using a subclass of the AbstractMojoTestCase. The plugin Mojo defines an outputFolder parameter with a defaultValue. This parameter is not generally expected to be provided by the user in the POM.
#Parameter(defaultValue = "${project.build.directory}/someOutputFolder")
private File outputFolder;
And if I use the plugin in a real scenario then the outputFolder gets defaulted as expected.
But if I test the Mojo using the AbstractMojoTestCase then while parameters defined in the test POM are populated, parameters with a defaultValue that are not defined in the POM are not populated.
public class MyPluginTestCase extends AbstractMojoTestCase {
public void testAssembly() throws Exception {
final File pom = getTestFile( "src/test/resources/test-pom.xml");
assertNotNull(pom);
assertTrue(pom.exists());
final MyMojo myMojo = (BaselineAssemblyMojo) lookupMojo("assemble", pom);
assertNotNull(myMojo);
myMojo.execute(); // Dies due to NullPointerException on outputFolder.
}
}
Further: if I define the outputFolder parameter in the POM like so:
<outputFolder>${project.build.directory}/someOutputFolder</outputFolder>
then ${project.build.directory} is NOT resolved within the AbstractMojoTestCase.
So what do I need to do to get the defaultvalue populated when testing?
Or is this a fault in the AbstractMojoTestCase?
This is Maven-3.2.3, maven-plugin-plugin-3.2, JDK 8
You need to use lookupConfiguredMojo.
Here's what I ended up using:
public class MyPluginTest
{
#Rule
public MojoRule mojoRule = new MojoRule();
#Test
public void noSource() throws Exception
{
// Just give the location, where the pom.xml is located
MyPlugin plugin = (MyPlugin) mojoRule.lookupConfiguredMojo(getResourcesFile("basic-test"), "myGoal");
plugin.execute();
assertThat(plugin.getSomeInformation()).isEmpty();
}
public File getResourcesFile(String filename)
{
return new File("src/test/resources", filename);
}
}
Of course you need to replace myGoal with your plugin's goal. You also need to figure out how to assert that your plugin executed successfully.
For a more complete example, check out the tests I wrote for fmt-maven-plugin

access configuration/property files from src/groovy

I have a file under src/groovy and I have some properties that are in my Config.groovy and in external property file too. Normally if one want access properties its possible to use grailsApplication .configuration.property.name expression. I want to be able to access all those properties from this file that is under src/groovy directory. What I've tried so far
import grails.util.Holders
class ForkedTomcatCustomizer {
def application
void customize(Tomcat tomcat) {
println Holders.grailsApplication.config.property.name
}
}
gave me NPE saying that grailsAppliction is null
import org.codehaus.groovy.grails.web.context.ServletContextHolder as SCH
import org.codehaus.groovy.grails.web.servlet.GrailsApplicationAttributes as GA
class ForkedTomcatCustomizer {
def application
void customize(Tomcat tomcat) {
def ctx = SCH.servletContext.getAttribute(GA.APPLICATION_CONTEXT)
def grailsAppliction = ctx.grailsApplication.getObject()
println grailsAppliction.config.property.name
}
}
the same - NPE because grailsAppliction is null
Is it possible to handle this situation somehow? Thank you!
Use the below and see if it works
println Holders.config.property.name
You don't need grailsApplication when using Holders.
The examples below are probably a little more complex than what you need, but they show how to get a configuration property at build time. I use them to merge two configuration files, but you might not need to do that.
This method returns a config property when called here at the CompileEnd event.
You could define a similar method in your app's _Events.groovy file that calls your own configuration holder class.
import org.codehaus.groovy.grails.commons.ConfigurationHolder;
class KeyAndSecret{
public static String consumerKey = ConfigurationHolder.config.consumerKey;
public static String consumerSecret = ConfigurationHolder.config.consumerSecret;
}
Try like this

Logback - do not create empty log files at startup

I have a project with a lot of 'tool' classes that have their own logging. Those logfiles are created at startup of the application, but remain empty, until used.
Is it possible to tell logback that empty files should not be created at startup? But only when they are being used?
Somehow I don't find information on this topic. Thanks!
There is no official support for lazy/on-demand creation of log files in Logback's FileAppender.
However there are some known configuration workarounds that may achieve the same result. For more details see the Logback feature request 202 "FileAppender should permit lazy file creation".
My personal favorite is the variant using the LazyFileOutputStream and a custom implementation of a FileAppender. A working implementation of an LazyFileOutputStream can be found in Alessio Pollero's log4j-additions section.
An the LazyFileappender code is very simple:
public class LazyFileAppender<E> extends FileAppender<E> {
#Override
public void openFile(String file_name) throws IOException {
lock.lock();
try {
File file = new File(file_name);
boolean result = FileUtil.createMissingParentDirectories(file);
if (!result) {
addError("Failed to create parent directories for [" + file.getAbsolutePath() + "]");
}
LazyFileOutputStream lazyFos = new LazyFileOutputStream(file, append);
setOutputStream(lazyFos);
} finally {
lock.unlock();
}
}
}

Resources