0
votes

Creating an spring-boot app with log4j2 logger and server is wildfly10/jboss7.1. I added "system property": "loglevel" from Configuration: System Properties and able to access this from spring boot application. I called this system property in log4j2.xml to set the log-level. log4j2.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration status="error" monitorInterval="30">
    <Properties>
        <Property name="basePath">D://propertieslog</Property>
    </Properties>

    <Appenders>

        <RollingFile name="fileLogger" fileName="${basePath}/acweb.log" filePattern="${basePath}/acweb-%d{yyyy-MM-dd}.log">
            <PatternLayout>
                <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>

        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
        </Console>
        <Jdbc name="databaseAppender" tableName="APPLICATION_LOG">
            <Filters>
                First deny warn, error and fatal messages
                <ThresholdFilter level="warn" onMatch="DENY" onMismatch="NEUTRAL" />
                <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL" />
                <ThresholdFilter level="fatal" onMatch="DENY" onMismatch="NEUTRAL" />
                <ThresholdFilter level="DEBUG" onMatch="DENY" onMismatch="NEUTRAL" />
                <ThresholdFilter level="INFO" onMatch="DENY" onMismatch="NEUTRAL" />
                Then accept info, warn, error, fatal and deny debug/trace
                <ThresholdFilter level="trace" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
            <ConnectionFactory class="path" method="getDatabaseConnection" />
            <Column name="LOGLEVEL" pattern="%level" />
            <Column name="LOGGER" pattern="%logger" />
            <Column name="MESSAGE" pattern="%message" />
        </Jdbc>
    </Appenders>
    <loggers>
        <Root level="${sys:loglevel:-ERROR}">
            <appender-ref ref="console" />
            <appender-ref ref="fileLogger" />
            <appender-ref ref="databaseAppender" />
        </Root>
    </loggers>

</configuration>

Controller Class:

@GetMapping("/dashboard")
    public ModelAndView welcomeMethod(HttpServletRequest request, HttpServletResponse response,
            @ModelAttribute("token") final AccessToken accessToken) {
        if(null==accessToken.getJwtToken()) { 
            logger.trace("A TRACE Message");
            logger.debug("A DEBUG Message");
            logger.info("An INFO Message");
            logger.warn("An WARN Message");
            logger.warn("Printing system property1:"+ System.getProperty("loglevel"));
            logger.error("An ERROR Message");
            logger.error("Printing system property1:"+ System.getProperty("loglevel"));
            return new ModelAndView("redirect:launchApp"); 
        } 

Issue is while changing the system property from wildfly console, it is reflecting in java class logs, but it is not reflecting in log4j2.xml. log level in log4j2.xml remains as the one which was set during application build.

set the loglevel system property set as "WARN" and build the project and deployed it. Logs are below:

[WARN ] 2018-09-26 15:13:05.787 [default task-7] WelcomeController - An WARN Message
[WARN ] 2018-09-26 15:13:05.792 [default task-7] WelcomeController - Printing system property1:WARN
[ERROR] 2018-09-26 15:13:05.793 [default task-7] WelcomeController - An ERROR Message
[ERROR] 2018-09-26 15:13:05.793 [default task-7] WelcomeController - Printing system property1:WARN

After on same deployment changed the loglevel system property to "INFO", but the logs are not changing to INFO level:

[WARN ] 2018-09-26 15:15:34.933 [default task-11] WelcomeController - An WARN Message
[WARN ] 2018-09-26 15:15:34.933 [default task-11] WelcomeController - Printing system property1:INFO
[ERROR] 2018-09-26 15:15:34.935 [default task-11] WelcomeController - An ERROR Message
[ERROR] 2018-09-26 15:15:34.935 [default task-11] WelcomeController - Printing system property1:INFO
1
How are you initializing the log4j2 log manager?James R. Perkins
I am new to these loggings and log4j2. Could you please explain about log4j2 log manager. @JamesR.PerkinsSrikanthVarma A
Generally speaking if you change a system property you'd need to reload the log manager as the configuration has already been read.James R. Perkins

1 Answers

0
votes

I don't think you can re-write the log4j2.xml via the code.

In addition to what @JamesR.Perkins said, log4j2's configuration states:

"Note that unlike Log4j 1.x, the public Log4j 2 API does not expose methods to add, modify or remove appenders and filters or manipulate the configuration in any way."

I believe you would have to re-define the log4j2 configuration.

Feel free to borrow my example to do so. If you have any questions about it, feel free to ask:

Gist link to my example

Log4j2 offers a guide in configuring the logging by Java and it's somewhat helpful... Can be a little confusing. Here's their guide.

If you know how the log4j2.xml is setup, that would help make it a little easier when reading through the guide and using my example.


A little side note...

I think you have the <ThresholdFilter> configured improperly. It is a little bit confusing until you get a hang of it.

First off, figure out exactly at what level you would like the logger to print log entries to the databaseAppender (APPLICATION_LOG).

The way I read it, you are denying everything and then accepting trace. The simplest way to do that would be:

<Jdbc name="databaseAppender" tableName="APPLICATION_LOG">
    <ThresholdFilter level="DEBUG" onMatch="DENY" onMismatch="NEUTRAL" />
    <ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY" />
    <!-- Other properties / attributes... -->
</Jdbc>

This is how it will translate:

--------------------------------
| Level   | Int value | Action |
--------------------------------
| FATAL   | 100       | DENY   |
--------------------------------
| ERROR   | 200       | DENY   |
--------------------------------
| WARN    | 300       | DENY   |
--------------------------------
| INFO    | 400       | DENY   |
--------------------------------
| DEBUG   | 500       | DENY   |
--------------------------------
| TRACE   | 600       | ACCEPT |
--------------------------------

If you referenced an appender in a logger and set a level, you are setting the minimum level.

Lets say you didn't set the ThresHold filter for Foo...

<appenders>
    <FileAppender name="Foo" fileName="theLogPath/fooLog.log" />
</appenders>
<Loggers>
    <Logger name="package.FooClass">
        <AppenderRef ref="Foo" level="INFO" />
    </Logger>
</Loggers>

This would mean that everything between Fatal and Info would be logged. If you wanted to include both Info and Warn, but ignore the rest, add a <ThresholdFilter> to the FileAppender like so:

<FileAppender name="Foo" fileName="theLogPath/fooLog.log">
    <ThresholdFilter level="ERROR" onMatch="DENY" onMisMatch="ACCEPT" />
</FileAppender>

And as long as you set the level in the <AppenderRef>, it will log everything between that level up to and including (ERROR).

Does that make sense?

If this doesn't help, let me know what I'm missing :)