When does log4j2 load the configuration file? - java

I read the configuration manual page https://logging.apache.org/log4j/2.x/manual/configuration.html
and it just says
Log4j has the ability to automatically configure itself during initialization. When Log4j starts it will locate all the ConfigurationFactory plugins and arrange them in weighted order from highest to lowest.
It just says When Log4j starts but it doesn't mean anything precise.
So the question is: when does log4j2 read the configuration file?

in case of web-applications (servlet 3.0 and above), log4j2 starts with your web-application. therefore you should include the log4j-web.jar this jar is a web-fragment, wich is configured to be loaded before any other web-fragments in the project. at this point log4j2 searches for a configuration-file to load
please refer to https://logging.apache.org/log4j/2.x/manual/webapp.html and take a look at the screenshot

Related

log4j1 to log4j2 bridge autoconfiguration is not being created

I followed steps for migrating log4j1 to log4j2 using bridge, https://logging.apache.org/log4j/2.x/manual/migration.html
The thing is it doesn't create automatic configuration even if I set the system property of log4j1.compatibility = true. I don't have idea what is happening because the console doesn't even show any errors that configuration file is missing.
Extra information:
It stopped logging when I replaced log4j 1.2.16 by these three jars
log4j-1.2-api-2.17.1
log4j-api-2.17.1
log4j-core-2.17.1

Not able to print logs to Tomcat's CATALINA_BASE by using log4j2

I have update our code from log4j to log4j 2.17.1 And I want to stored the log file to servers under the Apache tomcat. I am using the log4j2.properties mentioned below.
When I run the code, then the logs file is printed in under code structure(see in below attached screenshot)but I want to print the logs file in QA-Servers under apache tomcat.
Please help me to solve the issue.
TL;DR: use ${sys:catalina.base}.
The property substitution in Log4j 2.x differs from Log4j 1.x (cf. documentation). The most prominent change is that:
in Log4j 1.x ${catalina.base} is looked up in Java system properties and, if the system property does not exist, in the configuration file,
in Log4j 2.x ${catalina.base} is looked up only in the configuration file.
In both cases if the property can not be resolved the placeholder is left unchanged.
In Log4j 2.x all external property lookups must be prefixed using an appropriate prefix. The exact equivalent of Log4j 1.x behavior is ${sys:catalina.base}. Therefore you can use:
# Fallback
property.catalina.base=.
appender.rolling.fileName=${sys:catalina.base}/logs/aseq_wiptmobile_qa-1.applog

Does depedent project in java take log4j config of parent project?

I am having project A and project B, A has jar dependency of project B. I have defined log4j.xml in project A but I am not able to see logs of sub-project(B.jar) in file appender as well as tomcat server console. Does project B will take log4j.xml form parent project A or not then which config does it use?
There is one log4j config for your entire JVM (unless you're working in a containerized environment using class loaders and.... that's not what's described).
Missing log messages implies that the configuration from log4j either (a) isn't what you think it is (i.e. a different log4j.xml is being used) or (b) doesn't have the right settings for the missing log lines.
Adding the following to the JVM at startup may help:
-Dlog4j.debug
It may also be possible to browse the log4j settings via MBeans in jconsole.
If you want all apps (WAR files) in a Tomcat instance to have the same logging configs, the simple solution is to arrange that all WAR files have a copy of the same config file.
If you want the apps to share a common logging framework (with a single configuration), then you should consider using Context Selectors, as described in the Log4j 2 documentation.
Using Context Selectors
There are a few patterns for achieving the desired state of logging separation using ContextSelectors:
Place the logging jars in the container's classpath and set the system property log4j2.contextSelector to org.apache.logging.log4j.core.selector.BasicContextSelector. This will create a single LoggerContext using a single configuration that will be shared across all applications.
Place the logging jars in the container's classpath and use the default ClassLoaderContextSelector. Follow the instructions to initialize Log4j 2 in a web application. Each application can be configured to share the same configuration used at the container or can be individually configured. If status logging is set to debug in the configuration there will be output from when logging is initialized in the container and then again in each web application.
Follow the instructions to initialize Log4j 2 in a web application and set the system property or servlet context parameter log4j2.contextSelector to org.apache.logging.log4j.core.selector.JndiContextSelector. This will cause the container to use JNDI to locate each web application's LoggerContext. Be sure to set the isLog4jContextSelectorNamed context parameter to true and also set the log4jContextName and log4jConfiguration context parameters.
The exact method for setting system properties depends on the container. For Tomcat, edit $CATALINA_HOME/conf/catalina.properties. Consult the documentation for other web containers.
I don't think there is a direct equivalent in Log4j 1.x.

Ignoring log patterns of dependencies

I have a Spring Boot project with a dependency to a third party library. This library uses SLF4J with Log4j2 for logging, and has a log4j2.xml with a pattern layout defined.
The problem is that the pattern layout of this dependency is used as the pattern for my application, ignoring the layout defined in application.properties.
If I can't modify the source code of this third party lib, is possible to configure my app in order to ignore the log4j2.xml?
One solution that you can try is to define your own log4j2 configuration file and give its path in log4j.configurationFile system property. When you define your own log4j2 configuration file, you can control how much logging you want and in which pattern.
The reason behind this is - When Log4j starts it tries to locate all the ConfigurationFactory plugins and arrange them in weighted order from highest to lowest. And as per log4j2 Automation Configuration, setting system property log4j.configurationFile has highest weight.
If log4j will found configuration file using this system property, then it will not scan classpath for locating log4j2.xml file which is present in your dependent library.

Initializing Log4j within Web Context(tomcat)?

I checked log4j setup in my tomcat environment. Although there is no log4j-web.jar file in my webapp or in "common libs" folder, log4j is initialized properly. I only added log4j.properties in my classpath. And that's it, log4j is working.
I am using spring mvc, sl4j-api.jar and sl4j-jcl.jar are in my classpath.
My question is : How does log4j work properly and pickup the configuration?
You say that you used log4.properties so I will be assuming you are using log4j 1.2.x (log4 2 use log4j2.properties)
Log4 perform default initialization when log4j classes are loaded into memory within the static initializer of the LogManager class.
See the section: Default Initialization Procedure in the manual
As soon as you dropped log4j.properties into your classpath it trigger log4j logging.
This procedure will be executed in any environment (tomcat container or other).
if you want to skip this procedure please note item 1 in the procedure:
Setting the log4j.defaultInitOverride system property to any other
value then "false" will cause log4j to skip the default initialization
procedure (this procedure).
Log4Web is an extension for depending on log4j 2 so It's irrelevant in your case.
sl4j-api.jar and sl4j-jcl.jar requires log4j-over-slf4j if you what to migrate existing code to use SLF4J without changing the code itself.
If you are not interest in such migration you may ignore them.

Categories