I have method where I want to add specific logging:
@Slf4j
@Service
public class SomethingService {
public void doSomething(Something data, String comment, Integer limit) {
Long id = saveSomethingToDatabase(data, comment);
boolean sentNotification = doSomething(id);
// ...
// Log what you done.
// Variables that always have important data: data.getName(), id
// Variables that are optional: sentNotification, comment, limit
// (optional means they aren't mandatory, rarely contains essential data, often null, false or empty string).
}
}
I can simply log all:
log.info("Done something '{}' and saved (id {}, sentNotification={}) with comment '{}' and limit {}",
something.getName(), id, sentNotification, comment, limit);
// Done something 'Name of data' and saved (id 23, sentNotification=true) with comment 'Comment about something' and limit 2
But most of the time most of the parameters are irrelevant. With the above I get logs like:
// Done something 'Name of data' and saved (id 23, sentNotification=false) with comment 'null' and limit null
That makes logs hard to read, long and unnecessarily complicated (in most cases other parameters aren't present).
I want to handle all cases with preserving only essential data. Examples:
// Done something 'Name of data' and saved (id 23)
// Done something 'Name of data' and saved (id 23) with comment 'Comment about something'
// Done something 'Name of data' and saved (id 23) with limit 2
// Done something 'Name of data' and saved (id 23) with comment 'Comment about something' and limit 2
// Done something 'Name of data' and saved (id 23, sent notification)
// Done something 'Name of data' and saved (id 23, sent notification) with limit 2
// Done something 'Name of data' and saved (id 23, sent notification) with comment 'Comment about something'
// Done something 'Name of data' and saved (id 23, sent notification) with comment 'Comment about something' and limit 2
I can code it by hand:
String notificationMessage = sentNotification ? ", sent notification" : "";
String commentMessage = comment != null ? String.format(" with comment '%s'", comment) : "";
String limitMessage = "";
if (limit != null) {
limitMessage = String.format("limit %s", limit);
limitMessage = comment != null ? String.format(" and %s", limitMessage) : String.format(" with %s", limitMessage);
}
log.info("Done something '{}' and saved (id {}{}){}{}",
something.getName(), id, notificationMessage, commentMessage, limitMessage);
But it's hard to write, hard to read, complicated and causes errors.
I would like something like specify part of logs.
Example pseudocode:
log.info("Done something '{}' and saved (id {} $notification) $parameters",
something.getName(), id,
$notification: sentNotification ? "sent notification" : "",
$parameters: [comment, limit]);
It should supports optional parameters, replace boolean/condition with given string, supports separating spaces, commas and words with
and and
.
Maybe are there existing library for this? Or maybe is there at least a simpler way for coding this?
If not, it remains for me nothing else to write my own library for messages to logging. Additionally, this kind of library will provide that all logs would be consistent.
If you don't see a problem with three optional parameters, just imagine there are more (and you can't always pack them into a class - another class layer only for parameter logging cause even more complications).
At the end, I know I can log each action separately. But with this I get many more logs and I won't have the most important information in one place. Other logs are in the debug
level, not info
.