-
Notifications
You must be signed in to change notification settings - Fork 2.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add metrics when the connections limit is set
When the HTTP connection limit is set: - expose a new gauge with the max number of connections - expose a new gauge with the current number of connections - expose a new counter with the number of rejected connections
- Loading branch information
1 parent
e3dd81b
commit 31474fd
Showing
4 changed files
with
200 additions
and
2 deletions.
There are no files selected for viewing
108 changes: 108 additions & 0 deletions
108
...ent/src/test/java/io/quarkus/micrometer/deployment/binder/VertxConnectionMetricsTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
package io.quarkus.micrometer.deployment.binder; | ||
|
||
import static org.awaitility.Awaitility.await; | ||
|
||
import java.util.concurrent.CountDownLatch; | ||
import java.util.concurrent.ExecutorService; | ||
import java.util.concurrent.Executors; | ||
import java.util.concurrent.TimeUnit; | ||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
import jakarta.enterprise.context.ApplicationScoped; | ||
import jakarta.enterprise.event.Observes; | ||
import jakarta.inject.Inject; | ||
|
||
import org.assertj.core.api.Assertions; | ||
import org.junit.jupiter.api.AfterEach; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.junit.jupiter.api.extension.RegisterExtension; | ||
|
||
import io.micrometer.core.instrument.Counter; | ||
import io.micrometer.core.instrument.Gauge; | ||
import io.micrometer.core.instrument.Metrics; | ||
import io.quarkus.runtime.StartupEvent; | ||
import io.quarkus.test.QuarkusUnitTest; | ||
import io.restassured.RestAssured; | ||
import io.vertx.mutiny.ext.web.Router; | ||
|
||
/** | ||
* Verify that we report connection metrics when the connection limit it set. | ||
*/ | ||
public class VertxConnectionMetricsTest { | ||
|
||
@RegisterExtension | ||
static final QuarkusUnitTest config = new QuarkusUnitTest() | ||
.withConfigurationResource("test-logging.properties") | ||
.overrideConfigKey("quarkus.redis.devservices.enabled", "false") | ||
// Only allows 2 concurrent connections | ||
.overrideConfigKey("quarkus.http.limits.max-connections", "2") | ||
// Close the connection after 1s of inactivity, otherwise, the connection are kept open for 30min | ||
.overrideConfigKey("quarkus.http.idle-timeout", "1s") | ||
.withApplicationRoot(jar -> jar.addClasses(App.class)); | ||
|
||
@Inject | ||
App app; | ||
|
||
private ExecutorService executor; | ||
private int concurrency; | ||
|
||
@BeforeEach | ||
public void init() { | ||
concurrency = 10; | ||
executor = Executors.newFixedThreadPool(10); // More than the connection limit | ||
} | ||
|
||
@AfterEach | ||
public void cleanup() { | ||
executor.shutdown(); | ||
} | ||
|
||
@Test | ||
void testConnectionMetrics() throws InterruptedException { | ||
AtomicInteger rejected = new AtomicInteger(); | ||
CountDownLatch latch = new CountDownLatch(concurrency); | ||
for (int i = 0; i < concurrency; i++) { | ||
executor.submit(() -> { | ||
try { | ||
RestAssured.get("/ok").statusCode(); | ||
} catch (Exception e) { | ||
// RestAssured considers the rejection as an error. | ||
rejected.incrementAndGet(); | ||
} finally { | ||
latch.countDown(); | ||
} | ||
}); | ||
} | ||
|
||
Assertions.assertThat(latch.await(10, TimeUnit.SECONDS)).isTrue(); | ||
Gauge max = Metrics.globalRegistry.find("vertx.http.connections.max").gauge(); | ||
Gauge current = Metrics.globalRegistry.find("vertx.http.connections.current").gauge(); | ||
Assertions.assertThat(max).isNotNull(); | ||
Assertions.assertThat(current).isNotNull(); | ||
|
||
Assertions.assertThat(max.value()).isEqualTo(2); | ||
|
||
// All requests are done, and connection closed (idle timeout) | ||
await().untilAsserted(() -> Assertions.assertThat(current.value()).isEqualTo(0)); | ||
|
||
if (rejected.get() > 0) { | ||
Counter counter = Metrics.globalRegistry.find("vertx.http.connections.rejected").counter(); | ||
Assertions.assertThat(counter).isNotNull(); | ||
Assertions.assertThat(counter.count()).isGreaterThan(0); | ||
} | ||
} | ||
|
||
@ApplicationScoped | ||
public static class App { | ||
|
||
public void start(@Observes StartupEvent ev, Router router, io.vertx.core.Vertx vertx) { | ||
router.get("/ok").handler(rc -> { | ||
// Keep the connection open for 100ms. | ||
vertx.setTimer(250, l -> rc.endAndForget("ok")); | ||
}); | ||
} | ||
|
||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
.../runtime/src/main/java/io/quarkus/vertx/http/runtime/ExtendedQuarkusVertxHttpMetrics.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package io.quarkus.vertx.http.runtime; | ||
|
||
import java.util.concurrent.atomic.AtomicInteger; | ||
|
||
/** | ||
* An interface extending the metrics exposed for the Vert.x HTTP server. | ||
* <p> | ||
* The Vert.x HTTP metrics are managed by Vert.x, and are exposed by the Vert.x metrics SPI. | ||
* However, some of the metrics are not exposed by the SPI, and are only available through the Vert.x HTTP SPI. | ||
* <p> | ||
* Thus, we need to extend the Vert.x HTTP metrics SPI to expose these metrics. | ||
*/ | ||
public interface ExtendedQuarkusVertxHttpMetrics { | ||
|
||
/** | ||
* A no-op connection tracker. | ||
*/ | ||
ConnectionTracker NOOP_CONNECTION_TRACKER = new ConnectionTracker() { | ||
@Override | ||
public void onConnectionRejected() { | ||
} | ||
|
||
@Override | ||
public void initialize(int maxConnections, AtomicInteger current) { | ||
} | ||
}; | ||
|
||
/** | ||
* Gets a tracker to report the number of active HTTP connection, the number of rejected connections, etc. | ||
* | ||
* @return the tracker. | ||
*/ | ||
ConnectionTracker getHttpConnectionTracker(); | ||
|
||
interface ConnectionTracker { | ||
|
||
void onConnectionRejected(); | ||
|
||
void initialize(int maxConnections, AtomicInteger current); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters