5 Replies Latest reply on Dec 19, 2017 12:40 PM by jamezp

    [AS 7.1.1 Final] Using JBoss Log4J Module + External log4j.properties(or .xml)

    pribnow

      Hello! I know this is a well documented topic so apologies in advance if my understanding here is fundamentally flawed or if the answer is obvious (this knowledge base is for sure outside of my wheel house), I did some research but was unable to find information on the particular configuration I'm looking to achieve (if possible).  Some context, all the output from every WAR in a given deployment directory of a node is currently written to the same server.log which appears defined in the standalone-full.xml. In any given deployment directory there may be several different wars being deployed e.g: a.war, b.war and c.war. The desired change is to create log4j.properties (or .xml) for each war e.g.: a-log4j.properties, b-log4j.properties, c-log4j.properties that would result in, for example,  a-server.log, b-server.log, and c-server.log. I've tested my log4j.properties file and know that it is correct. Currently, all of these wars have, as I understand it, an implicit dependency on the JBoss org.apache.log4j module. I can confirm as much by adding an exclusion for that module to my jboss-deployment-structure.xml and watch the deployment fail because it cannot initialize log4j.

       

      The change I'm hoping to achieve is to continue to use the JBoss log4j module but to provide external (re: outside the war) log4j.properties or log4j.xml in the hope of eventually doing run time log-level changes on the fly, though whether or not that is possible I'm not sure yet.

       

      Is it possible to use the provided JBoss org.apache.log4j module as well as an external log4j.properties or .xml (external in the sense that it lives outside of my WARs)? For example, I've seen many examples (and I have been able to successfully reproduce) that solve this exact issue by performing the following:

       

      1) Breaking the implicit dependency of the log4j module provided by JBoss via a jboss-deployment-structure.xml such as:


      <?xml version="1.0" encoding="UTF-8"?>
      <jboss-deployment-structure>
        <deployment>
        <exclusions>
        <module name="org.apache.log4j"/>
        </exclusions>
        </deployment>
      </jboss-deployment-structure>

       

      2) Adding the log4j.1.x.jar to my WEB-INF/lib/

       

      3) Configuring my code so that each war will reference the specific external log4j.properties via run-time parameters.


      I'm working inside a legacy code base where I'm trying to avoid adding any new dependencies to these existing wars so I'm basically trying to avoid the above second step. As it stands currently, if I remove the above first and second step (that is to say, I continue to use the jboss log4j module) then the wars will not write to my log file. When I do perform the first two steps, the wars write correctly to their specific log files.

       

      I had to summarize my particular query in a few questions it'd be:

      1) Is it possible to use both the JBoss org.apache.log4j module (thus not having to add log4j to the class path of my war) and an external log4j properties config per war?

      2) If so, what would that configuration look like?

      3) If not, why is that not possible?

       

      Thanks again for taking a look at this post, and do forgive my ignorance if I've gotten anything wrong

       

      Best regards,

       

      Brion

        • 1. Re: [AS 7.1.1 Final] Using JBoss Log4J Module + External log4j.properties(or .xml)
          jamezp

          1) Is it possible to use both the JBoss org.apache.log4j module (thus not having to add log4j to the class path of my war) and an external log4j properties config per war?

          It's possible it would work with a single WAR, but not multiple WAR's.

          3) If not, why is that not possible?

          A module uses it's own (same) class loader. This means that each WAR has a dependency on the same module and therefore uses the same class loader for the module. The issue would be if a.war is configured after b.war then b.war would be using a.war's logging configuration. Essentially the log4j LogManager is static for all deployments.

           

          If there is any chance you could upgrade to a newer version of WildFly you could either just include a log4j.properties or log4j.xml in your deployment or use per-deployment logging for each WAR.

           

          --

          James R. Perkins

          1 of 1 people found this helpful
          • 2. Re: [AS 7.1.1 Final] Using JBoss Log4J Module + External log4j.properties(or .xml)
            pribnow

            Hi James,

             

            Thank you for your response an explaining the class loading piece, that was the fundamental piece I wasn't understanding for why my current solution isn't working. If I can ask a follow up question, is the per-module class loader behavior a function of the ModuleClassLoader? or is that just specific AS 7 behavior?

             

            Thanks again,

             

            Brion

            • 3. Re: [AS 7.1.1 Final] Using JBoss Log4J Module + External log4j.properties(or .xml)
              jamezp

              Hi Brion,

              It's the way JBoss Modules works. Each module gets it's own ModuleClassLoader. Since JBoss AS 7 and WildFly use JBoss Modules that behavior will always be present.

               

              HTH,

              --

              James R. Perkins

              1 of 1 people found this helpful
              • 4. Re: [AS 7.1.1 Final] Using JBoss Log4J Module + External log4j.properties(or .xml)
                pribnow

                Hi James,

                 

                Apologies for following up after marking your answer correct, I had a follow up question that arose while conducting some additional research into WildFly. (We will be upgrading our production application server form AS 7 to WildFly in the future) If the ModuleClassLoader behavior is consistent between JBoss AS 7 and WildFly, how does the per-deployment logging, when enabled, interact with the ModuleClassLoader? I assume that the principle of one class loader per module is still the same and that the difference was in how the LogManager interacts with the individual log4j.properties?

                 

                I was trying to find some more information about how the per-deployment logging internals function but hadn't been able to find any, would you be able to share some insight into what is happening between the wars and the wildfly log4j module when I enable the per-deployment logging?

                 

                Thanks again for your help in understanding this subject

                 

                Best regards,


                Brion

                • 5. Re: [AS 7.1.1 Final] Using JBoss Log4J Module + External log4j.properties(or .xml)
                  jamezp

                  Hi Brion,

                   

                  The per-deployment logging works off of class loaders. If a logging configuration is found in a deployment a new log context is created, configured and associated with the deployments class loader. When the deployment creates a new logger it selects the log context associated with the class loader. If there is not log context associated with the deployment it will default to the system level log context.

                   

                  Another option too are logging profiles. A logging profile allows you to make runtime changes via the logging subsystem without having to redeploy your application if you need to make a configuration change.

                   

                  --

                  James R. Perkins

                  1 of 1 people found this helpful