Search code examples
javalogback

Specific logback key-value pair in format


Logback allows adding key-value pairs to events. But the only way I've found to use them is the %kvp option in the formatter, that just dumps all of the key="value" pairs.

Isn't there any way to insert the values (I don't care about logging the key), separated at specific places in the format ?

It seems to be doable with %X for MDC elements, but not for simple key pairs.

Alternatively I guess I could use MDC for this, but then I would be basically changing my value for each event. It did not seem to me it was meant for this kind of use.


Solution

  • As luck would have it I also ran into this problem today!

    It's not a fantastic solution but one way would be to use a regex like so, assuming you have a property in your key value pair list named myProperty, and assuming that, like most people, you are using the pattern encoder:

    %replace(%kvp){'.*myProperty="([^"]+)".*', '$1'}

    breaking down the regex:

    • .* - match any character 0 or more times
    • myProperty= - exact string match
    • "([^"])" - one or more of any non-double quote character which are between the next two double quotes, place into capture group 1
    • .* - any character 0 or more times

    then $1 in the second argument replaces the whole key-value string with the contents of capture group 1

    Now, we just need to remove this key-value from the %kvp output we put in our log message, it is similar. Assuming you have some additionalData field in your log message:

    additionalData={%replace(%kvp{DOUBLE}){'[\s]{0,1}myProperty="[^"]"', ''}}

    Please note this regex could leave extra whitespace in the resulting string if it is the first element. To remedy this you can wrap this regex in a second one to remove any leading whitespace:

    additionalData={%replace(%replace(%kvp{DOUBLE}){'[\s]{0,1}myProperty="[^"]"', ''}}){'^\s+', ''}

    It's terse, but you can play around with the regex at regex101 or some similar interactive tool.

    If you'd like to avoid all this regex ugliness, you can also try registering a custom conversion specifier to do the heavy lifting for you, I have not tried this route though.