datadog-checks-base 37.7.0__py2.py3-none-any.whl → 37.8.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datadog_checks/base/__about__.py +1 -1
- datadog_checks/base/__init__.py +3 -43
- datadog_checks/base/__init__.pyi +31 -0
- datadog_checks/base/checks/__init__.py +2 -4
- datadog_checks/base/checks/__init__.pyi +7 -0
- datadog_checks/base/checks/base.py +58 -27
- datadog_checks/base/checks/kube_leader/__init__.py +2 -5
- datadog_checks/base/checks/kube_leader/__init__.pyi +8 -0
- datadog_checks/base/checks/kubelet_base/__init__.py +6 -0
- datadog_checks/base/checks/kubelet_base/__init__.pyi +6 -0
- datadog_checks/base/checks/openmetrics/__init__.py +2 -4
- datadog_checks/base/checks/openmetrics/__init__.pyi +6 -0
- datadog_checks/base/checks/openmetrics/v2/scraper.py +0 -2
- datadog_checks/base/checks/openmetrics/v2/transformers/__init__.py +3 -10
- datadog_checks/base/checks/openmetrics/v2/transformers/__init__.pyi +26 -0
- datadog_checks/base/checks/prometheus/__init__.py +2 -5
- datadog_checks/base/checks/prometheus/__init__.pyi +8 -0
- datadog_checks/base/checks/prometheus/mixins.py +1 -1
- datadog_checks/base/checks/win/__init__.py +2 -4
- datadog_checks/base/checks/win/__init__.pyi +7 -0
- datadog_checks/base/checks/win/wmi/__init__.py +2 -386
- datadog_checks/base/checks/win/wmi/__init__.pyi +32 -0
- datadog_checks/base/checks/win/wmi/base.py +390 -0
- datadog_checks/base/log.py +10 -8
- datadog_checks/base/stubs/datadog_agent.py +5 -6
- datadog_checks/base/utils/_http_utils.py +51 -0
- datadog_checks/base/utils/db/__init__.py +3 -2
- datadog_checks/base/utils/db/__init__.pyi +7 -0
- datadog_checks/base/utils/db/sql.py +2 -2
- datadog_checks/base/utils/db/utils.py +3 -3
- datadog_checks/base/utils/discovery/__init__.py +3 -1
- datadog_checks/base/utils/discovery/__init__.pyi +6 -0
- datadog_checks/base/utils/format/__init__.py +3 -0
- datadog_checks/base/utils/format/_json.py +43 -0
- datadog_checks/base/utils/format/json.py +30 -0
- datadog_checks/base/utils/http.py +37 -66
- datadog_checks/base/utils/metadata/__init__.py +3 -1
- datadog_checks/base/utils/metadata/__init__.pyi +6 -0
- datadog_checks/base/utils/prometheus/__init__.py +2 -1
- datadog_checks/base/utils/prometheus/__init__.pyi +6 -0
- datadog_checks/base/utils/replay/execute.py +6 -5
- datadog_checks/base/utils/replay/redirect.py +8 -7
- datadog_checks/base/utils/serialization.py +5 -0
- datadog_checks/base/utils/tracing.py +10 -1
- {datadog_checks_base-37.7.0.dist-info → datadog_checks_base-37.8.0.dist-info}/METADATA +18 -8
- {datadog_checks_base-37.7.0.dist-info → datadog_checks_base-37.8.0.dist-info}/RECORD +47 -29
- {datadog_checks_base-37.7.0.dist-info → datadog_checks_base-37.8.0.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# (C) Datadog, Inc. 2025-present
|
|
2
|
+
# All rights reserved
|
|
3
|
+
# Licensed under a 3-clause BSD style license (see LICENSE)
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import warnings
|
|
7
|
+
from typing import TYPE_CHECKING, Any
|
|
8
|
+
|
|
9
|
+
import lazy_loader
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from collections.abc import Callable
|
|
13
|
+
|
|
14
|
+
from datadog_checks.base.utils.format import _json
|
|
15
|
+
|
|
16
|
+
with warnings.catch_warnings():
|
|
17
|
+
warnings.filterwarnings('ignore', category=RuntimeWarning, module='lazy_loader')
|
|
18
|
+
json: _json = lazy_loader.load('datadog_checks.base.utils.format._json')
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def decode(s: str | bytes) -> Any:
|
|
22
|
+
return json.decode(s)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def encode(obj: Any, *, sort_keys: bool = False, default: Callable[[Any], Any] | None = None) -> str:
|
|
26
|
+
return json.encode(obj, sort_keys=sort_keys, default=default)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def encode_bytes(obj: Any, *, sort_keys: bool = False, default: Callable[[Any], Any] | None = None) -> bytes:
|
|
30
|
+
return json.encode_bytes(obj, sort_keys=sort_keys, default=default)
|
|
@@ -1,28 +1,27 @@
|
|
|
1
1
|
# (C) Datadog, Inc. 2019-present
|
|
2
2
|
# All rights reserved
|
|
3
3
|
# Licensed under a 3-clause BSD style license (see LICENSE)
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
4
6
|
import logging
|
|
5
7
|
import os
|
|
6
8
|
import re
|
|
7
9
|
import ssl
|
|
8
|
-
|
|
10
|
+
import warnings
|
|
11
|
+
from contextlib import ExitStack, contextmanager
|
|
9
12
|
from copy import deepcopy
|
|
10
|
-
from io import open
|
|
11
|
-
from ipaddress import ip_address, ip_network
|
|
12
13
|
from urllib.parse import quote, urlparse, urlunparse
|
|
13
14
|
|
|
15
|
+
import lazy_loader
|
|
14
16
|
import requests
|
|
15
|
-
import requests_unixsocket
|
|
16
17
|
from binary import KIBIBYTE
|
|
17
|
-
from cryptography.x509 import load_der_x509_certificate
|
|
18
|
-
from cryptography.x509.extensions import ExtensionNotFound
|
|
19
|
-
from cryptography.x509.oid import AuthorityInformationAccessOID, ExtensionOID
|
|
20
18
|
from requests import auth as requests_auth
|
|
21
19
|
from requests.exceptions import SSLError
|
|
22
|
-
from
|
|
20
|
+
from urllib3.exceptions import InsecureRequestWarning
|
|
23
21
|
from wrapt import ObjectProxy
|
|
24
22
|
|
|
25
23
|
from datadog_checks.base.agent import datadog_agent
|
|
24
|
+
from datadog_checks.base.utils import _http_utils
|
|
26
25
|
|
|
27
26
|
from ..config import is_affirmative
|
|
28
27
|
from ..errors import ConfigurationError
|
|
@@ -31,19 +30,16 @@ from .headers import get_default_headers, update_headers
|
|
|
31
30
|
from .network import CertAdapter, create_socket_connection
|
|
32
31
|
from .time import get_timestamp
|
|
33
32
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
# See Performance Optimizations in this package's README.md.
|
|
34
|
+
requests_kerberos = lazy_loader.load('requests_kerberos')
|
|
35
|
+
requests_ntlm = lazy_loader.load('requests_ntlm')
|
|
36
|
+
requests_oauthlib = lazy_loader.load('requests_oauthlib')
|
|
37
|
+
requests_unixsocket = lazy_loader.load('requests_unixsocket')
|
|
38
|
+
jwt = lazy_loader.load('jwt')
|
|
39
|
+
ipaddress = lazy_loader.load('ipaddress')
|
|
38
40
|
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
requests_kerberos = None
|
|
42
|
-
requests_ntlm = None
|
|
43
|
-
requests_oauthlib = None
|
|
44
|
-
oauth2 = None
|
|
45
|
-
jwt = None
|
|
46
|
-
serialization = None
|
|
41
|
+
# We log instead of emit warnings for unintentionally insecure HTTPS requests
|
|
42
|
+
warnings.simplefilter('ignore', InsecureRequestWarning)
|
|
47
43
|
|
|
48
44
|
LOGGER = logging.getLogger(__file__)
|
|
49
45
|
|
|
@@ -394,7 +390,7 @@ class RequestsWrapper(object):
|
|
|
394
390
|
new_options = self.populate_options(options)
|
|
395
391
|
|
|
396
392
|
if url.startswith('https') and not self.ignore_tls_warning and not new_options['verify']:
|
|
397
|
-
self.logger.
|
|
393
|
+
self.logger.debug(u'An unverified HTTPS request is being made to %s', url)
|
|
398
394
|
|
|
399
395
|
extra_headers = options.pop('extra_headers', None)
|
|
400
396
|
if extra_headers is not None:
|
|
@@ -499,23 +495,26 @@ class RequestsWrapper(object):
|
|
|
499
495
|
# https://tools.ietf.org/html/rfc3280#section-4.2.2.1
|
|
500
496
|
# https://tools.ietf.org/html/rfc5280#section-5.2.7
|
|
501
497
|
try:
|
|
502
|
-
cert =
|
|
498
|
+
cert = _http_utils.cryptography_x509_load_certificate(der_cert)
|
|
503
499
|
except Exception as e:
|
|
504
500
|
self.logger.error('Error while deserializing peer certificate to discover intermediate certificates: %s', e)
|
|
505
501
|
return
|
|
506
502
|
|
|
507
503
|
try:
|
|
508
504
|
authority_information_access = cert.extensions.get_extension_for_oid(
|
|
509
|
-
|
|
505
|
+
_http_utils.cryptography_x509_ExtensionOID.AUTHORITY_INFORMATION_ACCESS
|
|
510
506
|
)
|
|
511
|
-
except
|
|
507
|
+
except _http_utils.cryptography_x509_ExtensionNotFound:
|
|
512
508
|
self.logger.debug(
|
|
513
509
|
'No Authority Information Access extension found, skipping discovery of intermediate certificates'
|
|
514
510
|
)
|
|
515
511
|
return
|
|
516
512
|
|
|
517
513
|
for access_description in authority_information_access.value:
|
|
518
|
-
if
|
|
514
|
+
if (
|
|
515
|
+
access_description.access_method
|
|
516
|
+
!= _http_utils.cryptography_x509_AuthorityInformationAccessOID.CA_ISSUERS
|
|
517
|
+
):
|
|
519
518
|
continue
|
|
520
519
|
|
|
521
520
|
uri = access_description.access_location.value
|
|
@@ -541,7 +540,7 @@ class RequestsWrapper(object):
|
|
|
541
540
|
# Enables HostHeaderSSLAdapter
|
|
542
541
|
# https://toolbelt.readthedocs.io/en/latest/adapters.html#hostheaderssladapter
|
|
543
542
|
if self.tls_use_host_header:
|
|
544
|
-
self._session.mount('https://',
|
|
543
|
+
self._session.mount('https://', _http_utils.HostHeaderSSLAdapter())
|
|
545
544
|
# Enable Unix Domain Socket (UDS) support.
|
|
546
545
|
# See: https://github.com/msabramo/requests-unixsocket
|
|
547
546
|
self._session.mount('{}://'.format(UDS_SCHEME), requests_unixsocket.UnixAdapter())
|
|
@@ -619,9 +618,9 @@ def should_bypass_proxy(url, no_proxy_uris):
|
|
|
619
618
|
try:
|
|
620
619
|
# If no_proxy_uri is an IP or IP CIDR.
|
|
621
620
|
# A ValueError is raised if address does not represent a valid IPv4 or IPv6 address.
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
if
|
|
621
|
+
ip_network = ipaddress.ip_network(ensure_unicode(no_proxy_uri))
|
|
622
|
+
ip_address = ipaddress.ip_address(ensure_unicode(parsed_uri))
|
|
623
|
+
if ip_address in ip_network:
|
|
625
624
|
return True
|
|
626
625
|
except ValueError:
|
|
627
626
|
# Treat no_proxy_uri as a domain name
|
|
@@ -655,21 +654,13 @@ def create_digest_auth(config):
|
|
|
655
654
|
|
|
656
655
|
|
|
657
656
|
def create_ntlm_auth(config):
|
|
658
|
-
global requests_ntlm
|
|
659
|
-
if requests_ntlm is None:
|
|
660
|
-
import requests_ntlm
|
|
661
|
-
|
|
662
657
|
return requests_ntlm.HttpNtlmAuth(config['ntlm_domain'], config['password'])
|
|
663
658
|
|
|
664
659
|
|
|
665
660
|
def create_kerberos_auth(config):
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
KERBEROS_STRATEGIES['required'] = requests_kerberos.REQUIRED
|
|
671
|
-
KERBEROS_STRATEGIES['optional'] = requests_kerberos.OPTIONAL
|
|
672
|
-
KERBEROS_STRATEGIES['disabled'] = requests_kerberos.DISABLED
|
|
661
|
+
KERBEROS_STRATEGIES['required'] = requests_kerberos.REQUIRED
|
|
662
|
+
KERBEROS_STRATEGIES['optional'] = requests_kerberos.OPTIONAL
|
|
663
|
+
KERBEROS_STRATEGIES['disabled'] = requests_kerberos.DISABLED
|
|
673
664
|
|
|
674
665
|
# For convenience
|
|
675
666
|
if config['kerberos_auth'] is None or is_affirmative(config['kerberos_auth']):
|
|
@@ -692,15 +683,11 @@ def create_kerberos_auth(config):
|
|
|
692
683
|
|
|
693
684
|
|
|
694
685
|
def create_aws_auth(config):
|
|
695
|
-
global requests_aws
|
|
696
|
-
if requests_aws is None:
|
|
697
|
-
from aws_requests_auth import boto_utils as requests_aws
|
|
698
|
-
|
|
699
686
|
for setting in ('aws_host', 'aws_region', 'aws_service'):
|
|
700
687
|
if not config[setting]:
|
|
701
688
|
raise ConfigurationError('AWS auth requires the setting `{}`'.format(setting))
|
|
702
689
|
|
|
703
|
-
return
|
|
690
|
+
return _http_utils.BotoAWSRequestsAuth(
|
|
704
691
|
aws_host=config['aws_host'], aws_region=config['aws_region'], aws_service=config['aws_service']
|
|
705
692
|
)
|
|
706
693
|
|
|
@@ -851,15 +838,7 @@ class AuthTokenOAuthReader(object):
|
|
|
851
838
|
|
|
852
839
|
def read(self, **request):
|
|
853
840
|
if self._token is None or get_timestamp() >= self._expiration or 'error' in request:
|
|
854
|
-
|
|
855
|
-
if oauth2 is None:
|
|
856
|
-
from oauthlib import oauth2
|
|
857
|
-
|
|
858
|
-
global requests_oauthlib
|
|
859
|
-
if requests_oauthlib is None:
|
|
860
|
-
import requests_oauthlib
|
|
861
|
-
|
|
862
|
-
client = oauth2.BackendApplicationClient(client_id=self._client_id)
|
|
841
|
+
client = _http_utils.oauth2.BackendApplicationClient(client_id=self._client_id)
|
|
863
842
|
oauth = requests_oauthlib.OAuth2Session(client=client)
|
|
864
843
|
response = oauth.fetch_token(**self._fetch_options)
|
|
865
844
|
|
|
@@ -911,20 +890,12 @@ class DCOSAuthTokenReader(object):
|
|
|
911
890
|
def read(self, **request):
|
|
912
891
|
if self._token is None or 'error' in request:
|
|
913
892
|
with open(self._private_key_path, 'rb') as f:
|
|
914
|
-
|
|
915
|
-
if serialization is None:
|
|
916
|
-
from cryptography.hazmat.primitives import serialization
|
|
917
|
-
|
|
918
|
-
global jwt
|
|
919
|
-
if jwt is None:
|
|
920
|
-
import jwt
|
|
921
|
-
|
|
922
|
-
private_key = serialization.load_pem_private_key(f.read(), password=None)
|
|
893
|
+
private_key = _http_utils.cryptography_serialization.load_pem_private_key(f.read(), password=None)
|
|
923
894
|
|
|
924
895
|
serialized_private = private_key.private_bytes(
|
|
925
|
-
encoding=
|
|
926
|
-
format=
|
|
927
|
-
encryption_algorithm=
|
|
896
|
+
encoding=_http_utils.cryptography_serialization.Encoding.PEM,
|
|
897
|
+
format=_http_utils.cryptography_serialization.PrivateFormat.PKCS8,
|
|
898
|
+
encryption_algorithm=_http_utils.cryptography_serialization.NoEncryption(),
|
|
928
899
|
)
|
|
929
900
|
|
|
930
901
|
exp = int(get_timestamp() + self._expiration)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# (C) Datadog, Inc. 2016-present
|
|
2
2
|
# All rights reserved
|
|
3
3
|
# Licensed under Simplified BSD License (see LICENSE)
|
|
4
|
+
import lazy_loader
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
__getattr__, __dir__, __all__ = lazy_loader.attach_stub(__name__, __file__)
|
|
@@ -5,9 +5,10 @@ import os
|
|
|
5
5
|
import subprocess
|
|
6
6
|
import sys
|
|
7
7
|
|
|
8
|
+
from datadog_checks.base.utils.format import json
|
|
9
|
+
|
|
8
10
|
from ..common import ensure_bytes, to_native_string
|
|
9
11
|
from ..platform import Platform
|
|
10
|
-
from ..serialization import json
|
|
11
12
|
from .constants import KNOWN_DATADOG_AGENT_SETTER_METHODS, EnvVars
|
|
12
13
|
|
|
13
14
|
|
|
@@ -24,8 +25,8 @@ def run_with_isolation(check, aggregator, datadog_agent):
|
|
|
24
25
|
env_vars[EnvVars.MESSAGE_INDICATOR] = message_indicator
|
|
25
26
|
env_vars[EnvVars.CHECK_NAME] = check.name
|
|
26
27
|
env_vars[EnvVars.CHECK_ID] = check.check_id
|
|
27
|
-
env_vars[EnvVars.INIT_CONFIG] = to_native_string(json.
|
|
28
|
-
env_vars[EnvVars.INSTANCE] = to_native_string(json.
|
|
28
|
+
env_vars[EnvVars.INIT_CONFIG] = to_native_string(json.encode(init_config))
|
|
29
|
+
env_vars[EnvVars.INSTANCE] = to_native_string(json.encode(instance))
|
|
29
30
|
|
|
30
31
|
if Platform.is_windows():
|
|
31
32
|
env_vars[EnvVars.DDTRACE] = "false"
|
|
@@ -60,7 +61,7 @@ def run_with_isolation(check, aggregator, datadog_agent):
|
|
|
60
61
|
check.log.trace(line)
|
|
61
62
|
|
|
62
63
|
message_type, _, message = procedure.partition(':')
|
|
63
|
-
message = json.
|
|
64
|
+
message = json.decode(message)
|
|
64
65
|
if message_type == 'aggregator':
|
|
65
66
|
getattr(aggregator, message['method'])(check, *message['args'], **message['kwargs'])
|
|
66
67
|
elif message_type == 'log':
|
|
@@ -69,7 +70,7 @@ def run_with_isolation(check, aggregator, datadog_agent):
|
|
|
69
70
|
method = message['method']
|
|
70
71
|
value = getattr(datadog_agent, method)(*message['args'], **message['kwargs'])
|
|
71
72
|
if method not in KNOWN_DATADOG_AGENT_SETTER_METHODS:
|
|
72
|
-
process.stdin.write(b'%s\n' % ensure_bytes(json.
|
|
73
|
+
process.stdin.write(b'%s\n' % ensure_bytes(json.encode({'value': value})))
|
|
73
74
|
process.stdin.flush()
|
|
74
75
|
elif message_type == 'error':
|
|
75
76
|
check.log.error(message[0]['traceback'])
|
|
@@ -5,12 +5,13 @@ import logging
|
|
|
5
5
|
import os
|
|
6
6
|
import sys
|
|
7
7
|
|
|
8
|
+
from datadog_checks.base.utils.format import json
|
|
9
|
+
|
|
8
10
|
from ...checks import base
|
|
9
11
|
from ...log import LOG_LEVEL_MAP, TRACE_LEVEL, _get_py_loglevel
|
|
10
12
|
from ...utils.common import to_native_string
|
|
11
13
|
from ...utils.metadata import core
|
|
12
14
|
from ...utils.replay.constants import KNOWN_DATADOG_AGENT_SETTER_METHODS, EnvVars
|
|
13
|
-
from ...utils.serialization import json
|
|
14
15
|
|
|
15
16
|
MESSAGE_INDICATOR = os.environ[EnvVars.MESSAGE_INDICATOR]
|
|
16
17
|
LOG_METHODS = {log_level: log_method.lower() for log_method, log_level in LOG_LEVEL_MAP.items()}
|
|
@@ -30,7 +31,7 @@ class ReplayAggregator(object):
|
|
|
30
31
|
print(
|
|
31
32
|
'{}:aggregator:{}'.format(
|
|
32
33
|
MESSAGE_INDICATOR,
|
|
33
|
-
to_native_string(json.
|
|
34
|
+
to_native_string(json.encode({'method': method_name, 'args': list(args)[1:], 'kwargs': kwargs})),
|
|
34
35
|
)
|
|
35
36
|
)
|
|
36
37
|
|
|
@@ -49,11 +50,11 @@ class ReplayDatadogAgent(object):
|
|
|
49
50
|
print(
|
|
50
51
|
'{}:datadog_agent:{}'.format(
|
|
51
52
|
MESSAGE_INDICATOR,
|
|
52
|
-
to_native_string(json.
|
|
53
|
+
to_native_string(json.encode({'method': method_name, 'args': list(args), 'kwargs': kwargs})),
|
|
53
54
|
)
|
|
54
55
|
)
|
|
55
56
|
if read:
|
|
56
|
-
return json.
|
|
57
|
+
return json.decode(sys.stdin.readline())['value']
|
|
57
58
|
|
|
58
59
|
return method
|
|
59
60
|
|
|
@@ -63,7 +64,7 @@ class ReplayLogger(logging.Logger):
|
|
|
63
64
|
print(
|
|
64
65
|
'{}:log:{}'.format(
|
|
65
66
|
MESSAGE_INDICATOR,
|
|
66
|
-
to_native_string(json.
|
|
67
|
+
to_native_string(json.encode({'method': LOG_METHODS[level], 'args': [str(a) for a in args]})),
|
|
67
68
|
)
|
|
68
69
|
)
|
|
69
70
|
|
|
@@ -80,8 +81,8 @@ logging.getLogger().setLevel(_get_py_loglevel(base.datadog_agent.get_config('log
|
|
|
80
81
|
def run_check(check_class):
|
|
81
82
|
check = check_class(
|
|
82
83
|
os.environ[EnvVars.CHECK_NAME],
|
|
83
|
-
json.
|
|
84
|
-
[json.
|
|
84
|
+
json.decode(os.environ[EnvVars.INIT_CONFIG]),
|
|
85
|
+
[json.decode(os.environ[EnvVars.INSTANCE])],
|
|
85
86
|
)
|
|
86
87
|
check.check_id = os.environ[EnvVars.CHECK_ID]
|
|
87
88
|
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module is deprecated and will begin emitting deprecation warnings after all official
|
|
3
|
+
integrations have migrated to the new `datadog_checks.base.utils.format.json` module.
|
|
4
|
+
"""
|
|
5
|
+
|
|
1
6
|
# (C) Datadog, Inc. 2020-present
|
|
2
7
|
# All rights reserved
|
|
3
8
|
# Licensed under a 3-clause BSD style license (see LICENSE)
|
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
# (C) Datadog, Inc. 2018-present
|
|
2
2
|
# All rights reserved
|
|
3
3
|
# Licensed under Simplified BSD License (see LICENSE)
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
4
6
|
import functools
|
|
5
|
-
import inspect
|
|
6
7
|
import os
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
import lazy_loader
|
|
7
11
|
|
|
8
12
|
from datadog_checks.base.agent import datadog_agent
|
|
9
13
|
|
|
10
14
|
from ..config import is_affirmative
|
|
11
15
|
from ..utils.common import to_native_string
|
|
12
16
|
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
import inspect as _module_inspect
|
|
19
|
+
|
|
20
|
+
inspect: _module_inspect = lazy_loader.load('inspect')
|
|
21
|
+
|
|
13
22
|
EXCLUDED_MODULES = ['threading']
|
|
14
23
|
|
|
15
24
|
# During regular continuous tracing we trace only the check's top-level 'run' and
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datadog-checks-base
|
|
3
|
-
Version: 37.
|
|
3
|
+
Version: 37.8.0
|
|
4
4
|
Summary: The Datadog Check Toolkit
|
|
5
5
|
Project-URL: Source, https://github.com/DataDog/integrations-core
|
|
6
6
|
Author-email: Datadog <packages@datadoghq.com>
|
|
@@ -16,10 +16,11 @@ Provides-Extra: db
|
|
|
16
16
|
Requires-Dist: mmh3==5.1.0; extra == 'db'
|
|
17
17
|
Provides-Extra: deps
|
|
18
18
|
Requires-Dist: binary==1.0.1; extra == 'deps'
|
|
19
|
-
Requires-Dist: cachetools==5.5.
|
|
20
|
-
Requires-Dist: cryptography==
|
|
19
|
+
Requires-Dist: cachetools==5.5.2; extra == 'deps'
|
|
20
|
+
Requires-Dist: cryptography==44.0.1; extra == 'deps'
|
|
21
21
|
Requires-Dist: ddtrace==2.10.6; extra == 'deps'
|
|
22
22
|
Requires-Dist: jellyfish==1.1.3; extra == 'deps'
|
|
23
|
+
Requires-Dist: lazy-loader==0.4; extra == 'deps'
|
|
23
24
|
Requires-Dist: prometheus-client==0.21.1; extra == 'deps'
|
|
24
25
|
Requires-Dist: protobuf==5.29.3; extra == 'deps'
|
|
25
26
|
Requires-Dist: pydantic==2.10.6; extra == 'deps'
|
|
@@ -29,15 +30,14 @@ Requires-Dist: pyyaml==6.0.2; extra == 'deps'
|
|
|
29
30
|
Requires-Dist: requests-toolbelt==1.0.0; extra == 'deps'
|
|
30
31
|
Requires-Dist: requests-unixsocket2==0.4.2; extra == 'deps'
|
|
31
32
|
Requires-Dist: requests==2.32.3; extra == 'deps'
|
|
32
|
-
Requires-Dist: simplejson==3.
|
|
33
|
-
Requires-Dist: uptime==3.0.1; extra == 'deps'
|
|
33
|
+
Requires-Dist: simplejson==3.20.1; extra == 'deps'
|
|
34
34
|
Requires-Dist: wrapt==1.17.2; extra == 'deps'
|
|
35
35
|
Provides-Extra: http
|
|
36
36
|
Requires-Dist: aws-requests-auth==0.4.3; extra == 'http'
|
|
37
|
-
Requires-Dist: botocore==1.36.
|
|
37
|
+
Requires-Dist: botocore==1.36.26; extra == 'http'
|
|
38
38
|
Requires-Dist: oauthlib==3.2.2; extra == 'http'
|
|
39
39
|
Requires-Dist: pyjwt==2.10.1; extra == 'http'
|
|
40
|
-
Requires-Dist: pyopenssl==24.
|
|
40
|
+
Requires-Dist: pyopenssl==24.3.0; extra == 'http'
|
|
41
41
|
Requires-Dist: pysocks==1.7.1; extra == 'http'
|
|
42
42
|
Requires-Dist: requests-kerberos==0.15.0; extra == 'http'
|
|
43
43
|
Requires-Dist: requests-ntlm==1.3.0; extra == 'http'
|
|
@@ -45,7 +45,7 @@ Requires-Dist: requests-oauthlib==2.0.0; extra == 'http'
|
|
|
45
45
|
Provides-Extra: json
|
|
46
46
|
Requires-Dist: orjson==3.10.15; extra == 'json'
|
|
47
47
|
Provides-Extra: kube
|
|
48
|
-
Requires-Dist: kubernetes==32.0.
|
|
48
|
+
Requires-Dist: kubernetes==32.0.1; extra == 'kube'
|
|
49
49
|
Requires-Dist: requests-oauthlib==2.0.0; extra == 'kube'
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
|
|
@@ -80,6 +80,15 @@ install the toolkit locally and play with it:
|
|
|
80
80
|
pip install datadog-checks-base
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
+
## Performance Optimizations
|
|
84
|
+
|
|
85
|
+
We strive to balance lean resource usage with a "batteries included" user experience.
|
|
86
|
+
We employ a few tricks to achieve this.
|
|
87
|
+
|
|
88
|
+
One of them is the [lazy-loader][9] library that allows us to expose a nice API (simple, short imports) without the baseline memory overhead of importing everything all the time.
|
|
89
|
+
|
|
90
|
+
Another trick is to import some of our dependencies inside functions that use them instead of the more conventional import section at the top of the file. We rely on this the most in the `AgentCheck` base class.
|
|
91
|
+
|
|
83
92
|
## Troubleshooting
|
|
84
93
|
|
|
85
94
|
Need help? Contact [Datadog support][8].
|
|
@@ -91,3 +100,4 @@ Need help? Contact [Datadog support][8].
|
|
|
91
100
|
[6]: https://github.com/DataDog/integrations-core
|
|
92
101
|
[7]: https://pypi.org/project/datadog-checks-base/
|
|
93
102
|
[8]: https://docs.datadoghq.com/help/
|
|
103
|
+
[9]: https://github.com/scientific-python/lazy-loader
|