Limit logging to only one jar log4j - java

I have a project which is in turn used by several other projects. I want log4j to log only my logs to a file that I have specified in the properties file. Other project use their own logging mechanisms and I have no control over them. My log4j files should not affect other project's logging. How should i configure my log4j property file?
So far what I'm doing is setting log4j.rootLogger = ERROR and for my module log4j.logger.com.xyz.myproject = INFO, FILE. Will this work without affecting other project's loggers? Or possibly limit logging to only my jar?
Thanks

It depends on the package structure of the other projects. Supposing that
loggers from other projects are created by Logger.getLogger(ClassA.class) AND
some of them rely on root logger configuration (have no specific log4j.category.loggerName settings AND
these projects contain subpackages of the package used by your project (i.e. your project's package is com.abc.def and other projects have packages deeper in the hierarchy com.abc.def.ghi THEN
changing com.abc.def logging level would affect other projects - they'll start logging on the level defined by com.abc.def.
Verify that it's not the case and you should be safe.

I suppose your jar is entirely contained in your own package (ex com.foo.mypackage). In this case, is just enough to add to your log4j configuration something like:
# Print only messages of priority WARN or above in the package com.foo
log4j.category.com.foo=WARN
# Print only messages of priority DEBUG or above in the package com.foo.mypackage
log4j.category.com.foo.mypackage=DEBUG
Regards,
M.

Related

log4j2 log file is not generating

the log file is generated when I run the code within IDE (Intellij IDEA).
as soon as I create runnable jar of the code and then try to run the jar then the logs are not generating.
I have made sure the log4j2.xml file is a part of classpath.
is there anything extra I have to do while creating jar in the Intellij IDEA?
Taken from the FAQ: How do I debug my configuration?
First, make sure you have the right jar files on your classpath. You need at least log4j-api and log4j-core.
Next, check the name of your configuration file. By default, log4j2 will look for a configuration file named log4j2.xml on the classpath. Note the “2” in the file name! (See the configuration manual page for more details.)
From log4j-2.9 onward
From log4j-2.9 onward, log4j2 will print all internal logging to the console if system property log4j2.debug is either defined empty or its value equals to true (ignoring case).
Prior to log4j-2.9
Prior to log4j-2.9, there are two places where internal logging can be controlled:
If the configuration file is found correctly, log4j2 internal status logging can be controlled by setting in the configuration file. This will display detailed log4j2-internal log statements on the console about what happens during the configuration process. This may be useful to trouble-shoot configuration issues. By default the status logger level is WARN, so you only see notifications when there is a problem.
If the configuration file is not found correctly, you can still enable log4j2 internal status logging by setting system property -Dorg.apache.logging.log4j.simplelog.StatusLogger.level=TRACE.

How to know if logback configuration file has loaded?

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.

Stop displaying logger output to console from dependencies

I have a few Maven dependencies in my Java project that clutter the console output with redundant log info. I want to disable such logging.
Setting the additivity property to false might help. But could not use it properly.
I am looking for a log4j.xml config that will only print log output (warn, error, ...) from my project and not from any dependencies.
Redirect all the third party lib logs in a target appender, use another appender for your app
log4j.rootLogger=debug,thirdPartyLibAppender
log4j.logger.com.yourapp=debug, yourAppAppender
log4j.additivity.com.yourapp=false
# define where do you want third party lib logs to land : in a file
log4j.appender.thirdPartyLibAppender=org.apache.log4j.FileAppender
log4j.appender.thirdPartyLibAppender.append=true
log4j.appender.thirdPartyLibAppender.file=/tmp/app.log
log4j.appender.thirdPartyLibAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.thirdPartyLibAppender.layout.ConversionPattern=[%p] %c:%m%n
# define where do you want your app logs to land : stdout
log4j.appender.yourAppAppender=org.apache.log4j.ConsoleAppender
log4j.appender.yourAppAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.yourAppAppender.layout.ConversionPattern=[%p] %c:%m%n
Setting additivity to false will prevent that your app logs end in the thirdPartyLibAppender
In those 2 lines, don't forget to replace com.yourapp by the top level package name
log4j.logger.com.yourapp=debug, yourAppAppender
log4j.additivity.com.yourapp=false
It looks like the log4j2.xml was overriding all other configs. As of now, I have switched that dependency off. Maybe log4j2 > log4j hence the issue. Also, XML gets a higher priority over properties as I have seen somewhere.

Condition logging level in Log4j.properties

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!

Logging in multiple files with play framework

I have java application which is running on play framework 1.2.5.
I want to do logging in such a way that every module will have its own log file and respective module logging will go in its own file.
Is that possible using play logging? or is there any other way to do it?
Any help will be greatly appreciated.
Yes of course, it's possible. You can use advanced logger setting using apache log4j. By default, Play!Framework use apache log4j for logging purpose, see this documentation.
You must enabled this advanced setting on application.conf file using the entry like :
# More logging configuration - config file located at the same level on this file
application.log.path=/log4j.properties
application.log.system.out=off
Suppose you have two modules that located on com.mymodule and com.othermodule package. so if you want to make these modules logging on different file, your log4j.properties file should be like this :
# Define logging file appender for mymodule package
log4j.appender.mymodule=org.apache.log4j.FileAppender
log4j.appender.mymodule.File=mymodule.log
log4j.appender.mymodule.layout=org.apache.log4j.PatternLayout
# Define logging file appender for othermodule package
log4j.appender.othermodule=org.apache.log4j.FileAppender
log4j.appender.othermodule.File=othermodule.log
log4j.appender.othermodule.layout=org.apache.log4j.PatternLayout
log4j.logger.com.mymodule=INFO, package1
log4j.logger.com.othermodule=INFO, package2
For more reference, try to learn from following links:
How to create different log files for different packages using same log4j logger?
Apache Log4j learning resource

Categories

Resources