We are upgrading our Java application from log4j 1x to 2x.
In 1x we had an extension to RollingFileAppender specified in log4j.properties. As well as rolling the files, it would compute the path of the logs directory according to whether it was running in JBoss/Tomcat/Webserver, and file the logs there with a specific name.
It is not possible to extend RollingFileAppender in 2x.
My question is: What can I specify in log4j2.properties (or XML if necessary) that will allow me to set the log directory programmatically as before, and roll the files.
It's something like this question, but without having to set up an Environment Variable for every installation, if possible.
Log4j2 customize file path with rollingFileAppender (Java)
Log4j 2.x is very extensible. In your case you can write a StrLookup that computes the parameters you require and annotate it with:
#Plugin(name="some_prefix", category="Lookup")
The class must be compiled using the annotation processor in log4j-core and can be used in a configuration file as:
${some_prefix:key}
where key is the value that will be passed to StrLookup#lookup.
Related
I have several classes within a package and several packages within my project.
For those files that are inherited, within the parent class is
{ // File location for log4j2.xml
System.setProperty("log4j.configurationFile",
"file:\\\\" + System.getProperty("user.dir") + "\\Properties\\log4j2.xml");
}
And yet, I see ERROR StatusLogger No log4j2 configuration file found. Using default configuration: logging only errors to the console. Set system property 'log4j2.debug' to show Log4j2 internal initialization logging.
So, obviously, once isn't enough.
So what is the general rule that I need to set the system property of log4j.configurationFile?
Once per package?
Once per class?
Each parent/base class, regardless of the package?
Or something else?
What's best practice for multiple classes and packages?
Log4j 2 configures itself on initialisation i.e. whenever a Logger instance is first created within an instance of a JVM, approximately ... the first class in your application which declares a Logger instance causes Log4j 2 to initialise itself. So, the answer to this question ...
How often do you need to set the configuration file for log4j2?
... is once.
The issue reported in your OP: No log4j2 configuration file found. Using default configuration is caused by Log4j being unable to find the configuration file you attempted to point it at. This issue is not caused by not 'setting the configuration file' often enough.
According to the docs Log4j will look for its configuration source as follows:
Log4j will inspect the "log4j.configurationFile" system property and, if set, will attempt to load the configuration using the
ConfigurationFactory that matches the file extension.
If no system property is set the properties ConfigurationFactory will look for log4j2-test.properties in the classpath.
If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or log4j2-test.yml in the classpath.
If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or log4j2-test.jsn in the classpath.
If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the classpath.
If a test file cannot be located the properties ConfigurationFactory will look for log4j2.properties on the classpath.
If a properties file cannot be located the YAML ConfigurationFactory will look for log4j2.yaml or log4j2.yml on the
classpath.
If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or log4j2.jsn on the classpath.
If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml on the classpath.
If no configuration file could be located the DefaultConfiguration will be used. This will cause logging output to go to the console.
If your attempt to set log4j.configurationFile was successful then option 1 would be engaged but that attempt is not successful, we know this because the error message you quote tells us that Log4j is falling through to option 10.
I would suggest running your application with -Dlog4j.configurationFile=/path/to/log4j2.xml or ensuring that the log4j2.xml is on your application's classpath. The idea of littering your code with System.setProperty(...) calls feels like an anti pattern and is likely to be quite brittle since any static Logger which is instanced before the System.setProperty(...) call will result in Log4j initialising itself before it knows about your config file location.
My Java application uses SLF4J which I have configured to use the SimpleLogger implementation and redirect log messages to a file. That is working fine.
How do I subsequently change the name of the log file?
I have tried changing the LOG_FILE_KEY property but it seems to have no effect. The log messages continue to be output to the original log file.
This is what I've done:
System.setProperty(org.slf4j.impl.SimpleLogger.LOG_FILE_KEY, Paths.get("new-filename.txt").toString());
To set the file path to your liking, one simply has to set the following property, either in a file named simplelogger.properties on the classpath (e.g. by placing such a file under the resources directory) or through a -D JVM startup option.
The property name and syntax is simply:
org.slf4j.simpleLogger.logFile=your-file-path
See in this related answer for examples of providing a property through either of the two mentioned methods.
I think I figured out the answer with the help of this answer and looking at the source code for org.slf4j.impl.SimpleLogger.
The answer is you can't create a new log file as the logger properties are loaded only once - upon construction of the first logger instance. Subsequent loggers will use the same properties as the first one.
My code has a dependency on abc.jar file which internally uses log4j.jar and needs a configuration file. This configuration is used to set some of the required fields like ssl protocol, cert validate, port and also has a parameter, named debug, which is read by log4j.properties file (inside the abc.jar) to set the level of the logging.
The value of the debug parameter is restricted to all or none. Also, the abc.jar file has its own (custom) Logger class. So whenever I create an object of org.apache.log4j.Logger class, it creates object of the (custom) Logger class inside the abc.jar file. I guess because of this Log4j is unable to read my log4j.properties file.
I want to use my own log4j.properties file so that I can specify the level of logging. How can I do this?
You can set the property log4j.configurationFile to set the path of your config file you want to use.
On command line, you can write -Dlog4j.configurationFile=<path>
Doing that disables automatic configuration and use your manually set file for configuration
Have you seen this post? Uses PropertyConfigurator to set the log4j path in any init() like method.
Where to put the logback.xml file in Tomcat when we want to have it configurable?
And how to make it accessible for the Java application(s) running inside?
You typically want to have logback.xml on the classpath. Per the Logback FAQ:
For web-applications, configuration files can be placed directly under WEB-INF/classes/.
You therefore need to put it in:
/webapps/your-app/WEB-INF/classes/
Logback has some conventions for where it looks for it. Those are documented here.
Logback tries to find a file called logback.groovy in the classpath.
If no such file is found, logback tries to find a file called logback-test.xml in the classpath.
If no such file is found, it checks for the file logback.xml in the classpath..
If neither file is found, logback configures itself automatically using the BasicConfigurator which will cause logging output to be
directed to the console.
But you can also tell it where to find the file.
You may specify the location of the default configuration file with a
system property named "logback.configurationFile". The value of this
property can be a URL, a resource on the class path or a path to a
file external to the application.
java -Dlogback.configurationFile=/path/to/config.xml chapters.configuration.MyApp1
Note that the file extension must be ".xml" or ".groovy". Other
extensions are ignored. Explicitly registering a status listener may
help debugging issues locating the configuration file.
I have a java app and I'm using axis to make soap calls. Does anybody know how I can tell Axis to use my log4j.xml file located in my projects base directory instead of its internal properties?
Just make log4j.xml available in your classpath and log4j will pick it up. I know the name it looks for is log4j.properties if you are using properties file but not sure what is the standard name it looks for when you are using xml based configuration.