How to use a correlation ID for logging in microservices in Ballerina?

87 Views Asked by At

I'm trying to develop an HTTP service in Ballerina. I need to add a correlation Id to each log entry printed in the service like mentioned in [1] for java. Is there any recommended approach to achieve this in ballerina?

[1] https://dzone.com/articles/correlation-id-for-logging-in-microservices

I was trying the following simple HTTP service.

import ballerina/http;

type Album readonly & record {|
    string title;
    string artist;
|};

table<Album> key(title) albums = table [
    {title: "Blue Train", artist: "John Coltrane"},
    {title: "Jeru", artist: "Gerry Mulligan"}
];

service / on new http:Listener(9090) {
    resource function get albums() returns Album[] {
        return albums.toArray();
    }
}
1

There are 1 best solutions below

0
On BEST ANSWER

You can implement a request interceptor to generate correlation Id from UUID generation for each request and put it into the http:RequestContext as a key-value pair. The http:RequestContext is available throughout the request life cycle. Hence whenever the logging is required, retrieve the correlation Id from the http:RequestContext. You can add http:RequestContext as resource function argument to any service type.

import ballerina/http;
import ballerina/uuid;
import ballerina/log;

type Album readonly & record {|
    string title;
    string artist;
|};

table<Album> key(title) albums = table [
    {title: "Blue Train", artist: "John Coltrane"},
    {title: "Jeru", artist: "Gerry Mulligan"}
];

function generateCorrelationId() returns string {
    return uuid:createType1AsString();
}

service class RequestInterceptor {
    *http:RequestInterceptor;

    resource function 'default [string... path](http:RequestContext ctx)
        returns http:NotImplemented|http:NextService|error? {
        string id = generateCorrelationId();
        ctx.set("correlation-id", id);

        return ctx.next();
    }
}

service http:InterceptableService / on new http:Listener(9090) {
    public function createInterceptors() returns RequestInterceptor {
        return new RequestInterceptor();
    }

    resource function get albums(http:RequestContext ctx) returns Album[] {
        log:printInfo("Correlation ID: " + ctx.get("correlation-id").toString());
        return albums.toArray();
    }
}