Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Log4J for each context

Tags:

java

xml

log4j2

currently I'm using Log4J2 on WebApps, which run on Tomcat. Each webapp has to push its logs to an individual folder, named like the webapp's context.

In the webapp I implemented an ServletContextListener, which get's noticed when the Webapp Context is ready. It sets the logging path to the system property like this:

public void contextInitialized(ServletContextEvent sce) {
    context = sce.getServletContext().getContextPath();
    if(context == null || context.isEmpty()){
        context = "ROOT";
    }
    System.setProperty("WebappContext", context);
    log.info("Context \"" + context + "\" erstellt");
}

Then I use this property in log4j2.xml:

<Properties>
    <Property name="log-path">/srv/tomcat/logs/${sys:WebappContext}</Property>
</Properties>
<Appenders>
    <RollingFile name="rollingLogFile" fileName="${log-path}/out.log"
                 filePattern="${log-path}/out-%d{MMM-dd--HH-mm}.log" >
     ...
    </RollingFile>

This works fine when I deploy the first webapp. But as soon as I deploy two or more, all logs from all contexts go to the newest folder, because the system property is global for all instances. Sometimes I even get a folder named "{sys:WebappContext}", where some logs are written.

What is the right way to achieve the loggin that I want?

like image 896
user3774337 Avatar asked Jul 26 '26 21:07

user3774337


2 Answers

Try using the web context lookup instead of system lookup.

Source: https://logging.apache.org/log4j/2.0/manual/lookups.html#WebLookup

The WebLookup allows applications to retrieve variables that are associated with the ServletContext. In addition to being able to retrieve various fields in the ServletContext, WebLookup supports looking up values stored as attributes or configured as initialization parameters. The following table lists various keys that can be retrieved:

  • attr.name Returns the ServletContext attribute with the specified name
  • contextPath The context path of the web application
  • effectiveMajorVersion Gets the major version of the Servlet specification that the application represented by this ServletContext is based on.
  • effectiveMinorVersion Gets the minor version of the Servlet specification that the application represented by this ServletContext is based on.
  • initParam.name Returns the ServletContext initialization parameter with the specified name
  • majorVersion Returns the major version of the Servlet API that this servlet container supports.
  • minorVersion Returns the minor version of the Servlet API that this servlet container supports.
  • rootDir Returns the result of calling getRealPath with a value of "/".
  • serverInfo Returns the name and version of the servlet container on which the servlet is running.
  • servletContextName Returns the name of the web application as defined in the display-name element of the deployment descriptor

Example

<Appenders>
  <File name="ApplicationLog" fileName="${web:rootDir}/app.log"/>
</Appenders>
like image 52
alan7678 Avatar answered Jul 28 '26 11:07

alan7678


I typically just use a separate log4j2.xml for each web app with

<properties>
    <property name="LOG_DIR">${sys:catalina.home}/logs/AppName</property>
</properties>

However, if you want a single log4j2.xml, following alan7678's advice you should be able to add

<context-param>
    <param-name>applicationName</param-name>
    <param-value>AccountService</param-value>
</context-param>

to web.xml and then use

<properties>
    <property name="LOG_DIR">${sys:catalina.home}/logs/${web:applicationName}</property>
</properties>

However, I haven't tried this myself.

like image 43
rgoers Avatar answered Jul 28 '26 10:07

rgoers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!