0

I have a Spring Boot application that is using logback for application logs. Now I've added support for logz.io to centralize the logs from multiple machines to one place. The problem is that I can't know which log is coming from which machine.

In the application database, I have a unique token that is unique for every machine where the application is running. My idea is to pre-append that token value to every log message so I can differentiate which client is sending which logs.

I can access the token value through a method in the repository that extends the JpaRepository. Logback configuration is done through the logback.xml

Edit: Each client uses its own H2 database where the value is stored.

Example of a message I currently have:

2020-03-26 07:58:13,702 [scheduling-1] INFO n.g.service.ScheduledBotService - Test message

To be:

UniqueToken123 2020-03-26 07:58:13,702 [scheduling-1] INFO n.g.service.ScheduledBotService - Test message

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
SasaFajkovic
  • 395
  • 1
  • 4
  • 16
  • 1
    how about setting this value with MDC? – Balázs Németh Mar 26 '20 at 07:19
  • 1
    Are you sure you don't want to keep it in for example an environment variable? It would be accessible at all times, without a costly database query. Not to mention it would be easy to [include it automatically](https://stackoverflow.com/questions/37667551/how-to-read-environment-variable-or-property-in-logback-xml-and-print-that-prope) in the log message, with no code required. – Kayaman Mar 26 '20 at 07:19
  • Also [this](https://stackoverflow.com/questions/1975939/read-environment-variables-from-logback-configuration-file/10109584), so you can choose whether to use a "real" env variable (e.g. `export MACHINE="foo1"`) or a Java system property `-DMACHINE="foo1"`). – Kayaman Mar 26 '20 at 07:31
  • @Kayaman Keeping it as an env variable is not an option for me. It must be red from the database. Each client has it's own small H2 database so performance isn't an issue. – SasaFajkovic Mar 26 '20 at 08:14
  • @BalázsNémeth - I'm looking into it. – SasaFajkovic Mar 26 '20 at 08:18
  • 2
    What about reading it from the database once when the application starts, then storing it in a system property? Unless you intend to change its value during the application's lifetime. – Kayaman Mar 26 '20 at 08:23

1 Answers1

1

I try Thread Context in log4j2 and it seems work for me.

Test Code

public class AppTest {

    private Logger logger = LogManager.getLogger(AppTest.class);

    @Test
    public void testMaxFromIntegerList(){

        String uniqueToken = getTokenFromJpa();

        ThreadContext.put("uniqueToken", uniqueToken); 
        logger.info("Message Set uniqueToken");

        //remove after using
        ThreadContext.remove("uniqueToken");
        logger.info("Message Clear uniqueToken");
    }

    // dummy code.
    private String getTokenFromJpa() {
        return "UniqueToken123";
    }

}

Log4j2 Config.
Be notice that in your PatternLayout, use %X{key} to include the specified key.

appender.rolling.layout.pattern = %X{uniqueToken} %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

Content in logFile.

UniqueToken123 2020-03-26 18:18:56 INFO  AppTest:30 - Message Set uniqueToken
 2020-03-26 18:18:56 INFO  AppTest:33 - Message Clear uniqueToken

You can get more about Thread Context from here

I hope it would help.

Xiao Yu
  • 244
  • 1
  • 8
  • Yes, this work but the issue is that it's only accessible to logs made from that thread. I need to find a different solution where data can be accessed from any thread. I tried also using MDC and it's the same thing. – SasaFajkovic Apr 05 '20 at 22:25