Custom Logging in Moqui with log4j2

Custom Logs in Moqui

Use Case:

I am looking to log specific processes into a separate log file within Moqui.
Upon exploring, I came across an approach in log4j2 called fish tagging.

My Approach:

To achieve this, I am using ThreadContext.put("discriminatorId","discriminator-101") in my code to set a discriminator for the thread.

Code from test3.groovy -

final  Logger logger = LoggerFactory.getLogger(test3.class)
ThreadContext.put("discriminatorId","discriminator-101")  
logger.info("TEST Logging")

In my log4j2 configuration file, I have created a custom logger:

<Logger name="org.moqui.example.test3" level="info" additivity="false">
    <AppenderRef ref="RoutingAppender"/>
</Logger>

Alongside, a routing appender has been configured:

<Routing name="RoutingAppender">
    <Routes pattern="$${ctx:discriminatorId}">
        <Route if="$${ctx:discriminatorId} != ''">
            <RollingFile name="DmLogger" fileName="runtime/datamanager/${ctx:discriminatorId}.log" filePattern="runtime/datamanager/log-%d{yyyy-MM-dd}-%i-${ctx:discriminatorId}-%i.log">
                <PatternLayout>
                    <pattern>&lt;div class=&quot;%p&quot;&gt;%d |%-5level| %msg%n%rEx&lt;/div&gt;</pattern>
                </PatternLayout>
                <Policies>
                    <TimeBasedTriggeringPolicy/>
                    <SizeBasedTriggeringPolicy size="5 MB"/>
                </Policies>
                <DefaultRolloverStrategy max="10"/>
            </RollingFile>
        </Route>
    </Routes>
</Routing>` 

I want to avoid these logs appearing in STDOUT or any other files, hence routing to only one appender.
The above given approach addressed my issue.

Question to the Community:

Is the approach I’ve taken the correct way to address this issue? Are there any potential issues or improvements that the community suggests?

1 Like

Do you mean that for each session when the webfacade and similar user accessible code logs out to different files?

You might want to consider an approach similar to the elasticsearchlogger with a groovy file that subscribes to a log event and pushes the logs off to any place you want.

Besides the ElasticSearchLogger approach, customizing log4j2 is probably the best way to go.

Some thoughts:
This is a good excuse to learn more about how the logging facilities work in Moqui.

The basic logging utilities are largely handled in slf4j (as seen here).

As a side note:

For your extension here. I’m not sure if you’re using this in your custom code in production, but don’t be afraid to use your own domain like com.ayanco.example.test. If it’s not moqui framework code, then it’s probably better to not potentially conflict with it in the future.

1 Like

I mean to create separate logs for particular business processes, such as “file import”, if someone runs that service I want the logs to go in a separate file for easier debugging. For ex If 100 files are imported I don’t want 100 different log files, just one fileimport.log which contains logs for these 100 files.

I have studied the elasticsearchlogger but I don’t need to push logs to any external system.

I am still exploring whether to use MDC from slf4j or ThreadContext from log4j2, what are the differences and impact on performance.

Thanks for the tip but this was just a quick POC so I didn’t create a separate package and went with moqui.example.

1 Like