Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#33] Provide more health metrics #35

Merged
merged 9 commits into from
Nov 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.coreoz.plume.db.querydsl.guice;

import com.coreoz.plume.db.guice.DataSourceModule;
import com.coreoz.plume.db.querydsl.transaction.TransactionManagerQuerydsl;
import com.coreoz.plume.db.transaction.TransactionManager;
import com.google.inject.AbstractModule;
Expand All @@ -8,7 +9,7 @@ public class GuiceQuerydslModule extends AbstractModule {

@Override
protected void configure() {
install(new DataSourceModule());
bind(TransactionManager.class).to(TransactionManagerQuerydsl.class);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,16 @@ public class TransactionManagerQuerydsl extends TransactionManager {
private final Configuration querydslConfiguration;

@Inject
public TransactionManagerQuerydsl(Config config) {
this(config, "db");
public TransactionManagerQuerydsl(DataSource dataSource, Config config) {
super(dataSource);
String dialect = config.getString("db.dialect");
this.querydslConfiguration = new Configuration(QuerydslTemplates.valueOf(dialect).sqlTemplates());
}

public TransactionManagerQuerydsl(Config config, String prefix) {
super(config, prefix);

String dialect = config.getString(prefix + ".dialect");
this.querydslConfiguration = new Configuration(QuerydslTemplates.valueOf(dialect).sqlTemplates());
}

public TransactionManagerQuerydsl(DataSource dataSource, Configuration querydslConfiguration) {
super(dataSource);

this.querydslConfiguration = querydslConfiguration;
}
public TransactionManagerQuerydsl(DataSource dataSource, Configuration querydslConfiguration) {
super(dataSource);
this.querydslConfiguration = querydslConfiguration;
}

// API

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@

import javax.sql.DataSource;

import com.coreoz.plume.db.transaction.DataSourceProvider;
import com.coreoz.plume.db.transaction.HikariDataSourceProvider;
import com.google.inject.AbstractModule;
import com.zaxxer.hikari.HikariDataSource;

public class DataSourceModule extends AbstractModule {

@Override
protected void configure() {
bind(DataSource.class).toProvider(DataSourceProvider.class);
}

@Override
protected void configure() {
bind(DataSource.class).toProvider(HikariDataSourceProvider.class);
bind(HikariDataSource.class).toProvider(HikariDataSourceProvider.class);
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.coreoz.plume.db.transaction;

import com.typesafe.config.Config;
import com.zaxxer.hikari.HikariDataSource;
import jakarta.inject.Inject;
import jakarta.inject.Provider;
import jakarta.inject.Singleton;

/**
* Expose a {@link HikariDataSource} Object through dependency injection.
*/
@Singleton
public class HikariDataSourceProvider implements Provider<HikariDataSource> {

private final HikariDataSource dataSource;

@Inject
public HikariDataSourceProvider(Config config) {
this.dataSource = HikariDataSources.fromConfig(config, "db.hikari");
}

@Override
public HikariDataSource get() {
return dataSource;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@
*/
public class HikariDataSources {

public static DataSource fromConfig(Config config, String prefix) {
return initializeFromProperties(readConfig(config, prefix));
public static HikariDataSource fromConfig(Config config, String prefix) {
return new HikariDataSource(createHikariConfig(config, prefix));
}

private static HikariDataSource initializeFromProperties(Map<String, String> properties) {
return new HikariDataSource(new HikariConfig(mapToProperties(properties)));
}
public static HikariConfig createHikariConfig(Config config, String prefix) {
return new HikariConfig(mapToProperties(readConfig(config, prefix)));
}

private static Properties mapToProperties(Map<String, String> mapProperties) {
Properties properties = new Properties();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import javax.sql.DataSource;

import com.google.common.base.Throwables;
import com.typesafe.config.Config;

/**
* Handle transactions over a classic JDBC {@link Connection}.
Expand All @@ -20,18 +19,10 @@ public class TransactionManager {

private final DataSource dataSource;

@Inject
public TransactionManager(Config config) {
this(config, "db");
}

public TransactionManager(Config config, String prefix) {
this(HikariDataSources.fromConfig(config, prefix + ".hikari"));
}

public TransactionManager(DataSource dataSource) {
this.dataSource = dataSource;
}
@Inject
public TransactionManager(DataSource dataSource) {
this.dataSource = dataSource;
}

// API

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,19 @@
import static org.assertj.core.api.Assertions.assertThat;

import java.sql.Connection;
import java.sql.SQLException;

import com.zaxxer.hikari.HikariDataSource;
import org.junit.Test;

import com.typesafe.config.ConfigFactory;

public class TransactionManagerTest {

private final HikariDataSource dataSource = new HikariDataSourceProvider(ConfigFactory.load()).get();

@Test
public void should_disable_autocommit_during_transaction() throws SQLException {
TransactionManager transactionManager = new TransactionManager(ConfigFactory.load());
public void should_disable_autocommit_during_transaction() {
TransactionManager transactionManager = new TransactionManager(dataSource);
transactionManager.execute(connection -> {
try {
assertThat(connection.getAutoCommit()).isFalse();
Expand All @@ -24,8 +26,8 @@ public void should_disable_autocommit_during_transaction() throws SQLException {
}

@Test
public void should_leave_connection_with_autocommit() throws SQLException {
TransactionManager transactionManager = new TransactionManager(ConfigFactory.load());
public void should_leave_connection_with_autocommit() {
TransactionManager transactionManager = new TransactionManager(dataSource);
transactionManager.execute(connection -> {
try {
connection.prepareStatement("SELECT 1").execute();
Expand Down
18 changes: 12 additions & 6 deletions plume-web-jersey-monitoring/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@ to provide some basic functionality for monitoring your application's metrics (C
Exposed API :
- `registerMetric`: Register metrics to monitor
- `registerJvmMetrics`: Register the basic JVM metrics to monitor
- `registerGrizzlyMetrics`: Register metrics for Grizzly HTTP threads pool, see [Jersey module](../plume-web-jersey) for usage documentation on `GrizzlyThreadPoolProbe`
- `registerHikariMetrics`: Register metrics for HikariCP SQL connections pool
- `build`: create a metrics provider that provides the status of the metrics that are monitored.


Expand All @@ -87,7 +89,13 @@ public class MonitoringWs {
private final BasicAuthenticator<String> basicAuthenticator;

@Inject
public MonitoringWs(ApplicationInfoProvider applicationInfoProvider, TransactionManager transactionManager) {
public MonitoringWs(
ApplicationInfoProvider applicationInfoProvider,
TransactionManager transactionManager,
GrizzlyThreadPoolProbe grizzlyThreadPoolProbe,
HikariDataSource hikariDataSource,
InternalApiAuthenticator apiAuthenticator
) {
this.applicationInfo = applicationInfoProvider.get();
// Registering health checks
this.healthStatusProvider = new HealthCheckBuilder()
Expand All @@ -97,14 +105,12 @@ public class MonitoringWs {
// Registering metrics to monitor
this.metricsStatusProvider = new MetricsCheckBuilder()
.registerJvmMetrics()
.registerGrizzlyMetrics(grizzlyThreadPoolProbe)
.registerHikariMetrics(hikariDataSource)
.build();

// Require authentication to access monitoring endpoints
this.basicAuthenticator = BasicAuthenticator.fromSingleCredentials(
"plume",
"rocks",
"Plume showcase"
);
this.basicAuthenticator = apiAuthenticator.get();
}

@GET
Expand Down
18 changes: 18 additions & 0 deletions plume-web-jersey-monitoring/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@
<groupId>com.coreoz</groupId>
<artifactId>plume-web-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-grizzly2-http</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.coreoz</groupId>
<artifactId>plume-db</artifactId>
Expand Down Expand Up @@ -84,6 +89,19 @@
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<!-- Tests -->
<dependency>
<groupId>com.coreoz</groupId>
<artifactId>plume-db-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.14.1</version>
<scope>test</scope>
</dependency>
</dependencies>

<dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package com.coreoz.plume.jersey.monitoring.utils.metrics;

import com.codahale.metrics.Gauge;
import com.codahale.metrics.Metric;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.MetricSet;
import com.codahale.metrics.jvm.MemoryUsageGaugeSet;
import com.codahale.metrics.jvm.ThreadStatesGaugeSet;
import com.coreoz.plume.jersey.grizzly.GrizzlyThreadPoolProbe;
import com.zaxxer.hikari.HikariDataSource;

import jakarta.inject.Provider;
import java.util.Map;
Expand All @@ -27,6 +30,20 @@ public MetricsCheckBuilder registerJvmMetrics() {
return this;
}

public MetricsCheckBuilder registerGrizzlyMetrics(GrizzlyThreadPoolProbe grizzlyThreadPoolProbe) {
this.metricRegistry.register("http-pool.max-size", (Gauge<Integer>) grizzlyThreadPoolProbe::getPoolMaxSize);
this.metricRegistry.register("http-pool.current-size", (Gauge<Integer>) grizzlyThreadPoolProbe::getPoolCurrentSize);
this.metricRegistry.register("http-pool.waiting-size", (Gauge<Integer>) grizzlyThreadPoolProbe::getTasksWaitingSize);
this.metricRegistry.register("http-pool.usage-size", (Gauge<Integer>) grizzlyThreadPoolProbe::getPoolUsageSize);
this.metricRegistry.register("http-pool.usage", (Gauge<Float>) () -> ((float) grizzlyThreadPoolProbe.getPoolUsageSize()) / ((float)grizzlyThreadPoolProbe.getPoolMaxSize()));
return this;
}

public MetricsCheckBuilder registerHikariMetrics(HikariDataSource hikariDataSource) {
hikariDataSource.setMetricRegistry(this.metricRegistry);
return this;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Il faudrait ajouter un test d'intégration avec ça pour vérifier qu'on récupère bien toutes les métriques et que c'est ok. Tu peux voir avec chatgpt pour t'aider à écrire le test :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes j'ajoute ça !


public Provider<Map<String, Metric>> build() {
return this::getMetrics;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
db.hikari."dataSourceClassName"="org.h2.jdbcx.JdbcDataSource"
db.hikari."dataSource.url"="jdbc:h2:mem:test"
db.hikari."dataSource.user"=sa
db.hikari."dataSource.password"=sa
db.hikari.minimumIdle=1
db.hikari.maximumPoolSize=1
Loading
Loading