Home > OS >  Is it possible to filter key-value pairs of a ThreadContextMap with a Regex?
Is it possible to filter key-value pairs of a ThreadContextMap with a Regex?

Time:01-06

Hi all & Happy New Year!

I wish to filter certain logs if the "env" key in the ThreadContextMap has a value of prod1 or qa1. I already have something like the following set up:

<Console name="prodOutput" target="SYSTEM_OUT">
    <PatternLayout pattern="..."/>
    <Filters>
        <ThreadContextMapFilter onMatch="DENY" onMismatch="NEUTRAL" operator="or">
            <KeyValuePair key="ENV" value="qa1"/>
            <KeyValuePair key="ENV" value="prod1"/>
        </ThreadContextMapFilter>
    </Filters>
</Console>

But this code "hardcodes" the values prod1 & qa1. In spirit of making the code extensible, I wanted to filter out those logs if they match the regex of "prod\d " or "qa\d ".

Values that would match these regex's include "prod1", "qa2".

This is because we don't want those certain logs to appear on production & qa environments

In the ThreadContextMap, the key-value pairs we're checking for is ENV-prod1 or ENV-qa1.

I tried searching on StackOverflow as well as the log4j2 documentation but there doesn't seem to be any mention of how such a thing can be done.

Would anyone have any ideas on how I can approach this? Thanks for any inputs :) Am open to alternative ideas as well!

CodePudding user response:

I managed to find a workaround solution, where I instead apply the regex to the value being inserted into the ThreadContextMap

This way, I only ever have to check for 2 values in the ThreadContextMapFilter, prod & qa

This solution is satisfactory enough as it works & meets the requirements we had. For those curious, it looks something like this:

@Value("${env}")
private String environment;
...
// check environment against regex
boolean matchesProdRegex = Pattern.matches(".*prod.*", this.environment);
boolean matchesQaRegex = Pattern.matches(".*qa.*", this.environment);
if (matchesProdRegex ) {
  ThreadContext.put("ENV", "prod");
} else if (matchesQaRegex ) {
  ThreadContext.put("ENV", "qa");
} else {
  ThreadContext.put("ENV", this.environment);
}

Consequently in log4j2.xml, the ThreadContextMapFilter looks something like:

<Console name="prodOutput" target="SYSTEM_OUT">
    <PatternLayout pattern="..."/>
    <Filters>
        <ThreadContextMapFilter onMatch="DENY" onMismatch="NEUTRAL" operator="or">
            <KeyValuePair key="ENV" value="qa"/>
            <KeyValuePair key="ENV" value="prod"/>
        </ThreadContextMapFilter>
    </Filters>
</Console>

Thanks to anyone that took the time to read my post & hope this can be a useful reference for anyone in the future, cheers!

  • Related