Add host information to logging - Enterprise Java Content management system - Hippo CMS

Add host information to logging

In a situation where you run multiple subsites, it can be very useful to know at which subsite(host) an error has occurred. You can modify your log pattern for this, to always prefix the log entry with the hostname of the subsite. Thus, for example, in your log4j2.xml use:

<Configuration packages="com.onehippo.logging">
....
<!-- hippo-site.log -->
<RollingFile name="site" fileName="${sys:catalina.base}/logs/hippo-site.log"
             filePattern="${sys:catalina.base}/logs/hippo-site.log.%d{yyyy-MM-dd}">
  <LookupFilter key="jndi:logging/contextName" value="site" onMatch="ACCEPT"/>
  <PatternLayout pattern="%host %d{dd.MM.yyyy HH:mm:ss} %-5p %t [%C{1}.%M:%L] %m%n"/>
  <Policies>
    <TimeBasedTriggeringPolicy/>
  </Policies>
</RollingFile>

This is quite easy to do by using following pattern converter plugin:

package com.onehippo.logging;

import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.AbstractPatternConverter;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.PatternConverter;
import org.hippoecm.hst.container.RequestContextProvider;
import org.hippoecm.hst.core.container.HstContainerURL;
import org.hippoecm.hst.core.request.HstRequestContext;

@Plugin(name="HostConverter", category = PatternConverter.CATEGORY)
@ConverterKeys({"host"})
public class HostPatternConverter extends AbstractPatternConverter {
    
    private static final HostPatternConverter INSTANCE = new HostPatternConverter();

    private HostPatternConverter() {
        super("host", "host");
    }

    public static HostPatternConverter newInstance(final String[] options) {
        return INSTANCE;
    }

    @Override
    public void format(final Object obj, final StringBuilder toAppendTo) {
        toAppendTo.append(getHostInfo());
    }

    private String getHostInfo() {
        final HstRequestContext context = RequestContextProvider.get();
        if (context != null) {
            final HstContainerURL baseURL = context.getBaseURL();
            if (baseURL != null) {
                return baseURL.getHostName();
            }
        }
        return "";
    }
}

 

Log4j2 starts searching for available plugins during it's initialization phase, and thus HostPatternConverter should be available at that time. It can be done by placing plugin file into same location as log4j libraries.

Compile time dependencies are required for:

 <properties>
    <log4j2.version>2.8.2</log4j2.version>
    <hippo.hst.version>5.xx.yy</hippo.hst.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j2.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.onehippo.cms7.hst</groupId>
      <artifactId>hst-commons</artifactId>
      <version>${hippo.hst.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>

Add host information to logging

In a situation where you run multiple subsites, it can be very useful to know at which subsite(host) an error has occurred. You can modify your log pattern for this, to always prefix the log entry with the hostname of the subsite. Thus, for example, in your log4j2.xml use:

<Configuration packages="com.onehippo.logging">
....
<!-- hippo-site.log -->
<RollingFile name="site" fileName="${sys:catalina.base}/logs/hippo-site.log"
             filePattern="${sys:catalina.base}/logs/hippo-site.log.%d{yyyy-MM-dd}">
  <LookupFilter key="jndi:logging/contextName" value="site" onMatch="ACCEPT"/>
  <PatternLayout pattern="%host %d{dd.MM.yyyy HH:mm:ss} %-5p %t [%C{1}.%M:%L] %m%n"/>
  <Policies>
    <TimeBasedTriggeringPolicy/>
  </Policies>
</RollingFile>

This is quite easy to do by using following pattern converter plugin:

package com.onehippo.logging;

import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.AbstractPatternConverter;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.PatternConverter;
import org.hippoecm.hst.container.RequestContextProvider;
import org.hippoecm.hst.core.container.HstContainerURL;
import org.hippoecm.hst.core.request.HstRequestContext;

@Plugin(name="HostConverter", category = PatternConverter.CATEGORY)
@ConverterKeys({"host"})
public class HostPatternConverter extends AbstractPatternConverter {
    
    private static final HostPatternConverter INSTANCE = new HostPatternConverter();

    private HostPatternConverter() {
        super("host", "host");
    }

    public static HostPatternConverter newInstance(final String[] options) {
        return INSTANCE;
    }

    @Override
    public void format(final Object obj, final StringBuilder toAppendTo) {
        toAppendTo.append(getHostInfo());
    }

    private String getHostInfo() {
        final HstRequestContext context = RequestContextProvider.get();
        if (context != null) {
            final HstContainerURL baseURL = context.getBaseURL();
            if (baseURL != null) {
                return baseURL.getHostName();
            }
        }
        return "";
    }
}

 

Log4j2 starts searching for available plugins during it's initialization phase, and thus HostPatternConverter should be available at that time. It can be done by placing plugin file into same location as log4j libraries.

Compile time dependencies are required for:

 <properties>
    <log4j2.version>2.8.2</log4j2.version>
    <hippo.hst.version>5.xx.yy</hippo.hst.version>
  </properties>

  <dependencies>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>${log4j2.version}</version>
      <scope>provided</scope>
    </dependency>
    <dependency>
      <groupId>org.onehippo.cms7.hst</groupId>
      <artifactId>hst-commons</artifactId>
      <version>${hippo.hst.version}</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>