Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I wrap some of the methods of logstash logback encoder into an inner field?

I want to be able to have some of the fields that get generated by logstash logback encoder to be wrapped within another field. Can this be done by the XML configuration inside of logback-spring.xml or do I have to implement some class and then refer to this in the configuration?

I tried reading about implementing the Factory and Decorator methods but it didn't seem to get me anywhere.

<appender name="FILE"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>/Users/name/dev/test.log
    </file>
    <rollingPolicy
        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!-- daily rollover -->
        <fileNamePattern>/Users/name/dev/log/test.%d{yyyy-MM-dd}.log
        </fileNamePattern>
        <maxHistory>30</maxHistory>
    </rollingPolicy>
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{"component":"webserver","datacenter":"ord"}
        </customFields>

    </encoder>
</appender>

The current JSON I get when something logs is:

{
  "@timestamp": "2019-07-18T18:12:49.431-07:00",
  "@version": "1",
  "message": "Application shutdown requested.",
  "logger_name":     "org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar$SpringApplicationAdmin",
  "thread_name": "RMI TCP Connection(2)-127.0.0.1",
  "level": "INFO",
  "level_value": 20000,
  "component": "webserver",
  "datacenter": "ord"
}

What I want it to be is:

{
  "@timestamp": "2019-07-18T18:12:49.431-07:00",
  "@version": "1",
  "component": "webserver",
  "datacenter": "ord",
  "data": {
    "message": "Application shutdown requested.",
    "logger_name": "org.springframework.boot.admin.SpringApplicationAdminMXBeanRegistrar$SpringApplicationAdmin",
    "thread_name": "RMI TCP Connection(2)-127.0.0.1",
    "level": "INFO",
    "level_value": 20000
  }
}

As you can see a select set of fields are wrapped withiin 'data' instead of being in outer later.

like image 227
Kirit Avatar asked Jul 19 '19 01:07

Kirit


1 Answers

Instead of using net.logstash.logback.encoder.LogstashEncoder, you'll need to use a net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder and configure its set of providers. Use the nestedField provider to create the nested data field.

Configuring LoggingEventCompositeJsonEncoder is more complex than configuring LogstashEncoder, because LoggingEventCompositeJsonEncoder starts with no providers configured, and you have to build it up with all the providers you want. LogstashEncoder is just a subclass of LoggingEventCompositeJsonEncoder with a pre-configured set of providers.

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
  <providers>
    <timestamp/>
    <version/>
    <pattern>
      <pattern>
        {
          "component": "webserver",
          "datacenter":"ord"
        }
      </pattern>
    </pattern>
    <nestedField>
      <fieldName>data</fieldName>
      <providers>
        <message/>
        <loggerName/>
        <threadName/>
        <logLevel/>
        <callerData/>
        <stackTrace/>
        <context/>
        <mdc/>
        <tags/>
        <logstashMarkers/>
        <arguments/>
      </providers>
    </nestedField>
  </providers>
</encoder>

Be sure to check out the provider configuration documentation for the various configuration options for each provider.

like image 98
Phil Clay Avatar answered Sep 28 '22 05:09

Phil Clay