logginglistenerlifecycleballerina

How to log http listener start and stop in Ballerina?


For the below Ballerina code, how to add logs when starting and stopping the listener?

import ballerina/http;

listener http:Listener httpListener = new(8080);

service / on httpListener {
    resource function get greeting() returns string { 
        return "Hello, World!"; 
    }
}

Currently it does not show any logs when running the above code.


Solution

  • The logs which shows the start and stop of listeners are not added by the language because they are not always needed and sometimes it can be troublesome for developers to have them. If it is added by the language, there is no way to suppress them and gets in the way of library developers as they may not need to show them.

    Generally, Ballerina runtime handles the listeners registered to modules and their life cycle. But if we want to show logs what we can do is handle the listeners' life cycle by ourselves. We can do this as follows.

    import ballerina/http;
    import ballerina/lang.runtime;
    import ballerina/log;
    
    // remove the listener keyword here to not declare as a module listener
    http:Listener httpListener = check new (8080);
    
    // add the service as a service object declared in the module
    http:Service serviceObj = service object {
        resource function get greeting() returns string {
            return "Hello, World!";
        }
    };
    
    function init() returns error? {
        // add the below code to handle the listener dynamically by the developer
        runtime:onGracefulStop(detachAndStopListener);
        // need to register the listener with the module dynamically to activate the listening phase
        runtime:registerListener(httpListener);
        check httpListener.attach(serviceObj);
        error? startResult = httpListener.'start();
        if startResult is error {
            log:printInfo("HTTP listener startup failed.", host = "localhost", port = 8080);
            return startResult;
        } else {
            log:printInfo("Started HTTP listener.", host = "localhost", port = 8080);
        }
    }
    
    function detachAndStopListener() returns error? {
        error? stopResult = httpListener.gracefulStop();
        if stopResult is error {
            log:printInfo("HTTP listener stop failed.", host = "localhost", port = 8080);
            return stopResult;
        } else {
            log:printInfo("Stopped HTTP listener.", host = "localhost", port = 8080);
        }
        check httpListener.detach(serviceObj);
        runtime:deregisterListener(httpListener);
    }
    

    If we run the above code it shows

    time = 2023-08-22T11:43:18.543+05:30 level = INFO module = "" message = "Started HTTP listener." host = "localhost" port = 8080
    

    and when we send the SIGINT signal (Ctrl + C), it shows the below and the program ends.

    time = 2023-08-22T11:43:30.118+05:30 level = INFO module = "" message = "Stopped HTTP listener." host = "localhost" port = 8080