Skip to content
1 change: 1 addition & 0 deletions active_directory/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose the `include_total` option in the perf-counter spec, allowing the `_Total` aggregate instance to be collected for selected performance objects.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ExtraMetrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand All @@ -75,6 +76,7 @@ class Metrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ instances:
## include: This is the list of regular expressions used to select which instances to monitor.
## If not set, all instances are monitored.
## exclude: This is the list of regular expressions used to select which instances to ignore.
## If not set, no instances are ignored. Note: `_Total` instances are always ignored.
## If not set, no instances are ignored. Note: `_Total` instances are ignored by default;
## set `include_total` to `true` to collect them.
## include_total: Whether to collect the `_Total` aggregate instance for this performance object.
## Defaults to `false`. Most performance objects report `_Total` as the sum of the
## individual instances, in which case it is preferable to compute the total in
## Datadog. However, some perf objects (e.g. `MSExchangeTransport Queues`) report
## data on `_Total` that is not derivable from the visible instances, and in that
## case opting in restores the missing data without forcing the collection of every
## individual instance.
## include_fast: This is the list of wildcards or exact instance names used to select which
## instances to monitor. It is faster than the regular expression `include` filter
## because it relies on the Windows PDH built-in wildcard filtering.
Expand Down
1 change: 1 addition & 0 deletions aspdotnet/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose the `include_total` option in the perf-counter spec, allowing the `_Total` aggregate instance to be collected for selected performance objects.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ExtraMetrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand All @@ -75,6 +76,7 @@ class Metrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand Down
10 changes: 9 additions & 1 deletion aspdotnet/datadog_checks/aspdotnet/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ instances:
## include: This is the list of regular expressions used to select which instances to monitor.
## If not set, all instances are monitored.
## exclude: This is the list of regular expressions used to select which instances to ignore.
## If not set, no instances are ignored. Note: `_Total` instances are always ignored.
## If not set, no instances are ignored. Note: `_Total` instances are ignored by default;
## set `include_total` to `true` to collect them.
## include_total: Whether to collect the `_Total` aggregate instance for this performance object.
## Defaults to `false`. Most performance objects report `_Total` as the sum of the
## individual instances, in which case it is preferable to compute the total in
## Datadog. However, some perf objects (e.g. `MSExchangeTransport Queues`) report
## data on `_Total` that is not derivable from the visible instances, and in that
## case opting in restores the missing data without forcing the collection of every
## individual instance.
## include_fast: This is the list of wildcards or exact instance names used to select which
## instances to monitor. It is faster than the regular expression `include` filter
## because it relies on the Windows PDH built-in wildcard filtering.
Expand Down
1 change: 1 addition & 0 deletions datadog_checks_base/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add a per-performance-object `include_total` option (default `false`) to the Windows perf-counter framework. When set to `true`, the `_Total` aggregate instance is collected instead of being excluded by default.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,14 @@ def __init__(self, check, connection, name, config, use_localized_counters, tags
# See: https://learn.microsoft.com/en-us/windows/win32/perfctrs/about-performance-counters
self.include_pattern = re.compile('|'.join(include_patterns), re.IGNORECASE)

# Opt in to collect the `_Total` aggregate instance, which is excluded by default because
# it is usually derivable from the per-instance values. Some perf objects (e.g.
# `MSExchangeTransport Queues`) report data on `_Total` that is not the sum of the
# visible instances, in which case excluding it loses information.
include_total = config.get('include_total', False)
if not isinstance(include_total, bool):
raise ConfigTypeError(f'Option `include_total` for performance object `{self.name}` must be a boolean')

# List of regex patterns to filter multi-instance counters AFTER ALL data
# is collected and retrieved from PDH layer
exclude_patterns = config.get('exclude', [])
Expand All @@ -67,11 +75,13 @@ def __init__(self, check, connection, name, config, use_localized_counters, tags
f'Pattern #{i} of option `exclude` for performance object `{self.name}` must be a string'
)

final_exclude_patterns = [r'\b_Total\b']
final_exclude_patterns = [] if include_total else [r'\b_Total\b']
final_exclude_patterns.extend(exclude_patterns)
# `(?!)` is a never-matching pattern, used when there is nothing to exclude so that
# `self.exclude_pattern.search(...)` always returns None without special-casing.
# Instance names are not case-sensitive, so instances should not have names that differ only in case.
# See: https://learn.microsoft.com/en-us/windows/win32/perfctrs/about-performance-counters
self.exclude_pattern = re.compile('|'.join(final_exclude_patterns), re.IGNORECASE)
self.exclude_pattern = re.compile('|'.join(final_exclude_patterns) or r'(?!)', re.IGNORECASE)

# List of wildcards or instance name directly to filter multi-instance counters by PDH layer itself.
# Thus it is faster and and less resource intensive than regex-based include filtering.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,58 @@ def test_include_case_insensitive(aggregator, dd_run_check, mock_performance_obj
aggregator.assert_metric_has_tag('test.foo.bar', 'instance:Barbat', count=0)

aggregator.assert_all_metrics_covered()


def test_include_total(aggregator, dd_run_check, mock_performance_objects):
mock_performance_objects({'Foo': (['_Total', 'baz'], {'Bar': [1, 2]})})
check = get_check({'metrics': {'Foo': {'name': 'foo', 'include_total': True, 'counters': [{'Bar': 'bar'}]}}})
dd_run_check(check)

tags = ['instance:_Total']
tags.extend(GLOBAL_TAGS)
aggregator.assert_metric('test.foo.bar', 1, tags=tags)

tags = ['instance:baz']
tags.extend(GLOBAL_TAGS)
aggregator.assert_metric('test.foo.bar', 2, tags=tags)

aggregator.assert_all_metrics_covered()


def test_include_total_with_lowercase_instance(aggregator, dd_run_check, mock_performance_objects):
mock_performance_objects({'Foo': (['_total', 'baz'], {'Bar': [1, 2]})})
check = get_check({'metrics': {'Foo': {'name': 'foo', 'include_total': True, 'counters': [{'Bar': 'bar'}]}}})
dd_run_check(check)

tags = ['instance:_total']
tags.extend(GLOBAL_TAGS)
aggregator.assert_metric('test.foo.bar', 1, tags=tags)

aggregator.assert_metric_has_tag('test.foo.bar', 'instance:baz', count=1)

aggregator.assert_all_metrics_covered()


def test_include_total_respects_user_exclude(aggregator, dd_run_check, mock_performance_objects):
mock_performance_objects({'Foo': (['_Total', 'baz'], {'Bar': [1, 2]})})
check = get_check(
{
'metrics': {
'Foo': {
'name': 'foo',
'include_total': True,
'exclude': ['baz'],
'counters': [{'Bar': 'bar'}],
}
}
}
)
dd_run_check(check)

tags = ['instance:_Total']
tags.extend(GLOBAL_TAGS)
aggregator.assert_metric('test.foo.bar', 1, tags=tags)

aggregator.assert_metric_has_tag('test.foo.bar', 'instance:baz', count=0)

aggregator.assert_all_metrics_covered()
1 change: 1 addition & 0 deletions datadog_checks_dev/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add `include_total` option to the Windows perf-counter spec template, allowing integrations to opt in to collecting the `_Total` aggregate instance.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,15 @@
include: This is the list of regular expressions used to select which instances to monitor.
If not set, all instances are monitored.
exclude: This is the list of regular expressions used to select which instances to ignore.
If not set, no instances are ignored. Note: `_Total` instances are always ignored.
If not set, no instances are ignored. Note: `_Total` instances are ignored by default;
set `include_total` to `true` to collect them.
include_total: Whether to collect the `_Total` aggregate instance for this performance object.
Defaults to `false`. Most performance objects report `_Total` as the sum of the
individual instances, in which case it is preferable to compute the total in
Datadog. However, some perf objects (e.g. `MSExchangeTransport Queues`) report
data on `_Total` that is not derivable from the visible instances, and in that
case opting in restores the missing data without forcing the collection of every
individual instance.
include_fast: This is the list of wildcards or exact instance names used to select which
instances to monitor. It is faster than the regular expression `include` filter
because it relies on the Windows PDH built-in wildcard filtering.
Expand Down Expand Up @@ -95,6 +103,8 @@
type: array
items:
type: string
- name: include_total
type: boolean
- name: instance_counts
type: object
properties:
Expand Down
1 change: 1 addition & 0 deletions dotnetclr/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose the `include_total` option in the perf-counter spec, allowing the `_Total` aggregate instance to be collected for selected performance objects.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ExtraMetrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand All @@ -75,6 +76,7 @@ class Metrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand Down
10 changes: 9 additions & 1 deletion dotnetclr/datadog_checks/dotnetclr/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ instances:
## include: This is the list of regular expressions used to select which instances to monitor.
## If not set, all instances are monitored.
## exclude: This is the list of regular expressions used to select which instances to ignore.
## If not set, no instances are ignored. Note: `_Total` instances are always ignored.
## If not set, no instances are ignored. Note: `_Total` instances are ignored by default;
## set `include_total` to `true` to collect them.
## include_total: Whether to collect the `_Total` aggregate instance for this performance object.
## Defaults to `false`. Most performance objects report `_Total` as the sum of the
## individual instances, in which case it is preferable to compute the total in
## Datadog. However, some perf objects (e.g. `MSExchangeTransport Queues`) report
## data on `_Total` that is not derivable from the visible instances, and in that
## case opting in restores the missing data without forcing the collection of every
## individual instance.
## include_fast: This is the list of wildcards or exact instance names used to select which
## instances to monitor. It is faster than the regular expression `include` filter
## because it relies on the Windows PDH built-in wildcard filtering.
Expand Down
1 change: 1 addition & 0 deletions exchange_server/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose the `include_total` option in the perf-counter spec, allowing the `_Total` aggregate instance to be collected for selected performance objects.
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ExtraMetrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand All @@ -75,6 +76,7 @@ class Metrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ instances:
## include: This is the list of regular expressions used to select which instances to monitor.
## If not set, all instances are monitored.
## exclude: This is the list of regular expressions used to select which instances to ignore.
## If not set, no instances are ignored. Note: `_Total` instances are always ignored.
## If not set, no instances are ignored. Note: `_Total` instances are ignored by default;
## set `include_total` to `true` to collect them.
## include_total: Whether to collect the `_Total` aggregate instance for this performance object.
## Defaults to `false`. Most performance objects report `_Total` as the sum of the
## individual instances, in which case it is preferable to compute the total in
## Datadog. However, some perf objects (e.g. `MSExchangeTransport Queues`) report
## data on `_Total` that is not derivable from the visible instances, and in that
## case opting in restores the missing data without forcing the collection of every
## individual instance.
## include_fast: This is the list of wildcards or exact instance names used to select which
## instances to monitor. It is faster than the regular expression `include` filter
## because it relies on the Windows PDH built-in wildcard filtering.
Expand Down
1 change: 1 addition & 0 deletions hyperv/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose the `include_total` option in the perf-counter spec, allowing the `_Total` aggregate instance to be collected for selected performance objects.
2 changes: 2 additions & 0 deletions hyperv/datadog_checks/hyperv/config_models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class ExtraMetrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand All @@ -75,6 +76,7 @@ class Metrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand Down
10 changes: 9 additions & 1 deletion hyperv/datadog_checks/hyperv/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,15 @@ instances:
## include: This is the list of regular expressions used to select which instances to monitor.
## If not set, all instances are monitored.
## exclude: This is the list of regular expressions used to select which instances to ignore.
## If not set, no instances are ignored. Note: `_Total` instances are always ignored.
## If not set, no instances are ignored. Note: `_Total` instances are ignored by default;
## set `include_total` to `true` to collect them.
## include_total: Whether to collect the `_Total` aggregate instance for this performance object.
## Defaults to `false`. Most performance objects report `_Total` as the sum of the
## individual instances, in which case it is preferable to compute the total in
## Datadog. However, some perf objects (e.g. `MSExchangeTransport Queues`) report
## data on `_Total` that is not derivable from the visible instances, and in that
## case opting in restores the missing data without forcing the collection of every
## individual instance.
## include_fast: This is the list of wildcards or exact instance names used to select which
## instances to monitor. It is faster than the regular expression `include` filter
## because it relies on the Windows PDH built-in wildcard filtering.
Expand Down
1 change: 1 addition & 0 deletions iis/changelog.d/23530.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Expose the `include_total` option in the perf-counter spec, allowing the `_Total` aggregate instance to be collected for selected performance objects.
2 changes: 2 additions & 0 deletions iis/datadog_checks/iis/config_models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ExtraMetrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand All @@ -84,6 +85,7 @@ class Metrics(BaseModel):
counters: tuple[MappingProxyType[str, Union[str, Counters]], ...]
exclude: Optional[tuple[str, ...]] = None
include: Optional[tuple[str, ...]] = None
include_total: Optional[bool] = None
instance_counts: Optional[InstanceCounts] = None
name: str
tag_name: Optional[str] = None
Expand Down
Loading
Loading