Home > Mobile >  Logstash logback: combine multiple structured arguments in log message
Logstash logback: combine multiple structured arguments in log message

Time:11-30

In our domain we provide structured arguments to a log message in order to describe an object ID. If for instance an object SomeObject has three ID fields used to identify the object:


class SomeObject {
  SomeObjectId id;
  ....
}

class SomeObjectId {
  LocalDate date;
  int objectId;
  String objectLocation;
}

We use the following log set up to log all ID fields:

import static net.logstash.logback.argumentStructuredArgument.v;

log.info("Some object with ID {} {} {} is processed on {}.",
  v("date", objectId.getDate()),
  v("objectId", objectId.getObjectId()),
  v("location", objectId.getObjectLocation()),
  "someOtherArgument" // etc
);

Which generates the following JSON log output:

{
  "@timestamp": "2022-11-30T12:34:56.000 00:00",
  "@version": "1",
  "message": "Some object with ID 2022-11-30 123 NL is processed on someOtherArgument",
  "thread_name": "main",
  "level": "INFO",

  // Notice the structured arguments
  "date": "2022-11-30",
  "objectId": "123",
  "location": "NL"
}

It feels a bit cumbersome to explicitly mention every ID field at every log section in the code. Is there a way to combine the fields into the log string while at the same time having all the structured arguments added to the log message? For instance (in pseudo code) :

log.info("Some object with ID {} is processed on {}.",
  LogTags.fromId(someObjectId),
  "someOtherArgument" // etc
);

class LogTags {
  static String fromId(SomeObjectId id) {
     LogTags.forCurrentLogMessage.appendValue("date", id.getDate());
     LogTags.forCurrentLogMessage.appendValue("objectId", id.getObjectId());
     LogTags.forCurrentLogMessage.appendValue("location", id.getLocation());

     return id.getDate()   " "   id.getObjectId()   " "   id.getLocation();
  }
}

CodePudding user response:

Yes, use StructuredArguments.fields(object) (or its abbreviated form StructuredArguments.f(object))

For example:

class SomeObjectId {
  LocalDate date;
  int objectId;
  String objectLocation;

  public String toString() {
    return date   " "   objectId   " "   location;
  }
}

log.info("Some object with ID {} is processed on {}.",
  StructuredArguments.fields(someObjectId),
  "someOtherArgument" // etc
);
  • Related