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();
}
}
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
);