Untitled
dependencies { implementation 'org.springframework.boot:spring-boot-starter-actuator' implementation 'io.micrometer:micrometer-registry-prometheus' // For Prometheus metrics (optional) implementation 'io.micrometer:micrometer-registry-otel' // For OTEL metrics implementation 'com.zaxxer:HikariCP' } import io.micrometer.core.instrument.MeterRegistry; import com.zaxxer.hikari.HikariDataSource; @Component public class TenantDataSourceProvider { private final Map<String, DataSource> tenantDataSources = new ConcurrentHashMap<>(); private final ConnectionProvider connectionProvider; private final HikariConfigProperties hikariConfigProperties; private final MeterRegistry meterRegistry; // Micrometer MeterRegistry public TenantDataSourceProvider(ConnectionProvider connectionProvider, HikariConfigProperties hikariConfigProperties, MeterRegistry meterRegistry) { this.connectionProvider = connectionProvider; this.hikariConfigProperties = hikariConfigProperties; this.meterRegistry = meterRegistry; } public DataSource getTenantDataSource(String tenantId) { return tenantDataSources.computeIfAbsent(tenantId, this::createDataSource); } private DataSource createDataSource(String tenantId) { HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(connectionProvider.getConnectionUrl(tenantId, "prod")); dataSource.setUsername(connectionProvider.getUsername(tenantId)); dataSource.setPassword(connectionProvider.getPassword(tenantId)); dataSource.setMaximumPoolSize(hikariConfigProperties.getMaxPoolSize()); dataSource.setMinimumIdle(hikariConfigProperties.getMinIdle()); // Set other HikariCP properties // Register HikariCP metrics with Micrometer dataSource.setMetricRegistry(meterRegistry); return dataSource; } } ---- import io.micrometer.core.instrument.MeterRegistry; import io.micrometer.core.instrument.Tag; import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.metrics.micrometer.MicrometerMetricsTrackerFactory; @Component public class TenantDataSourceProvider { private final Map<String, DataSource> tenantDataSources = new ConcurrentHashMap<>(); private final ConnectionProvider connectionProvider; private final HikariConfigProperties hikariConfigProperties; private final MeterRegistry meterRegistry; public TenantDataSourceProvider(ConnectionProvider connectionProvider, HikariConfigProperties hikariConfigProperties, MeterRegistry meterRegistry) { this.connectionProvider = connectionProvider; this.hikariConfigProperties = hikariConfigProperties; this.meterRegistry = meterRegistry; } public DataSource getTenantDataSource(String tenantId) { return tenantDataSources.computeIfAbsent(tenantId, this::createDataSource); } private DataSource createDataSource(String tenantId) { HikariDataSource dataSource = new HikariDataSource(); dataSource.setJdbcUrl(connectionProvider.getConnectionUrl(tenantId, "prod")); dataSource.setUsername(connectionProvider.getUsername(tenantId)); dataSource.setPassword(connectionProvider.getPassword(tenantId)); dataSource.setMaximumPoolSize(hikariConfigProperties.getMaxPoolSize()); dataSource.setMinimumIdle(hikariConfigProperties.getMinIdle()); // Set other HikariCP properties // Add tenant-specific tags to HikariCP metrics dataSource.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(meterRegistry, "hikaricp", Tags.of("tenant", tenantId))); // Add tenant tag return dataSource; } } --- dataSource.setMetricsTrackerFactory(new MicrometerMetricsTrackerFactory(meterRegistry, "hikaricp", Tags.of("tenant", tenantId, "environment", "prod", "database", "mysql"))); -- management: metrics: export: otel: enabled: true step: 1m # Export metrics every 1 minute resource-attributes: # Optional: Add custom resource attributes service.name: my-springboot-service service.namespace: multitenant-app
Leave a Comment