Question

I have defined a Marker and would like to log this only to a specific file. Therefore I'm trying to set additivity = false. But it does not work and is still also logged to my global logfile in addition. What might be wrong here?

<Configuration>
    <Appenders>
        <RollingFile name="TEST" fileName="test.log" filePattern="test1.log">
            <MarkerFilter marker="TEST_LOG" onMatch="ACCEPT" onMismatch="DENY"/>
        </RollingFile>
        <RollingFile name="GLOBAL" fileName="global.log" filePattern="global.log">
            <ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>
            <MarkerFilter marker="TEST_LOG" onMatch="DENY" onMismatch="ACCEPT"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <logger name="foo" additivity="false">
            <appender-ref ref="TEST" />
        </logger>
    </Loggers>
</Configuration>

usage:

LogManager.getRootLogger().info(MarkerManager.getMarker("TEST_LOG"), "test log");
Was it helpful?

Solution 2

Additivity is not going to work in your case, coz additivity is controlling a specific logger not to inherit parent's appender.

In your config, you are setting logger foo to have additivity = false, which means, unless you are using foo or its children loggers for your logging, you will still follow root loggers' config. (I can't see your root logger config in your post, I suspect it is referring to both appenders). From your quoted code, you are using the root logger for your logging, the configuration of foo logger simply won't take effect.

There are two solution I can suggest:

  1. For all log messages you log with TEST_LOG marker, make sure you log it using foo logger. or,
  2. If you need to use any logger for your TEST_LOG messages, then you should reconfigure your appender, so that your GLOBAL file appender accept anything BUT TEST_LOG. (Currently you are only denying SELL_FAILURE marker)

Correct solution depends on your actual requirement. Make sure you understand the basic concepts so you can choose the right solution for you.


Edit:

First, even with your "correct" config you mentioned in the comment, the issue of different loggers still holds. Which mean, coz you are using root logger to do your logging, your config for foo logger has nothing to do with your log message, and additivity is out of picture in your case.

I am not using Log4J2, a brief check on the usage of filter lead me to two issues:

First, I believe proper way to define more than 1 filter is to make use of Composite Filter (which means defining in a <Filters> element, though I don't quite get the syntax from Log4J's doc).

Second, even you define it in composite filter, your config will still have problem. When a log event is having INFO or higher level, you declare in filter it is an ACCEPT or DENY which will prohibit subsequent filter evaluation. If you want to log messages with INFO and not containing TEST_LOG marker, you should do something like:

<MarkerFilter marker="TEST_LOG" onMatch="DENY" onMismatch="NETURAL"/>
<ThresholdFilter level="INFO" onMatch="ACCEPT" onMismatch="DENY"/>

NEUTRAL means current filter cannot determine whether to accept or deny the message, and will evaluate next filter to determine it.

OTHER TIPS

In the sample code the marker is named "TEST", but in the configuration the MarkerFilter only accepts log events with marker "TEST_LOG". Config and code should use the same string.

In addition, you probably need to define two Appenders: one for your global log file and one for your specific (marked) log events. Then ACCEPT the marked log events only in your specific appender, and DENY the marked log events in the global appender.

Couple of things I noticed:

  • You should use the same marker string in the code, and in the config for both MarkerFilters.
  • You need to add AppenderRef elements to connect your logger to both appenders
  • You can specify a level in the AppenderRef, this is easier than using a ThresholdFilter

Which gives you this config:

<Configuration>
    <Appenders>
        <RollingFile name="MARKED_ONLY" fileName="markedOnly.log" filePattern="markedOnly1.log">
            <MarkerFilter marker="MY_MARKER" onMatch="ACCEPT" onMismatch="DENY"/>
        </RollingFile>
        <RollingFile name="GLOBAL" fileName="global.log" filePattern="global.log">
            <MarkerFilter marker="MY_MARKER" onMatch="DENY" onMismatch="ACCEPT"/>
        </RollingFile>
    </Appenders>

    <Loggers>
        <root level="trace">
            <appender-ref ref="MARKED_ONLY" level="trace" />
            <appender-ref ref="GLOBAL" level="info" />
        </root>
    </Loggers>
</Configuration>

And this code:

Logger logger = LogManager.getLogger(MyClass.class); // or .getRootLogger()
logger.info(MarkerManager.getMarker("MY_MARKER"), "test log");

Note it is important to use the same "MY_MARKER" string in the code, and in the filters for both appenders. That way, the appender for the global file can use that filter to DENY the marked log events.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top