pvgoddijn
pvgoddijn

Reputation: 12898

Enable Micrometer TomcatMetrics without spring (how to get tomcat manager)

I want to plug in the Micrometer TomcatMetrics metrics class into an existing tomcat application that doesn't have Spring integration

From the looks of the source that seems quite possible by just calling

 public static void monitor(MeterRegistry registry, @Nullable Manager manager, String... tags) 

However, I can't seem to figure out how to get a hold of the org.apache.catalina.Manager instance.

Without the manager (null) it works but lacks session info which i would like to have.

So how do a get a hold of it in a proper way (servletContextListener or something)

Upvotes: 4

Views: 2344

Answers (2)

Cristian Florescu
Cristian Florescu

Reputation: 1816

Sample micrometer.jsp page for Prometheus registry with JVM and Tomcat metrics.

Include in your app classloader micrometer jars (Ex. micrometer-core-1.8.2.jar, micrometer-registry-prometheus-1.8.2.jar)

<%@ page contentType="text/plain" trimDirectiveWhitespaces="true" %>
<%@ page import="io.micrometer.prometheus.PrometheusMeterRegistry" %>
<%@ page import="io.micrometer.prometheus.PrometheusConfig" %>
<%@ page import="io.prometheus.client.exporter.common.TextFormat" %>
<%@ page import="io.micrometer.core.instrument.binder.jvm.ClassLoaderMetrics"%>
<%@ page import="io.micrometer.core.instrument.binder.jvm.JvmMemoryMetrics"%>
<%@ page import="io.micrometer.core.instrument.binder.jvm.JvmGcMetrics"%>
<%@ page import="io.micrometer.core.instrument.binder.system.ProcessorMetrics"%>
<%@ page import="io.micrometer.core.instrument.binder.jvm.JvmThreadMetrics"%>
<%@ page import="io.micrometer.core.instrument.binder.tomcat.TomcatMetrics"%>
<%@ page import="org.apache.catalina.core.ApplicationContextFacade"%>
<%@ page import="java.lang.reflect.Field"%>
<%@ page import="org.apache.catalina.core.ApplicationContext"%>
<%@ page import="org.apache.catalina.core.StandardContext"%>
<%
    PrometheusMeterRegistry prometheusRegistry = new PrometheusMeterRegistry(PrometheusConfig.DEFAULT);
    prometheusRegistry.config().commonTags("application", "myset-worker");
    //prometheusRegistry.config().meterFilter(new PrometheusRenameFilter());

    // JVM metrics
    new ClassLoaderMetrics().bindTo(prometheusRegistry);
    new JvmMemoryMetrics().bindTo(prometheusRegistry);
    new JvmGcMetrics().bindTo(prometheusRegistry);
    new ProcessorMetrics().bindTo(prometheusRegistry);
    new JvmThreadMetrics().bindTo(prometheusRegistry);

    // Tomcat metrics
    ApplicationContextFacade acf = (ApplicationContextFacade)request.getServletContext();
    Field applicationContextFacadeField = ApplicationContextFacade.class.getDeclaredField("context");
    applicationContextFacadeField.setAccessible(true);
    ApplicationContext appContext = (ApplicationContext) applicationContextFacadeField.get(acf);
    Field applicationContextField = ApplicationContext.class.getDeclaredField("context");
    applicationContextField.setAccessible(true);
    StandardContext stdContext = (StandardContext) applicationContextField.get(appContext);
    new TomcatMetrics(stdContext.getManager(),null).bindTo(prometheusRegistry);

    // Print metrics
    //out.print(prometheusRegistry.scrape());
    out.print(prometheusRegistry.scrape(TextFormat.CONTENT_TYPE_OPENMETRICS_100));
%>

Upvotes: 1

cocorossello
cocorossello

Reputation: 1357

private static Manager manager;

private static synchronized Manager getManager(ServletContext servletContext) {
    if (manager == null) {
        try {
            Field applicationContextField = servletContext.getClass().getDeclaredField("context");
            applicationContextField.setAccessible(true);
            ApplicationContext appContextObj = (ApplicationContext) applicationContextField.get(servletContext);
            Field standardContextField = appContextObj.getClass().getDeclaredField("context");
            standardContextField.setAccessible(true);
            StandardContext standardContextObj = (StandardContext) standardContextField.get(appContextObj);
            manager = standardContextObj.getManager();
        } catch (ReflectiveOperationException e) {
            throw new RuntimeException(e);
        }
    }
    return manager;
}

Upvotes: 3

Related Questions