-
Notifications
You must be signed in to change notification settings - Fork 1.6k
openmetrics v2: merge mapping-valued defaults instead of replacing them #24921
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Stop an OpenMetrics V2 instance that configures ``rename_labels`` from silently discarding the renames its check declares in ``get_default_config``. Mapping-valued defaults are now merged with the instance's mapping entry by entry, with the instance's own entries taking precedence, instead of being replaced wholesale. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,6 +31,96 @@ def get_default_config(self): | |
| aggregator.assert_all_metrics_covered() | ||
|
|
||
|
|
||
| def test_default_config_mapping_merged_with_instance(aggregator, dd_run_check, mock_http_response): | ||
| """ | ||
| A mapping-valued default is merged with the instance's mapping for the same option, entry by | ||
| entry. The instance config is layered over the defaults in a `ChainMap`, which resolves keys | ||
| shallowly, so without the merge an instance that sets `rename_labels` at all would shadow the | ||
| class default wholesale and silently lose renames the check depends on. | ||
| """ | ||
|
|
||
| class Check(OpenMetricsBaseCheckV2): | ||
| __NAMESPACE__ = 'test' | ||
|
|
||
| def get_default_config(self): | ||
| return {'metrics': ['.+'], 'rename_labels': {'foo': 'bar'}} | ||
|
|
||
| mock_http_response( | ||
| """ | ||
| # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. | ||
| # TYPE go_memstats_alloc_bytes gauge | ||
| go_memstats_alloc_bytes{foo="baz",qux="quux"} 6.396288e+06 | ||
| """ | ||
| ) | ||
| check = Check('test', {}, [{'openmetrics_endpoint': 'test', 'rename_labels': {'qux': 'corge'}}]) | ||
| dd_run_check(check) | ||
|
|
||
| # `bar:baz` is the class default's rename, `corge:quux` the instance's own. | ||
| aggregator.assert_metric( | ||
| 'test.go_memstats_alloc_bytes', | ||
| 6396288, | ||
| metric_type=aggregator.GAUGE, | ||
| tags=['endpoint:test', 'bar:baz', 'corge:quux'], | ||
| ) | ||
|
|
||
| aggregator.assert_all_metrics_covered() | ||
|
|
||
|
|
||
| def test_default_config_mapping_entry_overridden_by_instance(aggregator, dd_run_check, mock_http_response): | ||
| """ | ||
| Merging mapping-valued defaults must not cost the ability to override one: an instance entry for | ||
| the same key as a default entry still wins. | ||
| """ | ||
|
|
||
| class Check(OpenMetricsBaseCheckV2): | ||
| __NAMESPACE__ = 'test' | ||
|
|
||
| def get_default_config(self): | ||
| return {'metrics': ['.+'], 'rename_labels': {'foo': 'bar'}} | ||
|
|
||
| mock_http_response( | ||
| """ | ||
| # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. | ||
| # TYPE go_memstats_alloc_bytes gauge | ||
| go_memstats_alloc_bytes{foo="baz"} 6.396288e+06 | ||
| """ | ||
| ) | ||
| check = Check('test', {}, [{'openmetrics_endpoint': 'test', 'rename_labels': {'foo': 'corge'}}]) | ||
| dd_run_check(check) | ||
|
|
||
| aggregator.assert_metric( | ||
| 'test.go_memstats_alloc_bytes', 6396288, metric_type=aggregator.GAUGE, tags=['endpoint:test', 'corge:baz'] | ||
| ) | ||
|
|
||
| aggregator.assert_all_metrics_covered() | ||
|
|
||
|
|
||
| def test_default_config_mapping_not_shared_between_scrapers(aggregator, dd_run_check, mock_http_response): | ||
| """ | ||
| The merge must not write back into the mapping `get_default_config` returned, or a check with | ||
| several scraper configs would accumulate every scraper's custom renames into the shared default. | ||
| """ | ||
| default_renames = {'foo': 'bar'} | ||
|
|
||
| class Check(OpenMetricsBaseCheckV2): | ||
| __NAMESPACE__ = 'test' | ||
|
|
||
| def get_default_config(self): | ||
| return {'metrics': ['.+'], 'rename_labels': default_renames} | ||
|
|
||
| mock_http_response( | ||
| """ | ||
| # HELP go_memstats_alloc_bytes Number of bytes allocated and still in use. | ||
| # TYPE go_memstats_alloc_bytes gauge | ||
| go_memstats_alloc_bytes{foo="baz"} 6.396288e+06 | ||
| """ | ||
| ) | ||
| check = Check('test', {}, [{'openmetrics_endpoint': 'test', 'rename_labels': {'qux': 'corge'}}]) | ||
| dd_run_check(check) | ||
|
|
||
| assert default_renames == {'foo': 'bar'} | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This assertion only verifies that the caller-owned defaults dictionary was not mutated; it never creates a second scraper configuration or checks its effective renames, so it does not verify the stated behavior that one scraper's custom renames cannot leak into another. An implementation that caches accumulated merges on the check while leaving AGENTS.md reference: AGENTS.md:L177-L180 Useful? React with 👍 / 👎. |
||
|
|
||
|
|
||
| def test_tag_by_endpoint(aggregator, dd_run_check, mock_http_response): | ||
| mock_http_response( | ||
| """ | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a Kuma instance explicitly supplies
share_labels: {}or configures only a different source metric, this generic mapping merge also retains Kuma's defaultcp_infoentry fromkuma/datadog_checks/kuma/check.py:42. Previously the instance mapping replaced that default, but after this changeLabelAggregatoragain propagatesinstance_idandversionto the other metrics, unexpectedly changing their tags and leaving no way to disable that sharing. Restrict this merge torename_labels, or define an explicit opt-out for other mapping-valued options.Useful? React with 👍 / 👎.