user1884155
user1884155

Reputation: 3736

Group the logging inside a java servlet per user / per request

I have a simple servlet that does some calculations, and logs the intermediate results to a file using slf4j as the facade and a simple logging binder (also from slf4j) to log to the file. This works fine, but when multiple users are sending requests simultaneously, their logs get interwoven with each other. Below is a dummy example to show the problem: the logging from both user alice and bob gets mixed up:

log: phase1 of user alice
log: phase2 of user alice
log: phase1 of user bob
log: phase3 of user alice
log: phase2 of user bob
log: phase3 of user bob
...

This is really troublesome if the amount of users involved and the complexity of the log statements increases.

A possible solution is to create a logfile for each user, and when a request enters by user X (this can be detected by my code), append it to logfile X. The problem is I don't see how to do this with simple logging. Is is possible, and if not, is there another way?

Upvotes: 1

Views: 629

Answers (2)

BretC
BretC

Reputation: 4199

You might want to look at the "MDC" (Mapped Diagnostic Context) class in SLF4J (other logging frameworks also support this).

It allows you to set custom logging context data and then you can get that data to appear in your messages.

For example, you could do...

import org.slf4j.MDC;

...
    private static final USER_NAME_MDC_KEY = "USRKEY";

    servlet method {
        MDC.put(USER_NAME_MDC_KEY, user.getUserId());

        ...rest of logic...

    }

If you have a pattern set up like this...

        <PatternLayout pattern="[UID=%X{USRKEY}] %d{HH:mm} [%t] %-level %c{1} - %m%n" />

...then each line in your log will contain...

[UID=<whatever has been set in the MDC>]

You could then GREP your logs for the particular user Id in order to get the messages logged just for them.

(I think this is sort of what you wanted, I might be wrong!)

Upvotes: 1

John
John

Reputation: 5287

You could store entries for each user phase in some structure and then log all phases as single log entry at the end of last phase, or immediately when/if an error happens.

Upvotes: 1

Related Questions