Skip to content

Commit

Permalink
Add Jetty threadpool metrics
Browse files Browse the repository at this point in the history
  • Loading branch information
matsumana authored and Jon Schneider committed May 24, 2018
1 parent d7bec81 commit 21a375a
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2017 Pivotal Software, Inc.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.core.instrument.binder.jetty;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import org.eclipse.jetty.util.thread.QueuedThreadPool;

public class InstrumentedQueuedThreadPool extends QueuedThreadPool {

private final MeterRegistry registry;
private final Iterable<Tag> tags;

public InstrumentedQueuedThreadPool(MeterRegistry registry, Iterable<Tag> tags) {
this.registry = registry;
this.tags = tags;
}

@Override
protected void doStart() throws Exception {
super.doStart();
JettyServerThreadPoolMetrics threadPoolMetrics = new JettyServerThreadPoolMetrics(this, tags);
threadPoolMetrics.bindTo(registry);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/**
* Copyright 2017 Pivotal Software, Inc.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.core.instrument.binder.jetty;

import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.binder.MeterBinder;

public class JettyServerThreadPoolMetrics implements MeterBinder {

private final InstrumentedQueuedThreadPool threadPool;
private final Iterable<Tag> tags;

public JettyServerThreadPoolMetrics(InstrumentedQueuedThreadPool threadPool, Iterable<Tag> tags) {
this.threadPool = threadPool;
this.tags = tags;
}

@Override
public void bindTo(MeterRegistry registry) {
Gauge.builder("jetty.threads.config.min", threadPool, InstrumentedQueuedThreadPool::getMinThreads)
.tags(tags)
.description("The number of min threads")
.register(registry);
Gauge.builder("jetty.threads.config.max", threadPool, InstrumentedQueuedThreadPool::getMaxThreads)
.tags(tags)
.description("The number of max threads")
.register(registry);
Gauge.builder("jetty.threads.current", threadPool, InstrumentedQueuedThreadPool::getThreads)
.tags(tags)
.description("The current number of current threads")
.register(registry);
Gauge.builder("jetty.threads.busy", threadPool, InstrumentedQueuedThreadPool::getBusyThreads)
.tags(tags)
.description("The current number of busy threads")
.register(registry);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright 2017 Pivotal Software, Inc.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.core.instrument.binder.jetty;

import io.micrometer.core.instrument.MockClock;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.simple.SimpleConfig;
import io.micrometer.core.instrument.simple.SimpleMeterRegistry;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.Collections;

import static org.assertj.core.api.Assertions.assertThat;

public class JettyServerThreadPoolMetricsTest {
private SimpleMeterRegistry registry;
private Server server;

@BeforeEach
void setup() throws Exception {
registry = new SimpleMeterRegistry(SimpleConfig.DEFAULT, new MockClock());

Iterable<Tag> tags = Collections.singletonList(Tag.of("id", "0"));
QueuedThreadPool threadPool = new InstrumentedQueuedThreadPool(registry, tags);
threadPool.setMinThreads(32);
threadPool.setMaxThreads(100);
server = new Server(threadPool);
ServerConnector connector = new ServerConnector(server);
server.setConnectors(new Connector[] { connector });
server.start();
}

@AfterEach
void teardown() throws Exception {
server.stop();
}

@Test
void threadsMetrics() throws Exception {
assertThat(registry.get("jetty.threads.config.min").gauge().value()).isEqualTo(32.0);
assertThat(registry.get("jetty.threads.config.max").gauge().value()).isEqualTo(100.0);
assertThat(registry.get("jetty.threads.current").gauge().value()).isNotEqualTo(0.0);
assertThat(registry.get("jetty.threads.busy").gauge().value()).isNotEqualTo(0.0);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2017 Pivotal Software, Inc.
* <p>
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.micrometer.spring.autoconfigure.web.jetty;

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.jetty.InstrumentedQueuedThreadPool;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

@Configuration
@ConditionalOnClass(name = "org.eclipse.jetty.server.Server")
@ConditionalOnMissingClass("org.apache.catalina.startup.Tomcat")
public class JettyMetricsConfiguration {

@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory(MeterRegistry registry) {
JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory();
factory.setThreadPool(new InstrumentedQueuedThreadPool(registry, Collections.emptyList()));
return factory;
}
}

0 comments on commit 21a375a

Please sign in to comment.