Logback.groovy LogstashEncoder altering field names
Asked Answered
P

3

8

I have a logback.groovy that sends data to a logstash on the network with some custom fields:

appender("LOGSTASH", LogstashTcpSocketAppender) {
  encoder(LogstashEncoder) {
    customFields = """{ "token": "xxxxx", "environment":"dev", "some_property":"foobar" }"""
  }
  remoteHost = "logstashlistener.host.name"
  port = 5000
}

So far so good. However, I need to cleanup some field names that are not valid for elasticsearch downstream. Based on the LogstashEncoder documentation, this can be achieved like this:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
  <fieldNames>
    <timestamp>time</timestamp>
    <message>msg</message>
    ...
  </fieldNames>
</encoder>

This seems great but I have to fit this into the logback.groovy notation. I tried as a hashmap, string and more but always end up with Cannot cast object 'xxxx' with class 'xxxx' to class 'net.logstash.logback.fieldnames.LogstashFieldNames'

Palaver answered 15/4, 2016 at 13:18 Comment(0)
S
2

Try the following. You might also need to add some import for FieldNames and LifeCycle

appender("LOGSTASH", LogstashTcpSocketAppender) {
  encoder(LogstashEncoder) {
    customFields = """{ "token": "xxxxx", "environment":"dev", "some_property":"foobar" }"""

    FieldNames... aFieldNames = new FieldNames()
    aFieldNames.timestamp = "time"
    aFieldNames.message = "msg"
    if(aFieldNames instanceof LifeCycle)
      aFieldNames.start()
    fieldNames = aFieldNames
  }
  remoteHost = "logstashlistener.host.name"
  port = 5000
}

You can use the following helper page on the Logback website to transform your XML configuration into Groovy.

http://logback.qos.ch/translator/asGroovy.html

Stupefy answered 25/4, 2016 at 5:18 Comment(1)
Interesting answer. Sadly, it doesn't really work. The FieldNames doesn't exist per se. I converted that to LogstashFieldNames and adapted the ... (that gives a compilation error) but it complains that it cannot set the timestamp property of that class.Palaver
F
1

I had to do something similar, though I was using the LoggingEventCompositeJsonEncoder encoder.

The approach I've had to use is to dig through the logstash-logback-encoder code to work out the real classes involved. Thankfully IntelliJ's decompiler makes this not too painful.

If you look at LogstashEncoder it has a method public void setFieldNames(LogstashFieldNames fieldNames) - so what you need is an instance of LogstashFieldNames

LogstashFieldNames in turn has setters for setTimestamp and the rest, so in groovy your syntax should be:

    encoder(LogstashEncoder) {
        fieldNames(LogstashFieldNames) {
            timestamp = "time"
            message = "msg"
        }
    }
Fara answered 26/8, 2016 at 8:42 Comment(0)
G
0

This works fine for me. This example rename attribute "logger_name" to "loggerName"

import net.logstash.logback.fieldnames.LogstashFieldNames

appender('STDOUT', ConsoleAppender) {   
     encoder(net.logstash.logback.encoder.LogstashEncoder) {
          
            // Rename standard fields
            fieldNames = new LogstashFieldNames(logger:"loggerName")
     }
}
Gonagle answered 27/5, 2021 at 6:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.