0

I am trying to connect to the prometheus metrics info about how much time it takes a module to be executed. Below I am logging the amount of time it takes to create a session and then output that information. I document the time at the beggining and then at the end see the difference and then theoretically it should upload this info to prometheus, but when I go on http://localhost:8000/, I see nothing, but a blank screen.

I've tried something like this

    @Override
    public void execute() throws Exception {
        PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);

        Date startDate = Calendar.getInstance().getTime();
        IDfCollection collection = null;
        IDfSession session=null;
        CreateSession call = new CreateSession();
        try {
             session = call.privateGetSession();

            log.debug("Running test query : " + DQL_GET_TEST_RESULT, null, null);

            IDfQuery query = new DfQuery();
            query.setDQL(DQL_GET_TEST_RESULT);

            collection = query.execute(session, IDfQuery.DF_READ_QUERY);

        } catch (DfException de) {
            log.error("DFC Exception during test execution " + de.getMessage(), null, null);
        } catch (Exception e) {
            log.error("The following error ocurred: ", e);
        }
        finally {
            try {
                if (collection != null) {
                    collection.close();
                }
                call.releasesession();
            } catch (Exception e) {
                ;
            }
        }

        Date endDate = Calendar.getInstance().getTime();

        long diff = endDate.getTime() - startDate.getTime();
        prometheusRegistry.timer("processingDuration").record(diff, TimeUnit.MILLISECONDS);
}

Full code:

import java.util.Calendar;
import java.util.Date;

import com.documentum.bps.utils.PasswordUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.documentum.fc.client.DfQuery;
import com.documentum.fc.client.IDfCollection;
import com.documentum.fc.client.IDfQuery;
import com.documentum.fc.client.IDfSession;
import com.documentum.fc.common.DfException;
import com.pgi.tasks.bt.common.CreateSession;

import io.micrometer.prometheus.PrometheusConfig;
import io.micrometer.prometheus.PrometheusMeterRegistry;
import io.prometheus.client.exporter.HTTPServer;


import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;

@Component("VerifySessionCreationSpentTime")
public class VerifySessionCreationSpentTime extends AbstractTask {

    private static final Logger log = LoggerFactory.getLogger(VerifySessionCreationSpentTime.class);
    private static final String DQL_GET_TEST_RESULT = "SELECT r_object_id FROM dm_document WHERE 1=0";

    @Override
    public void execute() throws Exception {
        PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
        log.debug("VerifySessionCreationSpentTime: begin");
        System.out.println(1);

        Date startDate = Calendar.getInstance().getTime();
        IDfCollection collection = null;
        IDfSession session=null;
        CreateSession call = new CreateSession();
        try {
             session = call.privateGetSession();

            log.debug("Running test query : " + DQL_GET_TEST_RESULT, null, null);

            IDfQuery query = new DfQuery();
            query.setDQL(DQL_GET_TEST_RESULT);

            collection = query.execute(session, IDfQuery.DF_READ_QUERY);

        } catch (DfException de) {
            log.error("DFC Exception during test execution " + de.getMessage(), null, null);
        } catch (Exception e) {
            log.error("The following error ocurred: ", e);
        }
        finally {
            try {
                if (collection != null) {
                    collection.close();
                }
                call.releasesession();
            } catch (Exception e) {
                ;
            }
        }

        Date endDate = Calendar.getInstance().getTime();

        long diff = endDate.getTime() - startDate.getTime();
        prometheusRegistry.timer("processingDuration").record(diff, TimeUnit.MILLISECONDS);
        System.out.println(diff);
        log.debug("VerifySessionCreationSpentTime: end");
    }
    public static void main(String[] args) throws Exception {
        new HTTPServer(8000);
        VerifySessionCreationSpentTime task = new VerifySessionCreationSpentTime();
        task.execute();

    }

}

Jonatan Ivanov
  • 4,895
  • 2
  • 15
  • 30
Q_Q_
  • 3
  • 2

1 Answers1

0

There are many things wrong with what you are doing:

  1. You are creating a new PrometheusMeterRegistry every single time, you only need one registry in the lifecycle of your app
  2. If Spring Boot Actuator is on the classpath, it will create a registry for you, you can inject a MeterRegistry to your components
  3. You are creating a new HTTPServer, exactly how should it return anything when you did not tell it what to return?
  4. Spring Boot Actuator creates such an endpoint for you (/actuator/prometheus)
  5. You are measuring elapsed time in the wrong way, (see this article why)

How to do this right: Read the docs :)

You should end-up with something like this:

@Component
public class Demo {
    private final MeterRegistry registry;

    public Demo(MeterRegistry registry) {
        this.registry = registry;
    }

    public void execute() throws Exception {
        Timer timer = Timer.builder("demo.timer").register(registry);
        timer.record(this::executeBusinessLogic);
    }

    void executeBusinessLogic() {
        // ...
    }
}

Plus a property to enable the Prometheus endpoint:

management.endpoints.web.exposure.include=prometheus
Jonatan Ivanov
  • 4,895
  • 2
  • 15
  • 30