In a previous article, I showed you how to log to Azure Application Insights from a Java Spring Boot Application.

When logging a lot of data for a popular application, it can be difficult to search for data related to a specific call to a method. One way to address this is to generate a unique key for each call and record that key with every entry logged by the method or by any method called by that method.

You could pass this key as a parameter to every method, and include it with each logging statement; but that is inefficient and there is a good chance you may sometimes forget to pass it. The Mapped Diagnostic Context (MDC) service provides a way for you to include one or more key-value pairs in every Application Insights logging entry made by the current method and by any methods called in-process by that method.

Imagine I have a controller class that calls a service class and I have instantiated a logger object at the top of each:

private Logger logger = LoggerFactory.getLogger(MathController.class);

and that I have a Controller method named "Add" that adds together two number and I do some logging in that method, as shown below

@GetMapping("add/{firstNumber}/{secondNumber}")
public ResponseEntity<Integer> Add(
    @PathVariable("firstNumber") Integer firstNumber, 
    @PathVariable("secondNumber") Integer secondNumber) {
        logger.info("MathController.Add() called with " + firstNumber + " and " + secondNumber);
        Integer sum = mathService.AddNumbers(firstNumber, secondNumber);
        return new ResponseEntity<Integer>(sum, HttpStatus.OK);
}

and that this method calls a service to do the work of adding together the numbers and that service also does some logging, like so:

@Override
public Integer AddNumbers(Integer firstNumber, Integer secondNumber) {
    logger.info("MathServiceImpl.AddNumbers() called with " + firstNumber + " and " + secondNumber);
    Integer sum = firstNumber + secondNumber;
    return sum;
}

I can add the following two lines to the top of my Controller's Add() method:

String requestKey = UUID.randomUUID().toString();
MDC.put("Request-Key", requestKey);

This generates a new random key on each call to the controller and stores that key in the MDC object.

The modified method now looks like this:

@GetMapping("add/{firstNumber}/{secondNumber}")
public ResponseEntity<Integer> Add(
    @PathVariable("firstNumber") Integer firstNumber, 
    @PathVariable("secondNumber") Integer secondNumber) {
        String requestKey = UUID.randomUUID().toString();
        MDC.put("Request-Key", requestKey);

        logger.info("MathController.Add() called with " + firstNumber + " and " + secondNumber);

        Integer sum = mathService.AddNumbers(firstNumber, secondNumber);
        return new ResponseEntity<Integer>(sum, HttpStatus.OK);
}

Now, every time I log from this method or any in-process calls that this method makes, it will automatically add the Request-Key name-value pair to the log entry in Application Insights. I do not need to add the MDC.put() code to the service method. Because it is called in-process, it already knows to include the extra logging information.

When I run this code and call the controller method, Application Insights will include an extra custom property, as shown in Fig. 1.

Application Insights Trace log
Fig. 1

This is a simple, low-code way to add extra information to your logging, making it easier to track and troubleshoot your application.

You can find the code for this article here.