datadog-checks-base 37.18.1__py2.py3-none-any.whl → 37.20.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.
@@ -1,4 +1,4 @@
1
1
  # (C) Datadog, Inc. 2018-present
2
2
  # All rights reserved
3
3
  # Licensed under a 3-clause BSD style license (see LICENSE)
4
- __version__ = "37.18.1"
4
+ __version__ = "37.20.0"
@@ -11,19 +11,10 @@ import os
11
11
  import re
12
12
  from collections import deque
13
13
  from os.path import basename
14
- from typing import ( # noqa: F401
14
+ from typing import (
15
15
  TYPE_CHECKING,
16
16
  Any,
17
- AnyStr,
18
- Callable,
19
- Deque,
20
- Dict,
21
- List,
22
- Optional,
23
- Sequence,
24
- Set,
25
- Tuple,
26
- Union,
17
+ Deque, # noqa: F401
27
18
  )
28
19
 
29
20
  import lazy_loader
@@ -294,10 +285,16 @@ class AgentCheck(object):
294
285
  # Functions that will be called exactly once (if successful) before the first check run
295
286
  self.check_initializations = deque() # type: Deque[Callable[[], None]]
296
287
 
297
- self.check_initializations.append(self.load_configuration_models)
288
+ self.check_initializations.extend(
289
+ [
290
+ self.load_configuration_models,
291
+ self.__initialize_persistent_cache_key_prefix,
292
+ ]
293
+ )
298
294
 
299
295
  self.__formatted_tags = None
300
296
  self.__logs_enabled = None
297
+ self.__persistent_cache_key_prefix: str = ""
301
298
 
302
299
  if os.environ.get("GOFIPS", "0") == "1":
303
300
  enable_fips()
@@ -491,6 +488,18 @@ class AgentCheck(object):
491
488
  self._log_deprecation('in_developer_mode')
492
489
  return False
493
490
 
491
+ def persistent_cache_id(self) -> str:
492
+ """
493
+ Returns the ID that identifies this check instance in the Agent persistent cache.
494
+
495
+ Overriding this method modifies the default behavior of the AgentCheck and can
496
+ be used to customize when the persistent cache is invalidated. The default behavior
497
+ defines the persistent cache ID as the digest of the full check configuration.
498
+
499
+ Some per-check isolation is still applied to avoid different checks with the same ID to share the same keys.
500
+ """
501
+ return self.check_id.split(":")[-1]
502
+
494
503
  def log_typos_in_options(self, user_config, models_config, level):
495
504
  # See Performance Optimizations in this package's README.md.
496
505
  from jellyfish import jaro_winkler_similarity
@@ -1009,13 +1018,15 @@ class AgentCheck(object):
1009
1018
  attributes['timestamp'] = int(timestamp * 1000)
1010
1019
 
1011
1020
  datadog_agent.send_log(json.encode(attributes), self.check_id)
1021
+
1012
1022
  if cursor is not None:
1013
- self.write_persistent_cache('log_cursor_{}'.format(stream), json.encode(cursor))
1023
+ self.write_persistent_cache(f'log_cursor_{stream}', json.encode(cursor))
1014
1024
 
1015
1025
  def get_log_cursor(self, stream='default'):
1016
1026
  # type: (str) -> dict[str, Any] | None
1017
1027
  """Returns the most recent log cursor from disk."""
1018
- data = self.read_persistent_cache('log_cursor_{}'.format(stream))
1028
+ data = self.read_persistent_cache(f'log_cursor_{stream}')
1029
+
1019
1030
  return json.decode(data) if data else None
1020
1031
 
1021
1032
  def _log_deprecation(self, deprecation_key, *args):
@@ -1082,9 +1093,9 @@ class AgentCheck(object):
1082
1093
 
1083
1094
  return entrypoint
1084
1095
 
1085
- def _persistent_cache_id(self, key):
1086
- # type: (str) -> str
1087
- return '{}_{}'.format(self.check_id, key)
1096
+ def __initialize_persistent_cache_key_prefix(self):
1097
+ namespace = ':'.join(self.check_id.split(':')[:-1])
1098
+ self.__persistent_cache_key_prefix = f'{namespace}:{self.persistent_cache_id()}_'
1088
1099
 
1089
1100
  def read_persistent_cache(self, key):
1090
1101
  # type: (str) -> str
@@ -1094,9 +1105,9 @@ class AgentCheck(object):
1094
1105
  key (str):
1095
1106
  the key to retrieve
1096
1107
  """
1097
- return datadog_agent.read_persistent_cache(self._persistent_cache_id(key))
1108
+ return datadog_agent.read_persistent_cache(f"{self.__persistent_cache_key_prefix}{key}")
1098
1109
 
1099
- def write_persistent_cache(self, key, value):
1110
+ def write_persistent_cache(self, key: str, value: str):
1100
1111
  # type: (str, str) -> None
1101
1112
  """Stores `value` in a persistent cache for this check instance.
1102
1113
  The cache is located in a path where the agent is guaranteed to have read & write permissions. Namely in
@@ -1110,7 +1121,7 @@ class AgentCheck(object):
1110
1121
  value (str):
1111
1122
  the value to store
1112
1123
  """
1113
- datadog_agent.write_persistent_cache(self._persistent_cache_id(key), value)
1124
+ datadog_agent.write_persistent_cache(f"{self.__persistent_cache_key_prefix}{key}", value)
1114
1125
 
1115
1126
  def set_external_tags(self, external_tags):
1116
1127
  # type: (Sequence[ExternalTagType]) -> None
@@ -1282,13 +1293,7 @@ class AgentCheck(object):
1282
1293
 
1283
1294
  run_with_isolation(self, aggregator, datadog_agent)
1284
1295
  else:
1285
- while self.check_initializations:
1286
- initialization = self.check_initializations.popleft()
1287
- try:
1288
- initialization()
1289
- except Exception:
1290
- self.check_initializations.appendleft(initialization)
1291
- raise
1296
+ self.run_check_initializations()
1292
1297
 
1293
1298
  instance = copy.deepcopy(self.instances[0])
1294
1299
 
@@ -1328,6 +1333,15 @@ class AgentCheck(object):
1328
1333
 
1329
1334
  return error_report
1330
1335
 
1336
+ def run_check_initializations(self):
1337
+ while self.check_initializations:
1338
+ initialization = self.check_initializations.popleft()
1339
+ try:
1340
+ initialization()
1341
+ except Exception:
1342
+ self.check_initializations.appendleft(initialization)
1343
+ raise
1344
+
1331
1345
  def event(self, event):
1332
1346
  # type: (Event) -> None
1333
1347
  """Send an event.
@@ -0,0 +1,82 @@
1
+ # (C) Datadog, Inc. 2025-present
2
+ # All rights reserved
3
+ # Licensed under a 3-clause BSD style license (see LICENSE)
4
+ # This is the base implementation of the Agent Health reporting system.
5
+ # It provides a structure for health events and codes that can be extended by specific checks.
6
+
7
+ from __future__ import annotations
8
+
9
+ import time
10
+ from typing import TYPE_CHECKING
11
+
12
+ from datadog_checks.base.utils.serialization import json
13
+
14
+ if TYPE_CHECKING:
15
+ from datadog_checks.base import AgentCheck
16
+
17
+ try:
18
+ import datadog_agent
19
+ except ImportError:
20
+ from datadog_checks.base.stubs import datadog_agent
21
+
22
+
23
+ from enum import Enum
24
+
25
+
26
+ class HealthEvent(Enum):
27
+ """
28
+ Enum representing the health events.
29
+ """
30
+
31
+ INITIALIZATION = 'initialization'
32
+
33
+
34
+ class HealthStatus(Enum):
35
+ """
36
+ Enum representing the health statuses for a given event.
37
+ """
38
+
39
+ OK = 'ok'
40
+ WARNING = 'warning'
41
+ ERROR = 'error'
42
+
43
+
44
+ class Health:
45
+ def __init__(self, check: AgentCheck):
46
+ """
47
+ Initialize the HealthCheck instance.
48
+
49
+ :param check: AgentCheck
50
+ The check instance that will be used to submit health events.
51
+ """
52
+ self.check = check
53
+
54
+ def submit_health_event(self, name: HealthEvent, status: HealthStatus, tags: list[str] = None, **kwargs):
55
+ """
56
+ Submit a health event to the aggregator.
57
+
58
+ :param name: HealthEvent
59
+ The name of the health event.
60
+ :param status: HealthStatus
61
+ The health status to submit.
62
+ :param tags: list of str
63
+ Tags to associate with the health event.
64
+ :param kwargs: Additional keyword arguments to include in the event under `data`.
65
+ """
66
+ self.check.event_platform_event(
67
+ json.dumps(
68
+ {
69
+ 'timestamp': time.time() * 1000,
70
+ 'version': 1,
71
+ 'check_id': self.check.check_id,
72
+ 'category': self.check.__NAMESPACE__ or self.check.__class__.__name__.lower(),
73
+ 'name': name,
74
+ 'status': status,
75
+ 'tags': tags or [],
76
+ 'ddagentversion': datadog_agent.get_version(),
77
+ 'ddagenthostname': datadog_agent.get_hostname(),
78
+ 'data': {**kwargs},
79
+ }
80
+ ),
81
+ "dbm-health",
82
+ )
@@ -0,0 +1,33 @@
1
+ from collections.abc import Collection
2
+
3
+ from datadog_checks.base import AgentCheck
4
+ from datadog_checks.base.utils.containers import hash_mutable
5
+
6
+
7
+ def config_set_persistent_cache_id(
8
+ check: AgentCheck,
9
+ init_config_options: Collection[str] | None = None,
10
+ instance_config_options: Collection[str] | None = None,
11
+ ):
12
+ """
13
+ Returns an ID for the persisitent cache derives from a subset of the check's config options.
14
+
15
+ If the value of any of the provided options changes, the generate cache ID will change.
16
+
17
+ Parameters:
18
+ check: the check instance the key is going to be used for.
19
+ init_config_options: the subset of init_config options to use to generate the cache ID.
20
+ instance_config_options: the subset of config options to use to generate the cache ID.
21
+ """
22
+
23
+ if not init_config_options and not instance_config_options:
24
+ raise ValueError("At least one of init_config_options or instance_config_options must be provided")
25
+
26
+ set_init_config_options = set(init_config_options) if init_config_options else set()
27
+ set_instance_config_options = set(instance_config_options) if instance_config_options else set()
28
+
29
+ init_config_values = tuple(value for key, value in check.init_config.items() if key in set_init_config_options)
30
+ instance_config_values = tuple(value for key, value in check.instance.items() if key in set_instance_config_options)
31
+
32
+ selected_values = init_config_values + instance_config_values
33
+ return str(hash_mutable(selected_values)).replace("-", "")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datadog-checks-base
3
- Version: 37.18.1
3
+ Version: 37.20.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>
@@ -13,29 +13,29 @@ Classifier: License :: OSI Approved :: BSD License
13
13
  Classifier: Programming Language :: Python :: 3.12
14
14
  Classifier: Topic :: System :: Monitoring
15
15
  Provides-Extra: db
16
- Requires-Dist: mmh3==5.1.0; extra == 'db'
16
+ Requires-Dist: mmh3==5.2.0; extra == 'db'
17
17
  Provides-Extra: deps
18
18
  Requires-Dist: binary==1.0.2; extra == 'deps'
19
- Requires-Dist: cachetools==6.1.0; extra == 'deps'
20
- Requires-Dist: cryptography==45.0.4; extra == 'deps'
21
- Requires-Dist: ddtrace==3.9.3; extra == 'deps'
19
+ Requires-Dist: cachetools==6.2.0; extra == 'deps'
20
+ Requires-Dist: cryptography==45.0.6; extra == 'deps'
21
+ Requires-Dist: ddtrace==3.12.5; extra == 'deps'
22
22
  Requires-Dist: jellyfish==1.2.0; extra == 'deps'
23
23
  Requires-Dist: lazy-loader==0.4; extra == 'deps'
24
24
  Requires-Dist: prometheus-client==0.22.1; extra == 'deps'
25
- Requires-Dist: protobuf==6.31.1; extra == 'deps'
25
+ Requires-Dist: protobuf==6.32.0; extra == 'deps'
26
26
  Requires-Dist: pydantic==2.11.7; extra == 'deps'
27
27
  Requires-Dist: python-dateutil==2.9.0.post0; extra == 'deps'
28
- Requires-Dist: pywin32==310; (sys_platform == 'win32') and extra == 'deps'
28
+ Requires-Dist: pywin32==311; (sys_platform == 'win32') and extra == 'deps'
29
29
  Requires-Dist: pyyaml==6.0.2; extra == 'deps'
30
30
  Requires-Dist: requests-toolbelt==1.0.0; extra == 'deps'
31
31
  Requires-Dist: requests-unixsocket2==1.0.0; extra == 'deps'
32
- Requires-Dist: requests==2.32.4; extra == 'deps'
32
+ Requires-Dist: requests==2.32.5; extra == 'deps'
33
33
  Requires-Dist: simplejson==3.20.1; extra == 'deps'
34
34
  Requires-Dist: urllib3==2.5.0; extra == 'deps'
35
- Requires-Dist: wrapt==1.17.2; extra == 'deps'
35
+ Requires-Dist: wrapt==1.17.3; extra == 'deps'
36
36
  Provides-Extra: http
37
37
  Requires-Dist: aws-requests-auth==0.4.3; extra == 'http'
38
- Requires-Dist: botocore==1.38.41; extra == 'http'
38
+ Requires-Dist: botocore==1.40.21; extra == 'http'
39
39
  Requires-Dist: oauthlib==3.3.1; extra == 'http'
40
40
  Requires-Dist: pyjwt==2.10.1; extra == 'http'
41
41
  Requires-Dist: pyopenssl==25.1.0; extra == 'http'
@@ -44,7 +44,7 @@ Requires-Dist: requests-kerberos==0.15.0; extra == 'http'
44
44
  Requires-Dist: requests-ntlm==1.3.0; extra == 'http'
45
45
  Requires-Dist: requests-oauthlib==2.0.0; extra == 'http'
46
46
  Provides-Extra: json
47
- Requires-Dist: orjson==3.11.1; extra == 'json'
47
+ Requires-Dist: orjson==3.11.3; extra == 'json'
48
48
  Provides-Extra: kube
49
49
  Requires-Dist: kubernetes==33.1.0; extra == 'kube'
50
50
  Requires-Dist: requests-oauthlib==2.0.0; extra == 'kube'
@@ -3,7 +3,7 @@ datadog_checks/config.py,sha256=PrAXGdlLnoV2VMQff_noSaSJJ0wg4BAiGnw7jCQLSik,196
3
3
  datadog_checks/errors.py,sha256=eFwmnrX-batIgbu-iJyseqAPNO_4rk1UuaKK89evLhg,155
4
4
  datadog_checks/log.py,sha256=orvOgMKGNEsqSTLalCAQpWP-ouorpG1A7Gn-j2mRD80,301
5
5
  datadog_checks/py.typed,sha256=la67KBlbjXN-_-DfGNcdOcjYumVpKG_Tkw-8n5dnGB4,8
6
- datadog_checks/base/__about__.py,sha256=4qSLAXxeYfOKih3MKLLjw5ykR-Ucmj6wEToUwV4N5Lc,139
6
+ datadog_checks/base/__about__.py,sha256=hXkLHsKgHttGQ7R5jeQ0cESbDNRVE8U1W-La8t1CUAw,139
7
7
  datadog_checks/base/__init__.py,sha256=yWegSLE-TZWIGSvAiJj9PSrUxzlOo_UVJLt2zORZ8Ek,363
8
8
  datadog_checks/base/__init__.pyi,sha256=eH8XhrtvnD6uE6FWfEyCmKwOaaLJxNolS08D6IRHZuU,995
9
9
  datadog_checks/base/agent.py,sha256=nX9x_BYYizRKGNYfXq5z7S0FZ9xcX_wd2tuxpGe3_8k,350
@@ -15,7 +15,7 @@ datadog_checks/base/types.py,sha256=anajZS0W0TsxUHJQw-JHOP2NSeuC9BisXSy9mAStlxQ,
15
15
  datadog_checks/base/checks/__init__.py,sha256=q7V6v-FwQWkQC1QWaVzKaPjZMaxPJHJcLd71C0uM7bA,211
16
16
  datadog_checks/base/checks/__init__.pyi,sha256=LASfm-daLNQIYe6-w0NPqBw4cl83nYIX5_B-VhV6ARo,262
17
17
  datadog_checks/base/checks/_config_ast.py,sha256=v1rAhwORF80b3kfZKhf6zXZ7S5D3A2QPUK4tSo8eo-Y,3268
18
- datadog_checks/base/checks/base.py,sha256=kcnZ8ySfleMGw5y6iLEvhLaF42WGCMes0LfylLo_v50,59857
18
+ datadog_checks/base/checks/base.py,sha256=xP56kjtCvW-CMWrdVN3ZC1yAhQr4jad9ORPDuOdz-eM,60654
19
19
  datadog_checks/base/checks/network.py,sha256=UkgqkVHaoX7Hqi0WKEx-TvaFiF6-37VyF9A3m2aSaJM,1966
20
20
  datadog_checks/base/checks/kube_leader/__init__.py,sha256=q7V6v-FwQWkQC1QWaVzKaPjZMaxPJHJcLd71C0uM7bA,211
21
21
  datadog_checks/base/checks/kube_leader/__init__.pyi,sha256=UGDywoRwmCIz3Zii1uHsp7jiFGWRdn5fFMZZxgGGlQs,398
@@ -116,6 +116,7 @@ datadog_checks/base/utils/functions.py,sha256=iGlybxR6aPPElNxNb2ELOzbk328j9OVBAx
116
116
  datadog_checks/base/utils/headers.py,sha256=0SSdC71jwaB61BODfusahCVr1c56GvT9iwt7cidcHP0,1779
117
117
  datadog_checks/base/utils/http.py,sha256=ePSzL7x_xsb1dnXJyU2fBXIgOU0p5UFZIpG2AX_jZZA,44651
118
118
  datadog_checks/base/utils/limiter.py,sha256=YRTrPCX1S5EtHLVcP_-GEfzRots_LTcy1f_uHZVs90g,3027
119
+ datadog_checks/base/utils/persistent_cache.py,sha256=i5I9BKIb5V2BFEs0sVTf8bBQUIH21G2nL_tRQHC9GMk,1538
119
120
  datadog_checks/base/utils/platform.py,sha256=wW8f6XKo4JHxvu1sN0DpLDmYjS_cCu8GoKvfTjIj4yM,2499
120
121
  datadog_checks/base/utils/secrets.py,sha256=Tj5MBOoyGXXDWB3Hr-7UKDy5GV1NZJkFPY4T4v9PHHg,551
121
122
  datadog_checks/base/utils/serialization.py,sha256=pcRUzZIUZkOsfnGDGbxeUwGXrSsFl_9rLhA0ekD_AZ8,975
@@ -138,6 +139,7 @@ datadog_checks/base/utils/concurrency/limiter.py,sha256=is2ZpUEjfsI4nBGtXG2D0Zgv
138
139
  datadog_checks/base/utils/db/__init__.py,sha256=EVTc2FtnHWLHXI3M79jyMn9ypZAMa9eqG3EKLAiMF-M,211
139
140
  datadog_checks/base/utils/db/__init__.pyi,sha256=ewmGxxyJ52wAaYxNZahi2koEUnddfvHcn3HYxQ3RUr0,240
140
141
  datadog_checks/base/utils/db/core.py,sha256=bYanwXIqBzsSxK7b-Ofb0W1WiHbFBtKyYdUBonBLe_Q,11165
142
+ datadog_checks/base/utils/db/health.py,sha256=OWdhGSUhEr8Rxr6anVxD__52wkG8kDaY7M015Y4fCkA,2361
141
143
  datadog_checks/base/utils/db/query.py,sha256=-PyxdqpbShkQ78h7sWnghQZVtjdLGVrm71n8OpHuPW4,14432
142
144
  datadog_checks/base/utils/db/sql.py,sha256=oiEzQa_vC_w3U65VFrFCoQHWj5GQLLRlSO0CfiSlp4A,2490
143
145
  datadog_checks/base/utils/db/sql_commenter.py,sha256=r_efK6TGRQxM_-Qj-ndEJdECk47J4nCFjkVyxu1XmvU,1522
@@ -219,6 +221,6 @@ datadog_checks/utils/tracing.py,sha256=HQbQakKM-Lw75MDkItaYJYipS6YO24Z_ymDVxDsx5
219
221
  datadog_checks/utils/prometheus/__init__.py,sha256=8WwXnM9g1sfS5267QYCJX_hd8MZl5kRgBgQ_SzdNdXs,161
220
222
  datadog_checks/utils/prometheus/functions.py,sha256=4vWsTGLgujHwdYZo0tlAQkqDPHofqUJM3k9eItJqERQ,197
221
223
  datadog_checks/utils/prometheus/metrics_pb2.py,sha256=xg3UdUHe4TjeR4s13LUKZ2U1WVSt6U6zjsVRG6lX6dc,173
222
- datadog_checks_base-37.18.1.dist-info/METADATA,sha256=c0CirmMk4cxkDnX8P1TPhQMMjyfjAMHQJ7hLf9hRQTo,4244
223
- datadog_checks_base-37.18.1.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
224
- datadog_checks_base-37.18.1.dist-info/RECORD,,
224
+ datadog_checks_base-37.20.0.dist-info/METADATA,sha256=Btd945pDmErXUpZ1MdzT1T8BWpedTQU4xKyl9XsHOA8,4245
225
+ datadog_checks_base-37.20.0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
226
+ datadog_checks_base-37.20.0.dist-info/RECORD,,