title: Micronaut Log4j2 Custom HTTP Header logging
body: <p>I want to inject my custom &quot;X-RequestId&quot; (the header will always be provided) header into each and every log message. I'm using Micronaut 3.1.0 and log4j2. I want this to be thread safe, meaning - this must work with multiple threads and across multiple micro-services</p>
  <p>Here is my config:</p>
  <p>log4j2.xml (resource)</p>
  <pre><code>&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  &lt;Configuration status=&quot;info&quot; name=&quot;Demo&quot; packages=&quot;request.scope.issue&quot;&gt;
      &lt;Appenders&gt;
          &lt;Console name=&quot;STDOUT&quot;&gt;
              &lt;PatternLayout&gt;
                  &lt;pattern&gt;
                      %date{MM-dd HH:mm:ss,SSS} %-5level %logger{36} - %msg%n
                  &lt;/pattern&gt;
              &lt;/PatternLayout&gt;
          &lt;/Console&gt;
      &lt;/Appenders&gt;
      &lt;Loggers&gt;
          &lt;Root level=&quot;info&quot;&gt;
              &lt;AppenderRef ref=&quot;STDOUT&quot;/&gt;
          &lt;/Root&gt;
      &lt;/Loggers&gt;
  &lt;/Configuration&gt;
  </code></pre>
  <p>LogFactoryConfig</p>
  <pre><code>@Filter(Filter.MATCH_ALL_PATTERN)
  public class LogFactoryConfig implements LogEventFactory, HttpServerFilter {
  
      @Inject
      RequestScopedBean requestScopedBean;
  
      @Override
      public LogEvent createEvent(String loggerName, Marker marker, String fqcn, Level level, Message data, List&lt;Property&gt; properties, Throwable t) {
          //i get a nullpointer since i cannot inject the RequestScopedBean
          Message enrichedMessage = new MementoMessage(requestScopedBean.getxHeader() + &quot; &quot; + data.getFormattedMessage(), data.getFormat(), data.getParameters());
          return new Log4jLogEvent(loggerName, marker, fqcn, level, enrichedMessage, properties, t);
      }
  
      @Override
      public Publisher&lt;MutableHttpResponse&lt;?&gt;&gt; doFilter(HttpRequest&lt;?&gt; request, ServerFilterChain chain) {
          //the x-header will always be provided
          requestScopedBean.setxHeader(request.getHeaders().get(&quot;X-RequestId&quot;));
          return chain.proceed(request);
      }
  
      @Override
      public Publisher&lt;? extends HttpResponse&lt;?&gt;&gt; doFilter(HttpRequest&lt;?&gt; request, FilterChain chain) {
          //the x-header will always be provided
          requestScopedBean.setxHeader(request.getHeaders().get(&quot;X-RequestId&quot;));
          return chain.proceed(request);
      }
  }
  </code></pre>
  <p>RequestScopedBean</p>
  <pre><code>@RequestScope
  public class RequestScopedBean {
  
      private String xHeader;
  
      public RequestScopedBean() {
      }
  
      public RequestScopedBean(String xHeader) {
          this.xHeader = xHeader;
      }
  
      public String getxHeader() {
          return xHeader;
      }
  
      public void setxHeader(String xHeader) {
          this.xHeader = xHeader;
      }
  }
  </code></pre>
  <p>log4j2.component.properties (resource) - this is needed for the LogFactoryConfig to get recognized</p>
  <pre><code>Log4jLogEventFactory = request.scope.issue.LogFactoryConfig
  </code></pre>
  <p>I'm kinda stuck and unable to go further with this. I also tried the ThreadContext.put() method but this won't work if multiple threads are used to finish the request. The goal is to get a log message like this for each and every request and the following log messages:</p>
  <p>No additional request id header:</p>
  <pre><code>11-22 16:11:50,685 INFO  io.micronaut.runtime.Micronaut - Startup completed in 623ms. Server Running: http://localhost:8080
  </code></pre>
  <p>If a request kicks in (<strong>REQUEST_ID</strong> - the id which is provided for each request should be logged out) -&gt; see the log factory config:</p>
  <pre><code>11-22 16:11:50,685 INFO  io.micronaut.runtime.Micronaut - **REQUEST_ID** Startup completed in 623ms. Server Running: http://localhost:8080
  </code></pre>