Skip to content
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

Support new implementation of Windows performance counters on Python 3 #10716

Merged
merged 2 commits into from
Dec 1, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion hyperv/assets/configuration/spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ files:
options:
- template: init_config
options:
- template: init_config/perf_counters
- template: init_config/default
- template: instances
options:
- template: instances/pdh_legacy
- template: instances/perf_counters
- template: instances/default
13 changes: 13 additions & 0 deletions hyperv/datadog_checks/hyperv/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# (C) Datadog, Inc. 2021-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
from datadog_checks.base.checks.windows.perf_counters.base import PerfCountersBaseCheckWithLegacySupport

from .metrics import METRICS_CONFIG


class HypervCheckV2(PerfCountersBaseCheckWithLegacySupport):
__NAMESPACE__ = 'hyperv'

def get_default_config(self):
return {'metrics': METRICS_CONFIG}
32 changes: 24 additions & 8 deletions hyperv/datadog_checks/hyperv/config_models/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@ def shared_service(field, value):
return get_default_field_value(field, value)


def instance_additional_metrics(field, value):
return get_default_field_value(field, value)


def instance_counter_data_types(field, value):
return get_default_field_value(field, value)
def shared_use_localized_counters(field, value):
return False


def instance_disable_generic_tags(field, value):
Expand All @@ -24,18 +20,38 @@ def instance_empty_default_hostname(field, value):
return False


def instance_host(field, value):
return '.'
def instance_enable_health_service_check(field, value):
return True


def instance_extra_metrics(field, value):
return get_default_field_value(field, value)


def instance_metrics(field, value):
return get_default_field_value(field, value)


def instance_min_collection_interval(field, value):
return 15


def instance_namespace(field, value):
return get_default_field_value(field, value)


def instance_password(field, value):
return get_default_field_value(field, value)


def instance_server(field, value):
return get_default_field_value(field, value)


def instance_server_tag(field, value):
return get_default_field_value(field, value)


def instance_service(field, value):
return get_default_field_value(field, value)

Expand Down
81 changes: 76 additions & 5 deletions hyperv/datadog_checks/hyperv/config_models/instance.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,98 @@
# Licensed under a 3-clause BSD style license (see LICENSE)
from __future__ import annotations

from typing import Optional, Sequence
from typing import Literal, Mapping, Optional, Sequence, Union

from pydantic import BaseModel, root_validator, validator
from pydantic import BaseModel, Extra, Field, root_validator, validator

from datadog_checks.base.utils.functions import identity
from datadog_checks.base.utils.models import validation

from . import defaults, validators


class Counter(BaseModel):
class Config:
extra = Extra.allow
allow_mutation = False

aggregate: Optional[Union[bool, Literal['only']]]
average: Optional[bool]
metric_name: Optional[str]
name: Optional[str]
type: Optional[str]


class InstanceCounts(BaseModel):
class Config:
allow_mutation = False

monitored: Optional[str]
total: Optional[str]
unique: Optional[str]


class ExtraMetrics(BaseModel):
class Config:
allow_mutation = False

counters: Sequence[Mapping[str, Union[str, Counter]]]
exclude: Optional[Sequence[str]]
include: Optional[Sequence[str]]
instance_counts: Optional[InstanceCounts]
name: str
tag_name: Optional[str]
use_localized_counters: Optional[bool]


class Counter1(BaseModel):
class Config:
extra = Extra.allow
allow_mutation = False

aggregate: Optional[Union[bool, Literal['only']]]
average: Optional[bool]
metric_name: Optional[str]
name: Optional[str]
type: Optional[str]


class InstanceCounts1(BaseModel):
class Config:
allow_mutation = False

monitored: Optional[str]
total: Optional[str]
unique: Optional[str]


class Metrics(BaseModel):
class Config:
allow_mutation = False

counters: Sequence[Mapping[str, Union[str, Counter1]]]
exclude: Optional[Sequence[str]]
include: Optional[Sequence[str]]
instance_counts: Optional[InstanceCounts1]
name: str
tag_name: Optional[str]
use_localized_counters: Optional[bool]


class InstanceConfig(BaseModel):
class Config:
allow_mutation = False

additional_metrics: Optional[Sequence[Sequence[str]]]
counter_data_types: Optional[Sequence[str]]
disable_generic_tags: Optional[bool]
empty_default_hostname: Optional[bool]
host: Optional[str]
enable_health_service_check: Optional[bool]
extra_metrics: Optional[Mapping[str, ExtraMetrics]]
metrics: Optional[Mapping[str, Metrics]]
min_collection_interval: Optional[float]
namespace: Optional[str] = Field(None, regex='\\w*')
password: Optional[str]
server: Optional[str]
server_tag: Optional[str]
service: Optional[str]
tags: Optional[Sequence[str]]
username: Optional[str]
Expand Down
1 change: 1 addition & 0 deletions hyperv/datadog_checks/hyperv/config_models/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Config:
allow_mutation = False

service: Optional[str]
use_localized_counters: Optional[bool]

@root_validator(pre=True)
def _initial_validation(cls, values):
Expand Down
120 changes: 88 additions & 32 deletions hyperv/datadog_checks/hyperv/data/conf.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
#
init_config:

## @param use_localized_counters - boolean - optional - default: false
## Whether or not performance object and counter names should refer to their
## locale-specific versions rather than by their English name.
#
# use_localized_counters: false

## @param service - string - optional
## Attach the tag `service:<SERVICE>` to every metric, event, and service check emitted by this integration.
##
Expand All @@ -14,51 +20,101 @@ init_config:
instances:

-
## @param host - string - optional - default: .
## The host the current check connects to.
## "." means the current host
## @param server - string - optional
## The server with which to connect, defaulting to the local machine.
#
# host: .
# server: <SERVER>

## @param username - string - optional
## The username from the credentials needed to connect to the host.
## The username used to connect to the `server`.
#
# username: <USERNAME>

## @param password - string - optional
## The password from the credentials needed to connect to the host.
## The password of `username`.
#
# password: <PASSWORD>

## @param additional_metrics - list of lists - optional
## The additional metrics is a list of items that represent additional counters to collect.
## Each item is a list of strings, formatted as follows:
##
## ['<COUNTERSET_NAME>', <COUNTER_INSTANCE_NAME>, '<COUNTER_NAME>', <METRIC_NAME>, <METRIC_TYPE>]
##
## <COUNTERSET_NAME> is the name of the PDH counter set (the name of the counter).
## <COUNTER_INSTANCE_NAME> is the specific counter instance to collect, for example
## "Default Web Site". Specify 'none' for all instances of
## the counter.
## <COUNTER_NAME> is the individual counter to report.
## <METRIC_NAME> is the name that displays in Datadog.
## <METRIC_TYPE> is from the standard choices for all Agent checks, such as gauge,
## rate, histogram, or count.
## @param enable_health_service_check - boolean - optional - default: true
## Whether or not to send a service check named `<NAMESPACE>.windows.perf.health` which reports
## the health of the `server`.
#
# additional_metrics:
# - [Processor, none, '% Processor Time', processor.time, gauge]
# - [Processor, none, '% User Time', processor.user.time, gauge]
# enable_health_service_check: true

## @param counter_data_types - list of strings - optional
## counter_data_types is a list of <METRIC_NAME>,<DATA_TYPE> elements that
## allow the precision in which counters are queried on a per metric basis.
## <METRIC_NAME>: The name of your metric
## <DATA_TYPE> : The type of your metric (int or float)
## @param server_tag - string - optional
## The name used for tagging `server`. The value defined here replaces the `server:` tag key.
#
# server_tag: <SERVER_TAG>

## @param extra_metrics - mapping - optional
## This mapping defines which metrics to collect from the performance
## counters on the `server`. For more information, see:
## https://docs.microsoft.com/en-us/windows/win32/perfctrs/about-performance-counters
##
## The top-level keys are the names of the desired performance objects:
##
## metrics:
## System:
## <OPTION_1>: ...
## <OPTION_2>: ...
## LogicalDisk:
## <OPTION_1>: ...
## <OPTION_2>: ...
##
## The available performance object options are:
##
## name (required): This becomes the prefix of all metrics submitted for each counter.
## counters (required): This is the list of counters to collect.
## tag_name: This is the name of the tag used for instances. For example, if the tag name for
## the `LogicalDisk` performance object is `disk`, a possible tag would be `disk:C`.
## If not set, the default tag name is `instance`.
## 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.
## instance_counts: This is a mapping used to select the count of instances to submit, where each
## key is a count type and the value is the metric name to use, ignoring `name`.
## The `total` count type represents the total number of encountered instances.
## The `monitored` count type represents the number of monitored instances after
## `include`/`exclude` filtering. The `unique` count type represents the number
## of unique instance names that are monitored.
## use_localized_counters: Whether or not performance object and counter names should refer to their
## locale-specific versions rather than by their English name. This overrides
## any defined value in `init_config`.
##
## The key for each counter object represents the name of the desired counter.
## Counters may be defined in the following ways:
##
## 1. If a value is a string, then it represents the suffix of the sent metric name, for example:
##
## counters:
## - '% Free Space': usable
## - Current Disk Queue Length: queue_length.current
##
## 2. If a value is a mapping, then it must have a `name` key that represents the suffix of the
## sent metric name, for example:
##
## counters:
## - '% Free Space':
## name: usable
## - Current Disk Queue Length:
## name: queue_length.current
##
## The available counter options are:
##
## type: This represents how the metric is handled, defaulting to `gauge`. The available types are:
## gauge, rate, count, monotonic_count, service_check, temporal_percent, time_elapsed
## average: When there are multiple values for the same instance name (e.g. multiple processes
## spawned with the same name) the check submits the sum. Setting this option to `true`
## instructs the check to calculate the average instead.
## aggregate: Whether or not to send an additional metric that is the aggregation of all values for
## every monitored instance. If `average` is set to `true` the check submits the average as
## a metric suffixed by `avg`, otherwise it submits the sum as a metric suffixed by `sum`.
## If this is set to `only`, the check does not submit a metric per instance.
## metric_name: This represents the full metric name in lieu of a `name` key and is not be prefixed by
## the parent object's `name` key.
#
# counter_data_types:
# - <METRIC_NAME>,<DATA_TYPE>
# - processor.time,int
# - processor.user.time,float
# extra_metrics: {}

## @param tags - list of strings - optional
## A list of tags to attach to every metric and service check emitted by this instance.
Expand Down
10 changes: 10 additions & 0 deletions hyperv/datadog_checks/hyperv/hyperv.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
# (C) Datadog, Inc. 2018-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)
from six import PY3

from datadog_checks.base import PDHBaseCheck

from .metrics import DEFAULT_COUNTERS


class HypervCheck(PDHBaseCheck):
def __new__(cls, name, init_config, instances):
if PY3:
from .check import HypervCheckV2

return HypervCheckV2(name, init_config, instances)
else:
return super(HypervCheck, cls).__new__(cls)

def __init__(self, name, init_config, instances=None):
super(HypervCheck, self).__init__(name, init_config, instances=instances, counter_list=DEFAULT_COUNTERS)
Loading