micrometer icon indicating copy to clipboard operation
micrometer copied to clipboard

Feature: Undertow metrics

Open bbzg opened this issue 6 years ago • 9 comments

I would very much like to measure Undertow using Micrometer, but I notice that there is no UndertowMetrics class like there is for Tomcat (TomcatMetrics) or Jetty (JettyStatisticsMetrics et.al).

Has anyone already built this somewhere else, or are there any ongoing efforts to build this?

I noticed that there are multiple issues mentioning Undertow metrics, but none that come to any conclusion.

Thank you for considering my request.

bbzg avatar Feb 12 '19 22:02 bbzg

Hey @shakuzen Can please review my PR?

dharmeshjogadia avatar Sep 09 '19 15:09 dharmeshjogadia

@dharmeshjogadia thank you for the pull request. I've optimistically marked this for inclusion in 1.3.0, but I can't guarantee we'll be able to get it reviewed and merged in time.

shakuzen avatar Sep 20 '19 19:09 shakuzen

I use undertow without servlets, and https://github.com/micrometer-metrics/micrometer/pull/1575 only cover servlets part (which more specific), but not the undertow server itself, which based on handlers. Example of built-in metric handler: https://github.com/undertow-io/undertow/blob/master/core/src/main/java/io/undertow/server/handlers/MetricsHandler.java

IRus avatar Sep 30 '19 08:09 IRus

Hi..

What you think about this kind of implementation? It's very simple and give us metrics about ThreadPoolWorkers and ioThreadCount of Undertow. It is generics for Servlet or Reactive application.

If you prefer I can make a pull request. What do you think?

public class UndertowMetrics implements MeterBinder {
	private static final String OBJECT_NAME = "org.xnio:type=Xnio,provider=\"nio\",worker=\"XNIO-1\"";
	private static final String GAUGE_NAME_WORKER_QUEUE_SIZE = "undertow.worker.queue.size";
	private static final String GAUGE_NAME_WORKER_POOL_SIZE = "undertow.worker.pool.size";
	private static final String GAUGE_NAME_MAX_WORKER_POOL_SIZE = "undertow.worker.pool.max";
	private static final String GAUGE_NAME_IO_THREAD_COUNT = "undertow.io.thread-count";
	private static final String ATTR_WORKER_QUEUE_SIZE = "WorkerQueueSize";
	private static final String ATTR_WORKER_POOL_SIZE = "CoreWorkerPoolSize";
	private static final String ATTR_MAX_WORKER_POOL_SIZE = "MaxWorkerPoolSize";
	private static final String ATTR_IO_THREAD_COUNT = "IoThreadCount";
	private final MBeanServer platformMBeanServer = ManagementFactory.getPlatformMBeanServer();

	@Override
	public void bindTo(@NonNull MeterRegistry registry) {
		buildAndRegisterGauge(GAUGE_NAME_WORKER_QUEUE_SIZE,
			ATTR_WORKER_QUEUE_SIZE,
			"Undertow worker queue size",
			registry);

		buildAndRegisterGauge(GAUGE_NAME_WORKER_POOL_SIZE,
			ATTR_WORKER_POOL_SIZE,
			"Undertow worker pool size",
			registry);

		buildAndRegisterGauge(GAUGE_NAME_MAX_WORKER_POOL_SIZE,
			ATTR_MAX_WORKER_POOL_SIZE,
			"Undertow max worker pool size",
			registry);

		buildAndRegisterGauge(GAUGE_NAME_IO_THREAD_COUNT,
			ATTR_IO_THREAD_COUNT,
			"Undertow IO thread count",
			registry);
	}

	private void buildAndRegisterGauge(@NonNull String name, @NonNull String attributeName, @NonNull String description, @NonNull MeterRegistry registry) {
		Gauge.builder(name,
				platformMBeanServer,
				mBeanServer -> getWorkerAttribute(mBeanServer, attributeName))
				.description(description)
				.register(registry);
	}

	private double getWorkerAttribute(@NonNull MBeanServer mBeanServer, @NonNull String attributeName) {
		Object attributeValueObj = null;
		try {
			attributeValueObj = mBeanServer.getAttribute(workerObjectName(), attributeName);
		} catch (Exception e) {
			log.warn("Unable to get {} from JMX", ATTR_WORKER_QUEUE_SIZE, e);
		}
		return Optional.ofNullable(attributeValueObj)
				.map(value -> (Number) value)
				.map(Number::doubleValue)
				.orElse(0d);
	}

	private ObjectName workerObjectName() throws MalformedObjectNameException {
		return new ObjectName(OBJECT_NAME);
	}
}

ignacio83 avatar Sep 23 '20 19:09 ignacio83

@ignacio83 is there a reason to use org.xnio:type=Xnio,provider="nio",worker="XNIO-1" over jboss.threads:name="XNIO-1",type=thread-pool ? Genuine question, as they both seem to contain similar information

austinarbor avatar Dec 28 '20 16:12 austinarbor

Hi @austinarbor

Are you using Wildly as application server? Undertow is servlet container of Wildly. I believe that’s why you’re seeing the two metrics who the same value.

In my case I am using only Undertow.

ignacio83 avatar Jan 04 '21 16:01 ignacio83

I am using it from within spring boot as an embedded server, AFAIK wildfly is not being used but I could be wrong

austinarbor avatar Jan 04 '21 19:01 austinarbor

Has anyone looking for Undertow Micrometer metrics tried requesting this to the Undertow project yet? There may be benefits to having the instrumentation done in Undertow as opposed to from outside of it like access to information not exposed in the API. If someone does ask the Undertow project, please link to the request from here so that people can follow the request and give their feedback on what metrics are important to them.

shakuzen avatar Mar 03 '22 10:03 shakuzen

@shakuzen Any plans to release this soon?

petromir avatar May 12 '22 12:05 petromir

Any news?)

SimSonic avatar Oct 31 '23 15:10 SimSonic

It would be great if instrumentation could be added as a new Undertow module, please comment this issue if you would like it to happen: https://issues.redhat.com/browse/UNDERTOW-2294

jonatan-ivanov avatar Oct 31 '23 17:10 jonatan-ivanov

We're closing it in favour of https://issues.redhat.com/browse/UNDERTOW-2294 . If anyone has any access to Undertow maintainers please help us reaching out to them

marcingrzejszczak avatar Dec 21 '23 14:12 marcingrzejszczak

@marcingrzejszczak I suggest to try in Google groups ([email protected]), there is some activity by the maintainers and users there (not much)

flozano avatar Dec 21 '23 15:12 flozano

Thanks! I've published a message there

marcingrzejszczak avatar Dec 21 '23 15:12 marcingrzejszczak