In log4j I could specify a class in the properties file to log at the debug level like this:
log4j.logger.com.mycompany.mypackage.ClassName=DEBUG
How do I do this in log4j2? Note I still need to use the new property file (not xml or json).
As the log4j2 configuration documentation states
As of version 2.4, Log4j now supports configuration via properties
files. Note that the property syntax is NOT the same as the syntax
used in Log4j 1.
It then provides a substantial example for all types of configuration elements.
Concerning your question, you need to specify your loggers in a loggers element, then configure each of them. For example
loggers = mine
logger.mine.name = com.mycompany.mypackage.ClassName
logger.mine.level = DEBUG
Note that log4j2 looks for a .properties file on the classpath by default.
If a test file cannot be located the properties ConfigurationFactory
will look for log4j2.properties on the classpath.
But you can also configure the location yourself. You can use the system property
-Dlog4j.configurationFile=conf/log4j.properties
with an appropriate path.
If you are using spring boot, you can use
logging.level.com.mycompany.mypackage.ClassName=DEBUG
in application.properties.
Related
I am new to SLF4j and I don't know if the logback.xml file has loaded properly or not. The logback.xml file is in PROJECTNAME/src/main/java where all my packages are found.
My questions are:
How can I know if the configuration file has properly loaded or not
?
How can restrict the logging only from an explicit set of class,
only to avoid logging from libraries
You can add the debug="true" attribute to the <configuration> element to enable debug of the logback configuration. It will print the configuration to the console. See https://logback.qos.ch/manual/configuration.html#dumpingStatusData.
Simple answer, if the configuration file is loaded properly, you will see results in log file or console, depending on your configuration.
By default, logback searches file in src/main/resources instead of src/main/java if I remember correctly.
In the configuration file, you can define log lever on a specific logger. Normally you'll still want to see logs of the libraries, but maybe only WARN or ERROR, so you could set the root level to WARN/ERROR, and add a logger of your root package with DEBUG/INFO level.
Also, use a logback-test file (under src/test/resources) for your own dev environment.
I'm using LogBack with Slf4j.
At program startup LogBack searches the configuration file from various places and in case of finding nothing, it configures itself automatically by using BasicConfigurator.
http://logback.qos.ch/manual/configuration.html
At program startup I need to print out the used LogBack configuration file name.
How can I programmatically get the name/path of the loaded LogBack xml configuration file or some information if LogBack did not find any configuration file and configured itself automatically?
Would it be enough to set debug=true on logback.xml files? If not, following seems to work at least with logback 1.1.5 version but will create a direct dependency to logback:
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
System.out
.println(ConfigurationWatchListUtil.getConfigurationWatchList(context).getCopyOfFileWatchList().get(0));
I placed a default log4j2 config file (log4j2.xml) in my application jar.
If the user doesn't define a own config file, I want to load my default config.
I could get a stream of the default config this way:
InputStream defaultConfigStream = MyApp.class.getClassLoader().getResourceAsStream("log4j2.xml");
But that won't help me, because following code takes a full path to the config file to check its existance and to load it.
System.setProperty("log4j.configurationFile", file.toUri().toURL().toString());
How can I accomplish that? I don't want to hardcode my default config settings, like here.
Use a DomConfigurator, see: https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/DOMConfigurator.html, you can parse the XML and feed it to the configurator and when initializing logger it will automatically consider the configuration
As I found out, it's pretty simple. Like described in the documentation (point 7), Log4j2 will automatically look for a log4j2.xml on the classpath.
So if the user doesn't define a own config file, I don't call any method to load my default config.
I am using log4j for logger purpose. At the same time I am also using JXL to read/write Excel file.
But instead of writing log into log4j logger file, it is writing into jxl.log file.
What can be issue?
Looks like you have been using jxl-2.6.3.jar or similar version.
Log4j picks up the first configuration file with default file name ( i.e. log4j.xml or log4j.properties ) in your classpath if you haven't specified a specific name via JVM parameters. As jxl-2.6.3.jar contains a log4j.xml you ended up printing everything to jxl.log as defined in the log4j.xml
The best way to deal with these kind of problems is to run your application with -Dlog4j.debug JVM parameter. This would print a few line snippet when the log4j is initialized.
log4j: Using URL [jar:file:/C:/YourApp/WEB-INF/lib/jxl-2.6.3.jar!/log4j.xml] for automatic log4j configuration.
log4j: Preferred configurator class: org.apache.log4j.xml.DOMConfigurator
...{Blah Blah Blah}
There are many ways in which you can solve this problem.
Use the newer versions of jxl which doesn't contain log4j.xml.
Make sure your log4j.properties file is on top of classpath.
Remove the log4j.xml from the jxl-2.6.3.jar (Dirty solution).
Pass the configuration file name in VM parameter as -Dlog4j.configuration=log4j.properties. This would atleast make sure log4j.xml inside jxl-2.6.3.jar will not be used. (But what if another jar with same name as log4j.properties?).
Rename your log4j.properties file to log4j-yourApp.properties and add VM parameter -Dlog4j.configuration=log4j-yourApp.properties This would definitely help and this is how it should be done to avoid these kind of situations.
More details on Log4j here
Is it possible to have conditions in log4j.properties. I have a situation where I want to have logging level set to Info on production environment and DEBUG on local. Is it possible to read environment variables in log4j.properties.
No, you have to have 2 different log4j.properties file
Configuring logging is something that should happen as part of the deployment, not as part of the build, i.e. you should NOT create multiple builds for different log configurations, the risk of introducing also other differences in artifacts is to big.
Create ONE build containing a default configuration, possibly the one you want to use in production.
Implement a way to find and use an alternative configuration without changing your artifact. Most of the time this is achieved by adding an additional directory to the classpath of your application and store a log4j configuration there. You can use the default initialization of log4j by using a configuration format that has higher precedence then the one contained in the artifact. This also allows you to reconfigure logging without new deployment, which can be very helpful when troubleshooting.
Alternatively you can provide the location of the configuration file to use via a environment variable at startup: -Dlog4j.configuration=log4j-prod.xml (borrowed from Keerthi Ramanathan's answer)
You can prepare different builds and decide which log4j.propeties you want to include on build time, for example using maven params, profiles or any other way.
There is no way to declare condition in log4j.properties
No.
But just to outline some other options
a) I would encourage you to have a look at logback which provides a simple facade over log4j and you can then change your config at runtime. The relevant documentation can be found here.
b) If you have a build process in place (ant/maven) you can do the replacement as part of the build process. If you use maven you can set up a profile to build and the in the build-cycle apply filtering
c) Load the log4j files from a conf directory for each environment. The idea for that is that the files once set for an environment are changed minimally over time. You maintain both in your repository and as part of your deployment process ensure that additional/deleted files/props get added/removed.
What i would suggest as said in comment, have a separate version of log4j properties file for every environment and follow the naming convention for easy maintainance. say, for dev environment, it would be log4j-dev.xml and for production, log4j-prod.xml. Now, you can configure the appropriate file to pick up during runtime using
-Dlog4j.configuration=log4j-prod.xml
during server startup. so, that appropriate conffiguration file will be taken by log4j.
You can use programmatic configuration when using log4j, which gives you more control over what options to use in what environment. You can have your own configuration files and use your own logic to convert them into a log4j configuration. The downside is that you need to do init() somewhere in your application. This answer provides good reference.
I used a this approach when I had similar question. A default log level if nothing is explicitly specified, and option to override.
So, I added a log4j.properties file in application resources.
log4j.rootLogger=ALL, stdout
...
log4j.appender.stdout.Threshold=INFO
...
And then added more log config properties (log4j-n.properties, for n in {d, i, w, e}) defining log levels at debug, info, warning and error. Now, during startup I would supply the config file explicitly if I wanted to override the default.
java ... -Dlog4j.configuration=file:///<path>/log4j-n.properties ...
This would override any config I had in the default log4j.properties.
Later I went with this approach. I removed all the extra config files. In the log4j.properties file in resources, I used a JVM arg placeholder:
log4j.appender.stdout.Threshold=${app.log.level}
And supplied that as JVM argument.
java ... -Dapp.log.level=<LOG-LEVEL> ...
Voila!