Skip to content

Commit 3a0ceb7

Browse files
committed
Add service check, expand metric groups, add tests
1 parent 2c8987e commit 3a0ceb7

5 files changed

Lines changed: 156 additions & 5 deletions

File tree

.ddev/config.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ storm = "Storm"
77
[overrides.metrics-prefix]
88
aerospike_enterprise = "aerospike."
99
snmpwalk = "snmpwalk."
10+
stonebranch = "stonebranch."
1011
warpstream = "warpstream."

.github/workflows/test-all.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1394,7 +1394,7 @@ jobs:
13941394
setup-env-vars: "${{ inputs.setup-env-vars }}"
13951395
secrets: inherit
13961396
j712c9df:
1397-
uses: DataDog/integrations-core/.github/workflows/test-target.yml@master
1397+
uses: DataDog/integrations-core/.github/workflows/test-target.yml@5f6b58dfb609ea0afb37762612dbb6e2c37d2933
13981398
with:
13991399
job-name: stonebranch
14001400
target: stonebranch

stonebranch/datadog_checks/stonebranch/check.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,14 @@
22

33
from typing import Any
44

5-
from datadog_checks.base import ConfigurationError, OpenMetricsBaseCheckV2
5+
from datadog_checks.base import AgentCheck, ConfigurationError, OpenMetricsBaseCheckV2
66

77
from .metrics import ADDITIONAL_METRICS, DEFAULT_METRICS
88

99

1010
class StonebranchCheck(OpenMetricsBaseCheckV2):
1111
__NAMESPACE__ = "stonebranch"
12+
DEFAULT_METRIC_LIMIT = 0
1213

1314
def __init__(self, name, init_config, instances):
1415
super().__init__(name, init_config, instances)
@@ -58,6 +59,16 @@ def get_default_config(self) -> dict[str, Any]:
5859
)
5960
return config
6061

62+
def check(self, instance: dict[str, Any]) -> None:
63+
endpoint = self.instance.get("openmetrics_endpoint", "")
64+
tags = [f"endpoint:{endpoint}"]
65+
try:
66+
super().check(instance)
67+
self.service_check("openmetrics.health", AgentCheck.OK, tags=tags)
68+
except Exception as e:
69+
self.service_check("openmetrics.health", AgentCheck.CRITICAL, message=str(e), tags=tags)
70+
raise
71+
6172
@staticmethod
6273
def _coerce_metrics(value: Any) -> list[dict[str, str]]:
6374
"""

stonebranch/datadog_checks/stonebranch/metrics.py

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,44 @@
2727
# Opt-in groups
2828
ADDITIONAL_METRICS = {
2929
"jvm": [
30+
{"jvm_buffer_pool_capacity_bytes": "jvm_buffer_pool_capacity_bytes"},
31+
{"jvm_buffer_pool_used_buffers": "jvm_buffer_pool_used_buffers"},
32+
{"jvm_buffer_pool_used_bytes": "jvm_buffer_pool_used_bytes"},
33+
{"jvm_classes_currently_loaded": "jvm_classes_currently_loaded"},
34+
{"jvm_classes_loaded_total": "jvm_classes_loaded_total"},
35+
{"jvm_classes_unloaded_total": "jvm_classes_unloaded_total"},
36+
{"jvm_compilation_time_seconds_total": "jvm_compilation_time_seconds_total"},
37+
{"jvm_gc_collection_seconds": "jvm_gc_collection_seconds"},
38+
{"jvm_memory_committed_bytes": "jvm_memory_committed_bytes"},
39+
{"jvm_memory_init_bytes": "jvm_memory_init_bytes"},
40+
{"jvm_memory_max_bytes": "jvm_memory_max_bytes"},
41+
{"jvm_memory_objects_pending_finalization": "jvm_memory_objects_pending_finalization"},
42+
{"jvm_memory_pool_allocated_bytes_total": "jvm_memory_pool_allocated_bytes_total"},
43+
{"jvm_memory_pool_collection_committed_bytes": "jvm_memory_pool_collection_committed_bytes"},
44+
{"jvm_memory_pool_collection_init_bytes": "jvm_memory_pool_collection_init_bytes"},
45+
{"jvm_memory_pool_collection_max_bytes": "jvm_memory_pool_collection_max_bytes"},
46+
{"jvm_memory_pool_collection_used_bytes": "jvm_memory_pool_collection_used_bytes"},
47+
{"jvm_memory_pool_committed_bytes": "jvm_memory_pool_committed_bytes"},
48+
{"jvm_memory_pool_init_bytes": "jvm_memory_pool_init_bytes"},
49+
{"jvm_memory_pool_max_bytes": "jvm_memory_pool_max_bytes"},
50+
{"jvm_memory_pool_used_bytes": "jvm_memory_pool_used_bytes"},
51+
{"jvm_memory_used_bytes": "jvm_memory_used_bytes"},
52+
{"jvm_runtime_info": "jvm_runtime_info"},
3053
{"jvm_threads_current": "jvm_threads_current"},
54+
{"jvm_threads_daemon": "jvm_threads_daemon"},
55+
{"jvm_threads_deadlocked": "jvm_threads_deadlocked"},
56+
{"jvm_threads_deadlocked_monitor": "jvm_threads_deadlocked_monitor"},
3157
{"jvm_threads_peak": "jvm_threads_peak"},
32-
{"jvm_memory_used_bytes": "jvm_memory_used_bytes"},
33-
{"jvm_memory_committed_bytes": "jvm_memory_committed_bytes"},
58+
{"jvm_threads_started_total": "jvm_threads_started_total"},
59+
{"jvm_threads_state": "jvm_threads_state"},
3460
],
3561
"process": [
3662
{"process_cpu_seconds_total": "process_cpu_seconds_total"},
63+
{"process_max_fds": "process_max_fds"},
64+
{"process_open_fds": "process_open_fds"},
3765
{"process_resident_memory_bytes": "process_resident_memory_bytes"},
66+
{"process_start_time_seconds": "process_start_time_seconds"},
3867
{"process_virtual_memory_bytes": "process_virtual_memory_bytes"},
39-
{"process_open_fds": "process_open_fds"},
4068
],
4169
"license_details": [
4270
{"uc_license_agents_distributed_used": "uc_license.agents_distributed.used"},

stonebranch/tests/test_unit.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import io
22

3+
import pytest
34
import requests
45

6+
from datadog_checks.base import AgentCheck
57
from datadog_checks.dev.utils import get_metadata_metrics
68
from datadog_checks.stonebranch import StonebranchCheck
79

@@ -20,6 +22,28 @@
2022
uc_database_connection_pool_allocated{db_type="MySQL",pool="Client"} 5.0
2123
"""
2224

25+
PROM_TEXT_JVM = """\
26+
# HELP jvm_threads_current Current thread count of a JVM
27+
# TYPE jvm_threads_current gauge
28+
jvm_threads_current 42.0
29+
30+
# HELP jvm_threads_peak Peak thread count of a JVM
31+
# TYPE jvm_threads_peak gauge
32+
jvm_threads_peak 60.0
33+
34+
# HELP jvm_memory_used_bytes Used bytes of a given JVM memory area.
35+
# TYPE jvm_memory_used_bytes gauge
36+
jvm_memory_used_bytes{area="heap"} 123456789.0
37+
38+
# HELP jvm_memory_committed_bytes Committed (bytes) of a given JVM memory area.
39+
# TYPE jvm_memory_committed_bytes gauge
40+
jvm_memory_committed_bytes{area="heap"} 256000000.0
41+
42+
# HELP jvm_gc_collection_seconds Time spent in a given JVM garbage collector in seconds.
43+
# TYPE jvm_gc_collection_seconds gauge
44+
jvm_gc_collection_seconds{gc="G1 Young Generation"} 0.123
45+
"""
46+
2347

2448
def make_streaming_response(url: str, text: str) -> requests.Response:
2549
r = requests.Response()
@@ -87,3 +111,90 @@ def test_openmetrics_basic_auth_and_labels(aggregator, dd_run_check, mocker):
87111

88112
aggregator.assert_all_metrics_covered()
89113
aggregator.assert_metrics_using_metadata(get_metadata_metrics())
114+
115+
116+
def test_metric_groups_jvm(aggregator, dd_run_check, mocker):
117+
url = "http://test.local/metrics"
118+
instance = {
119+
"openmetrics_endpoint": url,
120+
"metric_groups": ["jvm"],
121+
"tags": ["environment:test"],
122+
}
123+
124+
mocker.patch(
125+
"requests.sessions.Session.request",
126+
autospec=True,
127+
return_value=make_streaming_response(url, PROM_TEXT_JVM),
128+
)
129+
130+
check = StonebranchCheck("stonebranch", {}, [instance])
131+
dd_run_check(check)
132+
133+
endpoint_tag = f"endpoint:{url}"
134+
base_tags = ["environment:test", endpoint_tag]
135+
136+
aggregator.assert_metric("stonebranch.jvm_threads_current", value=42.0, tags=base_tags)
137+
aggregator.assert_metric("stonebranch.jvm_threads_peak", value=60.0, tags=base_tags)
138+
aggregator.assert_metric(
139+
"stonebranch.jvm_memory_used_bytes",
140+
value=123456789.0,
141+
tags=base_tags + ["area:heap"],
142+
)
143+
aggregator.assert_metric(
144+
"stonebranch.jvm_memory_committed_bytes",
145+
value=256000000.0,
146+
tags=base_tags + ["area:heap"],
147+
)
148+
aggregator.assert_metric(
149+
"stonebranch.jvm_gc_collection_seconds",
150+
tags=base_tags + ["gc:G1 Young Generation"],
151+
)
152+
153+
154+
def test_can_connect_ok(aggregator, dd_run_check, mocker):
155+
url = "http://test.local/metrics"
156+
instance = {
157+
"openmetrics_endpoint": url,
158+
"metrics": [{"uc_build_info": "uc_build.info"}],
159+
}
160+
161+
mocker.patch(
162+
"requests.sessions.Session.request",
163+
autospec=True,
164+
return_value=make_streaming_response(
165+
url, "# HELP uc_build_info info\n# TYPE uc_build_info gauge\nuc_build_info{release=\"7.9\"} 1\n"
166+
),
167+
)
168+
169+
check = StonebranchCheck("stonebranch", {}, [instance])
170+
dd_run_check(check)
171+
172+
aggregator.assert_service_check(
173+
"stonebranch.openmetrics.health",
174+
status=AgentCheck.OK,
175+
tags=[f"endpoint:{url}"],
176+
)
177+
178+
179+
def test_can_connect_critical(aggregator, dd_run_check, mocker):
180+
url = "http://unreachable.local/metrics"
181+
instance = {
182+
"openmetrics_endpoint": url,
183+
"metrics": [{"uc_build_info": "uc_build.info"}],
184+
}
185+
186+
mocker.patch(
187+
"requests.sessions.Session.request",
188+
autospec=True,
189+
side_effect=requests.exceptions.ConnectionError("Connection refused"),
190+
)
191+
192+
check = StonebranchCheck("stonebranch", {}, [instance])
193+
with pytest.raises(Exception):
194+
dd_run_check(check)
195+
196+
aggregator.assert_service_check(
197+
"stonebranch.openmetrics.health",
198+
status=AgentCheck.CRITICAL,
199+
tags=[f"endpoint:{url}"],
200+
)

0 commit comments

Comments
 (0)