Logging optional key values
You can use %replace
to replace user_uuid=
with an empty string if the value is missing (note the trailing $
in the regex, meaning "end of input"):
%-5p [%d{ISO8601,UTC}]%replace( user_uuid=%mdc{user_uuid}){' user_uuid=$', ''} %c: %m%n%rEx
As a bonus, the above will also remove the leading space if the value is missing, so you don't get two successive spaces in your log message if the value is missing.
This entry in your pattern ...
user_uuid=%mdc{user_uuid:-}
... consists of two parts:
A static 'root' (i.e. the left hand side of the assignment) this is always present in the output. The decision to include this is made when Logback initialises itself.
A value (i.e. the right hand side of the assignment), this is only present in the output if the MDC attribute
user_uuid
is populated. The decision to include this is made at runtime for each log event.
Probably not telling you anything new there but the key point is that the inclusion of the left hand side cannot be undone by any conditional logic which kicks in when evaluating each log event emitted by your application. Logback's PatternLayoutBase
walks through its given pattern and each time it comes to something conditional or derivable it evaluates it and appends the evaluated value to the pattern it is walking through. So, for your pattern; Logback has already assigned "user_uuid=" to the current StringBuilder before it even starts evaluating the MDC condition.
However, you could achieve the desired end goal by populating the user_uuid
MDC attribute with: user_uuid=<the user id>
and then change you logging pattern to simply log the MDC value without the assignment. For example:
%-5p [%d{ISO8601,UTC}] %mdc{user_uuid:-}%c: %m%n%rEx
With that pattern in place the following log invocations ...
logger.info("Does this include the user_uuid?");
MDC.put("user_uuid", "user_uuid=me ");
logger.info("Or does this include the user_uuid?");
... will emit:
INFO [2017-10-09 11:15:22,420] com.stackoverflow.SomeClassTest: Does this include the user_uuid?
INFO [2017-10-09 11:15:22,435] user_uuid=me com.stackoverflow.SomeClassTest: Or does this include the user_uuid?
Though that's a bit awkward because you have to remember to include a space at the end of the MDC value and this user_uuid
MDC value is only useful for logging within this specific pattern (whereas simply including the user_uuid
- without the left hand side and the equals operator - would be more generally useful).
If these drawbacks render this approach unuseable for you then I think you'll have to get stuck into Logback's PatternLayoutBase
or FormattingConverter
to implement some form of look-ahead or some way of amending the in-progress StringBuilder if the right hand side of an assignment returns an empty String.