2

Context is:

I have switched from logging to file as text towards logging to stdout as json, to send the log messages as parsable json-logs to the elastic stack with kibana.

The wildfly server (version 22.0.1.Final or 26.1.3.Final) uses the jboss logger which I also switched from Textbased logging to structured parsable json logs writing them also to stdout.

The jboss logger takes the logs from our java application (with log4j2) and wraps them into it's own log message enriching it with more context.

Problem is:

the application json-logs are getting escaped by the jboss logger before appending it, therefore breaking the json format and making it unparsable for the rest of our workflow.

This is the result with the setting jboss-logger in json format & log4j2 in json format - see the key 'message' where quotation marks are escaped like \"log.level\": \"INFO\" instead of "log.level": "INFO"

{
    "timestamp": "2023-04-26T09:01:50.489+02:00",
    "sequence": 295,
    "loggerClassName": "org.jboss.logmanager.Logger",
    "loggerName": "stdout",
    "level": "INFO",
    "message": "{\"@timestamp\":\"2023-04-25T12:01:50.488Z\",\"log.level\": \"INFO\",\"message\":\"creating a new account for userid 146\", \"ecs.version\": \"1.2.0\",\"service.name\":\"my_project_x\",\"service.version\":\"5.67\",\"event.dataset\":\"my_project_x.log\",\"process.thread.name\":\"default task-2\",\"log.logger\":\"org.my_project_x.logic.AccountImpl\",\"hostname\":\"Lenovo\",\"environment\":\"develop\",\"user.id\":\"146\",\"log\":{\"origin\":{\"file\":{\"name\":\"AccountImpl.java\",\"line\":720},\"function\":\"addAccount\"}}}",
    "threadName": "default task-2",
    "threadId": 183,
    "mdc": {},
    "ndc": "",
    "hostName": "lenovo-p14s",
    "processName": "jboss-modules.jar",
    "processId": 64672
}

then I tried turning the jboss logger back to Text format while leaving the application logs as json in log4j2. Like this the application logs stay correctly in the json format:

2023-04-26 10:49:59,407 INFO  [stdout] (default task-6) {"@timestamp":"2023-04-26T10:49:59,407Z","log.level": "INFO","message":"creating a new account for userid 166.", "ecs.version": "1.2.0","service.name":"my_project_x","service.version":"5.67","event.dataset":"my_project_x.log","process.thread.name":"default task-6","log.logger":"org.my_project_x.logic.AccountImpl","hostname":"Lenovo","environment":"develop","user.id":"166","log":{"origin":{"file":{"name":"AccountImpl.java","line":720},"function":"addAccount"}}}

but I would like to have the jboss logs also in the json format, while leaving my application logs in valid json format.

Question is:

I could not find any way to disable the escaping of the application logs when turning on the json format for the jboss logger. Is there any way to have our application logs in correct json format, while also having the jboss logs in json, resulting in a valid json (application log4j2) in json (jboss log).

Any help will be appreciated.

Regards,

ps: my setup if needed

for wildfly / jboss logger

<subsystem xmlns="urn:jboss:domain:logging:8.0">
    <console-handler name="CONSOLE">
        <level name="INFO"/>
        <formatter>
            <named-formatter name="JSON"/>
        </formatter>
    </console-handler>
    <periodic-rotating-file-handler name="FILE" autoflush="true">
        <formatter>
            <named-formatter name="PATTERN"/>
        </formatter>
        <file relative-to="jboss.server.log.dir" path="server.log"/>
        <suffix value=".yyyy-MM-dd"/>
        <append value="true"/>
    </periodic-rotating-file-handler>
    <logger category="com.arjuna">
        <level name="WARN"/>
    </logger>
    <logger category="io.jaegertracing.Configuration">
        <level name="WARN"/>
    </logger>
    <logger category="org.jboss.as.config">
        <level name="DEBUG"/>
    </logger>
    <logger category="sun.rmi">
        <level name="WARN"/>
    </logger>
    <root-logger>
        <level name="INFO"/>
        <handlers>
            <handler name="CONSOLE"/>
            <handler name="FILE"/>
        </handlers>
    </root-logger>
    <formatter name="PATTERN">
        <pattern-formatter pattern="%d{yyyy-MM-dd HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
    </formatter>
    <formatter name="COLOR-PATTERN">
        <pattern-formatter pattern="%K{level}%d{HH:mm:ss,SSS} %-5p [%c] (%t) %s%e%n"/>
    </formatter>
    <formatter name="JSON">
        <json-formatter/>
    </formatter>
</subsystem>

for log4j2 (version 2.19.0) in the java application:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration packages="org.my_project_x.logging" status="WARN" strict="true" verbose="true">
    <Appenders>
        <Console name="myConsoleLog">
            <IgnoreExceptions>false</IgnoreExceptions>
            <EcsLayout serviceName="my_project_x" serviceVersion="${serverVersion}" includeOrigin="true" eventDataset="my_project_x.log">
                <KeyValuePair key="hostname" value="%hostname"/>
                <KeyValuePair key="environment" value="develop"/>
                <KeyValuePair key="user.id" value="%userId"/>
            </EcsLayout>
        </Console>
    </Appenders>

    <Loggers>
        <Logger name="org.my_project_x">
            <Level>INFO</Level>
        </Logger>
        
        <Root>
            <AppenderRef ref="myConsoleLog"/>
            <Level>WARN</Level>
        </Root>
    </Loggers>
</Configuration>
Ferdi
  • 23
  • 4
  • Does this answer your question? [Log message as json format in wildfly logs](https://stackoverflow.com/questions/59469499/log-message-as-json-format-in-wildfly-logs) – aled Apr 26 '23 at 11:41
  • Thank you, but no it doesn't answer my question. In your referenced link the problem is about "how to log in json format with wildfly". My current setup (see last sub-title of my question) already does that much, but when it appends also my java-application-json-logs, it escapes my java-application-json-log turning those logs into non-json. – Ferdi Apr 26 '23 at 13:11
  • Do you need to use a log4j configuration file? – James R. Perkins Apr 26 '23 at 13:54
  • Hi James, yes on java application side I have to use log4j2, I cannot swap it with another logging lib. – Ferdi Apr 26 '23 at 14:08

1 Answers1

2

You're using both the logging configuration in WildFly and including a logging configuration in your deployment with a handler which is writing to System.out. WildFly wraps System.out and System.err in a logger. When another log manager writes to one of the standard streams, then it's processed through the log manager.

With JSON logging you've got three options.

  1. You can accept the JSON output that WildFly outputs and remove your logging configuration from your deployment. Note that this will be the most consistent output and include logs from WildFly.
  2. You can set the direct configuration parameter to true. Do note the remarks there of how messages could still be interwined.
  3. Write your JSON output to a file instead of the console.

Do note with the second option you may end up with two different JSON formats.

James R. Perkins
  • 16,800
  • 44
  • 60
  • Thanks for the pointers, I would like to try out option 1 and 2. Could you maybe provide some sources I could follow to test out these options? It would be much appreciated. – Ferdi Apr 26 '23 at 14:28
  • 1
    1 is easy, for WildFly 26 at least, you'd just leave the log4j-core.jar out of your deployment and the configuration file too. For 2, I'm not too sure. I'm not familiar with log4j2 custom appenders at all. – James R. Perkins Apr 26 '23 at 18:15
  • 2
    For 2, just set `direct="true"` on the console appender (cf. [documentation](https://logging.apache.org/log4j/2.x/manual/appenders.html#ConsoleAppender)). – Piotr P. Karwasz Apr 26 '23 at 18:21
  • I'll update the answer as that seems like a much better approach than a custom appender. – James R. Perkins Apr 26 '23 at 20:01
  • Option 2: it worked as in bypassing the jboss logger. But like this I also dont get the benefits of added context by the jboss logger, like sequence, threadId, processId, etc. So I would like try out Opiton-1. @JamesR.Perkins how can I leave the log4j-core.jar and the configuration file (i guess you mean the log4j2.xml?) out of my deployment as you suggest? – Ferdi May 02 '23 at 11:59
  • 1
    For option 1 you need to exclude the log4j-core library, log4j-api library ad the log4j2.xml file from your deployment. If you have a jboss-deployment-structure.xml which excludes any log module exclusions, that might require modification as well. – James R. Perkins May 02 '23 at 14:24