-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: [CO-1350] export http connection pool statistics to prometheus (#…
…551)
- Loading branch information
1 parent
7dcd419
commit ea87abb
Showing
11 changed files
with
288 additions
and
17 deletions.
There are no files selected for viewing
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
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
14 changes: 14 additions & 0 deletions
14
common/src/main/java/com/zimbra/common/metric/CarbonioCollector.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,14 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Zextras <https://www.zextras.com> | ||
* | ||
* SPDX-License-Identifier: CC0-1.0 | ||
*/ | ||
package com.zimbra.common.metric; | ||
|
||
import io.prometheus.client.Collector; | ||
|
||
/** | ||
* Carbonio Collector | ||
*/ | ||
public abstract class CarbonioCollector extends Collector { | ||
} |
68 changes: 68 additions & 0 deletions
68
common/src/main/java/com/zimbra/common/util/HttpConnectionManagerMetricsExport.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,68 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Zextras <https://www.zextras.com> | ||
* | ||
* SPDX-License-Identifier: CC0-1.0 | ||
*/ | ||
package com.zimbra.common.util; | ||
|
||
import com.zimbra.common.metric.CarbonioCollector; | ||
import io.prometheus.client.GaugeMetricFamily; | ||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | ||
import org.apache.http.pool.PoolStats; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collections; | ||
import java.util.List; | ||
|
||
/** | ||
* For export HttpConnectionPools metrics | ||
* | ||
*/ | ||
public class HttpConnectionManagerMetricsExport extends CarbonioCollector { | ||
|
||
private static final String POOL = "pool"; | ||
|
||
/** | ||
* @return List<MetricFamilySamples> | ||
*/ | ||
@Override | ||
public List<MetricFamilySamples> collect() { | ||
List<MetricFamilySamples> mfs = new ArrayList<>(); | ||
GaugeMetricFamily internalGaugeMetricFamily = getGaugeMetricFamily("internal"); | ||
|
||
setMetrics(ZimbraHttpConnectionManager.getInternalHttpConnMgr(), internalGaugeMetricFamily); | ||
mfs.add(internalGaugeMetricFamily); | ||
|
||
GaugeMetricFamily externalGaugeMetricFamily = getGaugeMetricFamily("external"); | ||
setMetrics(ZimbraHttpConnectionManager.getExternalHttpConnMgr(), externalGaugeMetricFamily); | ||
mfs.add(externalGaugeMetricFamily); | ||
return mfs; | ||
} | ||
|
||
/** | ||
* get Gauge Metric Family | ||
*/ | ||
GaugeMetricFamily getGaugeMetricFamily(String type) { | ||
return new GaugeMetricFamily( | ||
"http_connection_" + POOL + "_" + type, | ||
"Metrics for " + type + " " + POOL, | ||
Collections.singletonList(POOL)); | ||
} | ||
|
||
/** | ||
* set metrics | ||
*/ | ||
void setMetrics(ZimbraHttpConnectionManager zimbraHttpConnectionManager, GaugeMetricFamily gaugeMetricFamily) { | ||
PoolStats poolStats = null; | ||
if (zimbraHttpConnectionManager != null && zimbraHttpConnectionManager.getHttpConnMgr() instanceof PoolingHttpClientConnectionManager) { | ||
poolStats = ((PoolingHttpClientConnectionManager) zimbraHttpConnectionManager.getHttpConnMgr()).getTotalStats(); | ||
} | ||
if (poolStats == null) { | ||
return; | ||
} | ||
gaugeMetricFamily.addMetric(Collections.singletonList("available"), poolStats.getAvailable()); | ||
gaugeMetricFamily.addMetric(Collections.singletonList("leased"), poolStats.getLeased()); | ||
gaugeMetricFamily.addMetric(Collections.singletonList("max"), poolStats.getMax()); | ||
gaugeMetricFamily.addMetric(Collections.singletonList("pending"), poolStats.getPending()); | ||
} | ||
} |
39 changes: 39 additions & 0 deletions
39
common/src/test/java/com/zimbra/common/util/HttpConnectionManagerMetricsExportTest.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,39 @@ | ||
package com.zimbra.common.util; | ||
|
||
import io.prometheus.client.GaugeMetricFamily; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.BeforeEach; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
|
||
|
||
class HttpConnectionManagerMetricsExportTest { | ||
|
||
private HttpConnectionManagerMetricsExport export; | ||
|
||
@BeforeEach | ||
void setUp() { | ||
export = new HttpConnectionManagerMetricsExport(); | ||
} | ||
@Test | ||
void test_collect() { | ||
Assertions.assertDoesNotThrow(() ->export.collect()); | ||
} | ||
|
||
@Test | ||
void test_setMetrics_when_zimbraHttpConnectionManager_is_null_then_do_nothing() { | ||
GaugeMetricFamily gaugeMetricFamily = Mockito.mock(GaugeMetricFamily.class); | ||
export.setMetrics(null, gaugeMetricFamily); | ||
Mockito.verify(gaugeMetricFamily, Mockito.times(0)) | ||
.addMetric(Mockito.anyList(), Mockito.anyInt()); | ||
} | ||
|
||
@Test | ||
void test_setMetrics_when_zimbraHttpConnectionManager_is_not_instanceof_PoolingHttpClientConnectionManager_then_do_nothing() { | ||
GaugeMetricFamily gaugeMetricFamily = Mockito.mock(GaugeMetricFamily.class); | ||
ZimbraHttpConnectionManager zimbraHttpConnectionManager = Mockito.mock(ZimbraHttpConnectionManager.class); | ||
export.setMetrics(zimbraHttpConnectionManager, gaugeMetricFamily); | ||
Mockito.verify(gaugeMetricFamily, Mockito.times(0)) | ||
.addMetric(Mockito.anyList(), Mockito.anyInt()); | ||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
store/src/main/java/com/zextras/mailbox/metric/CarbonioMetricRegisterer.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,26 @@ | ||
/* | ||
* SPDX-FileCopyrightText: 2024 Zextras <https://www.zextras.com> | ||
* | ||
* SPDX-License-Identifier: CC0-1.0 | ||
*/ | ||
package com.zextras.mailbox.metric; | ||
|
||
import com.zimbra.common.util.HttpConnectionManagerMetricsExport; | ||
import io.prometheus.client.CollectorRegistry; | ||
import io.prometheus.client.hotspot.DefaultExports; | ||
|
||
/** | ||
* For register DefaultExports and project specific exports | ||
*/ | ||
public final class CarbonioMetricRegisterer { | ||
|
||
private CarbonioMetricRegisterer() {} | ||
/** | ||
* | ||
* @param registry CollectorRegistry | ||
*/ | ||
public static void register(CollectorRegistry registry) { | ||
DefaultExports.register(registry); | ||
registry.register(new HttpConnectionManagerMetricsExport()); | ||
} | ||
} |
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
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
92 changes: 92 additions & 0 deletions
92
...src/test/java/com/zextras/mailbox/domain/usecase/metric/CarbonioMetricRegistererTest.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,92 @@ | ||
package com.zextras.mailbox.domain.usecase.metric; | ||
|
||
import com.zextras.mailbox.metric.CarbonioMetricRegisterer; | ||
import com.zimbra.common.util.HttpConnectionManagerMetricsExport; | ||
import io.prometheus.client.CollectorRegistry; | ||
import io.prometheus.client.hotspot.BufferPoolsExports; | ||
import io.prometheus.client.hotspot.ClassLoadingExports; | ||
import io.prometheus.client.hotspot.GarbageCollectorExports; | ||
import io.prometheus.client.hotspot.MemoryAllocationExports; | ||
import io.prometheus.client.hotspot.MemoryPoolsExports; | ||
import io.prometheus.client.hotspot.StandardExports; | ||
import io.prometheus.client.hotspot.ThreadExports; | ||
import io.prometheus.client.hotspot.VersionInfoExports; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
|
||
class CarbonioMetricRegistererTest { | ||
|
||
|
||
@Test | ||
void test_register_registers_StandardExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(StandardExports.class)); | ||
|
||
} | ||
|
||
@Test | ||
void test_register_registers_MemoryPoolsExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(MemoryPoolsExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_MemoryAllocationExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(MemoryAllocationExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_BufferPoolsExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(BufferPoolsExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_GarbageCollectorExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(GarbageCollectorExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_ThreadExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(ThreadExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_ClassLoadingExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(ClassLoadingExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_VersionInfoExports() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(VersionInfoExports.class)); | ||
} | ||
|
||
@Test | ||
void test_register_registers_HttpConnectionManagerMetricsExport() { | ||
CollectorRegistry collectorRegistry = Mockito.mock(CollectorRegistry.class); | ||
CarbonioMetricRegisterer.register(collectorRegistry); | ||
Mockito.verify(collectorRegistry, Mockito.times(1)) | ||
.register(Mockito.any(HttpConnectionManagerMetricsExport.class)); | ||
} | ||
} |
17 changes: 17 additions & 0 deletions
17
store/src/test/java/com/zextras/mailbox/domain/usecase/metric/MetricsTest.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,17 @@ | ||
package com.zextras.mailbox.domain.usecase.metric; | ||
|
||
import com.zextras.mailbox.metric.Metrics; | ||
import io.prometheus.client.Collector; | ||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
import org.mockito.Mockito; | ||
|
||
class MetricsTest { | ||
|
||
@Test | ||
void test_register() { | ||
Collector collector = Mockito.mock(Collector.class); | ||
Metrics.register(collector); | ||
Assertions.assertDoesNotThrow(() -> Metrics.COLLECTOR_REGISTRY.unregister(collector)); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
store/src/test/java/com/zextras/mailbox/servlet/MetricsServletModuleTest.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,13 @@ | ||
package com.zextras.mailbox.servlet; | ||
|
||
import org.junit.jupiter.api.Assertions; | ||
import org.junit.jupiter.api.Test; | ||
|
||
class MetricsServletModuleTest { | ||
|
||
@Test | ||
void test_provideCollector() { | ||
MetricsServletModule module = new MetricsServletModule(); | ||
Assertions.assertNotNull(module.provideCollector()); | ||
} | ||
} |