Question

I would like to use logback MDC feature for my log name, but I get %PARSER_ERROR[X] in file name. Maybe it is impossible to assign the name for log file. In my log file pattern parameter is passed without problems. Any help would be appreciated.

Here is my logback.xml file content:

 <?xml version="1.0" encoding="UTF-8" ?>
    <configuration  scan="true" scanPeriod="60 seconds">
    <jmxConfigurator />
    <property scope="context" name="PATH_TO_LOGS" value="${catalina.base}/logs" />

       <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
   <file>${PATH_TO_LOGS}/app.log</file>

    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>ERROR</level>
    </filter>

   <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
    <fileNamePattern>${PATH_TO_LOGS}/%X{myDefinedName}.app.%i.log</fileNamePattern>
    <maxIndex>10</maxIndex>
   </rollingPolicy>

   <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
    <maxFileSize>10MB</maxFileSize>
   </triggeringPolicy>

   <encoder>
   <pattern>%d{ISO8601} %-5level [%thread] %logger{36} - [%X{myDefinedName}] - %msg%n</pattern>
  </encoder>
  </appender>

  <root level="WARN">
    <appender-ref ref="FILE"/>
  </root>

    </configuration>

EDIT: And here is my filter

private static final String NAME_TO_PASS = "myDefinedName";

    private String getParameter(ServletRequest request) {

    HttpServletRequest req = (HttpServletRequest) request;

    String parameter = req.getParameter(NAME_TO_PASS);
    HttpSession session = req.getSession();

    if(parameter != null) {
        session.setAttribute(NAME_TO_PASS, parameter);      
    } else {
        parameter = (String)session.getAttribute(NAME_TO_PASS);
    }
    return parameter;
    }

@Override
public void init(FilterConfig filterConfig) throws ServletException {   
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
        MDC.put(NAME_TO_PASS, getParameter(request));
        chain.doFilter(request, response);
    } finally {
        MDC.remove(NAME_TO_PASS);
    }
}

@Override
public void destroy() {     
}

Somewhere I read that I should use ${myDefinedName} pattern instead of %X{myDefinedName}, but I cannot check it properly, because log is created on app deploy process without MDC parameter. How to start logging only when MCD parameter is passed ?

Was it helpful?

Solution

Used SiftingAppender like in official example and it works: http://logback.qos.ch/manual/appenders.html#SiftingAppender

<configuration>

  <appender name="FILE" class="ch.qos.logback.classic.sift.SiftingAppender">
    <!-- in the absence of the class attribute, it is assumed that the
         desired discriminator type is
         ch.qos.logback.classic.sift.MDCBasedDiscriminator -->
    <discriminator>
      <key>myDefinedName</key>
      <defaultValue>unknown</defaultValue>
    </discriminator>
    <sift>
      <appender name="FILE-${myDefinedName}" class="ch.qos.logback.core.FileAppender">
        <file>${myDefinedName}.log</file>
        <append>false</append>
        <layout class="ch.qos.logback.classic.PatternLayout">
          <pattern>%d [%thread] %level %mdc %logger{35} - %msg%n</pattern>
        </layout>
      </appender>
    </sift>
  </appender>

  <root level="WARN">
    <appender-ref ref="FILE" />
  </root>
</configuration>

if that MDC value is null, then defaultValue is used as the discriminating value for log name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top