datadog-checks-base 37.23.2__py2.py3-none-any.whl → 37.24.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.23.2"
4
+ __version__ = "37.24.0"
@@ -1487,14 +1487,20 @@ class AgentCheck(object):
1487
1487
  import subprocess
1488
1488
  import sys
1489
1489
 
1490
+ # Force UTF-8 encoding for subprocess
1491
+ env = os.environ.copy()
1492
+ env['PYTHONIOENCODING'] = 'utf-8'
1493
+
1490
1494
  process = subprocess.Popen(
1491
1495
  [sys.executable, '-c', 'import sys, yaml; print(yaml.safe_load(sys.stdin.read()))'],
1492
1496
  stdin=subprocess.PIPE,
1493
1497
  stdout=subprocess.PIPE,
1494
1498
  stderr=subprocess.PIPE,
1499
+ env=env,
1495
1500
  )
1496
- stdout, stderr = process.communicate(yaml_str.encode())
1501
+ # Explicitly encode as UTF-8 to match PYTHONIOENCODING
1502
+ stdout, stderr = process.communicate(yaml_str.encode('utf-8'))
1497
1503
  if process.returncode != 0:
1498
- raise ValueError(f'Failed to load config: {stderr.decode()}')
1504
+ raise ValueError(f'Failed to load config: {stderr.decode("utf-8", errors="replace")}')
1499
1505
 
1500
- return _parse_ast_config(stdout.strip().decode())
1506
+ return _parse_ast_config(stdout.strip().decode('utf-8'))
@@ -2,6 +2,8 @@
2
2
  # All rights reserved
3
3
  # Licensed under a 3-clause BSD style license (see LICENSE)
4
4
 
5
+ from abc import abstractmethod
6
+
5
7
  from . import AgentCheck
6
8
 
7
9
 
@@ -20,3 +22,32 @@ class DatabaseCheck(AgentCheck):
20
22
 
21
23
  def database_monitoring_health(self, raw_event: str):
22
24
  self.event_platform_event(raw_event, "dbm-health")
25
+
26
+ @property
27
+ @abstractmethod
28
+ def reported_hostname(self) -> str | None:
29
+ pass
30
+
31
+ @property
32
+ @abstractmethod
33
+ def database_identifier(self) -> str:
34
+ pass
35
+
36
+ @property
37
+ def dbms(self) -> str:
38
+ return self.__class__.__name__.lower()
39
+
40
+ @property
41
+ @abstractmethod
42
+ def dbms_version(self) -> str:
43
+ pass
44
+
45
+ @property
46
+ @abstractmethod
47
+ def tags(self) -> list[str]:
48
+ pass
49
+
50
+ @property
51
+ @abstractmethod
52
+ def cloud_metadata(self) -> dict:
53
+ pass
@@ -110,8 +110,8 @@ class WinWMICheck(AgentCheck):
110
110
  )
111
111
  raise TypeError
112
112
 
113
- def _get_tag_query_tag(self, sampler, wmi_obj, tag_query):
114
- # type: (WMISampler, WMIObject, TagQuery) -> str
113
+ def _get_tag_query_tag(self, sampler, wmi_obj, tag_query, alias):
114
+ # type: (WMISampler, WMIObject, TagQuery, str) -> str
115
115
  """
116
116
  Design a query based on the given WMIObject to extract a tag.
117
117
 
@@ -133,13 +133,14 @@ class WinWMICheck(AgentCheck):
133
133
 
134
134
  link_value = str(tag_query_sampler[0][target_property]).lower()
135
135
 
136
- tag = "{tag_name}:{tag_value}".format(tag_name=target_property.lower(), tag_value="_".join(link_value.split()))
136
+ tag_name = alias.lower()
137
+ tag = "{tag_name}:{tag_value}".format(tag_name=tag_name, tag_value="_".join(link_value.split()))
137
138
 
138
139
  self.log.debug("Extracted `tag_queries` tag: '%s'", tag)
139
140
  return tag
140
141
 
141
- def _extract_metrics(self, wmi_sampler, tag_by, tag_queries, constant_tags):
142
- # type: (WMISampler, str, List[List[str]], List[str]) -> List[WMIMetric]
142
+ def _extract_metrics(self, wmi_sampler, tag_by, tag_queries, constant_tags, tag_by_aliases, tag_queries_aliases):
143
+ # type: (WMISampler, str, List[List[str]], List[str], Dict[str, str], List[str]) -> List[WMIMetric]
143
144
  """
144
145
  Extract and tag metrics from the WMISampler.
145
146
 
@@ -170,9 +171,9 @@ class WinWMICheck(AgentCheck):
170
171
  tags = list(constant_tags) if constant_tags else []
171
172
 
172
173
  # Tag with `tag_queries` parameter
173
- for query in tag_queries:
174
+ for index, query in enumerate(tag_queries):
174
175
  try:
175
- tags.append(self._get_tag_query_tag(wmi_sampler, wmi_obj, query))
176
+ tags.append(self._get_tag_query_tag(wmi_sampler, wmi_obj, query, tag_queries_aliases[index]))
176
177
  except TagQueryUniquenessFailure:
177
178
  continue
178
179
 
@@ -193,17 +194,17 @@ class WinWMICheck(AgentCheck):
193
194
  continue
194
195
  # Tag with `tag_by` parameter
195
196
  for t in tag_by.split(','):
196
- t = t.strip()
197
- if wmi_property == t:
197
+ if normalized_wmi_property == t:
198
198
  tag_value = str(wmi_value).lower()
199
199
  if tag_queries and tag_value.find("#") > 0:
200
200
  tag_value = tag_value[: tag_value.find("#")]
201
201
 
202
- tags.append("{name}:{value}".format(name=t, value=tag_value))
202
+ alias = tag_by_aliases.get(t)
203
+ tags.append("{name}:{value}".format(name=alias, value=tag_value))
203
204
  continue
204
205
 
205
206
  # No metric extraction on 'Name' and properties in tag_by
206
- if wmi_property == 'name' or normalized_wmi_property in tag_by.lower():
207
+ if normalized_wmi_property == 'name' or normalized_wmi_property in tag_by.lower():
207
208
  continue
208
209
 
209
210
  try:
@@ -260,6 +261,7 @@ class WinWMICheck(AgentCheck):
260
261
  def get_running_wmi_sampler(self, properties, filters, **kwargs):
261
262
  # type: (List[str], List[Dict[str, WMIFilter]], **Any) -> WMISampler
262
263
  tag_by = kwargs.pop('tag_by', "")
264
+
263
265
  return self._get_running_wmi_sampler(
264
266
  instance_key=None,
265
267
  wmi_class=self.wmi_class,
@@ -303,6 +305,49 @@ class WinWMICheck(AgentCheck):
303
305
 
304
306
  return self._wmi_props
305
307
 
308
+ def parse_tag_queries_aliases(self, tag_queries):
309
+ # type: (List[TagQuery]) -> None
310
+ """
311
+ Validate tag_queries configuration to ensure aliases are provided when 'AS' is used.
312
+ return parsed_tag_queries and aliases
313
+ """
314
+ aliases = [] # type: list[str]
315
+ parsed_tag_queries = [] # type: list[TagQuery]
316
+ for tag_query in tag_queries:
317
+ if len(tag_query) < 4:
318
+ continue
319
+ target_property_str = tag_query[3]
320
+ property, alias = self.parse_alias(target_property_str)
321
+ aliases.append(alias)
322
+ tag_query[3] = property
323
+ parsed_tag_queries.append(tag_query)
324
+ return parsed_tag_queries, aliases
325
+
326
+ def parse_alias(self, property):
327
+ # type: (str) -> Tuple[str, Optional[str]]
328
+ """
329
+ Parse an alias from a string.
330
+ """
331
+ property = property.strip().lower()
332
+ if ' as ' in property:
333
+ # Valid format: property AS alias (with spaces around AS)
334
+ property_split = property.split(' as ')
335
+ property = property_split[0].strip()
336
+ alias = property_split[1].strip()
337
+ self.log.debug("Parsed alias: {%s} for property: {%s}", alias, property)
338
+ if alias == "":
339
+ self.log.warning("No alias provided after 'AS' for property: %s. Using property for tag", property)
340
+ alias = property
341
+ elif ' as' in property:
342
+ # Invalid format: AS found but without proper spacing
343
+ raise InvalidWMIQuery(
344
+ "Invalid alias syntax in property '{}'. "
345
+ "Expected format: 'property AS alias' with spaces around 'AS'".format(property)
346
+ )
347
+ else:
348
+ alias = property
349
+ return property, alias
350
+
306
351
 
307
352
  def from_time(
308
353
  year=None, month=None, day=None, hours=None, minutes=None, seconds=None, microseconds=None, timezone=None
@@ -0,0 +1,189 @@
1
+ # (C) Datadog, Inc. 2025-present
2
+ # All rights reserved
3
+ # Licensed under a 3-clause BSD style license (see LICENSE)
4
+
5
+ from __future__ import annotations
6
+
7
+ from abc import ABC, abstractmethod
8
+ from typing import TYPE_CHECKING, TypedDict
9
+
10
+ from datadog_checks.base.utils.serialization import json
11
+
12
+ from .utils import now_ms
13
+
14
+ if TYPE_CHECKING:
15
+ from datadog_checks.base.checks.db import DatabaseCheck
16
+
17
+ try:
18
+ import datadog_agent # type: ignore
19
+ except ImportError:
20
+ from datadog_checks.base.stubs import datadog_agent
21
+
22
+
23
+ class DatabaseInfo(TypedDict):
24
+ name: str
25
+
26
+
27
+ # The schema collector sends lists of DatabaseObjects to the agent
28
+ # DBMS subclasses may add additional fields to the dictionary
29
+ class DatabaseObject(TypedDict):
30
+ name: str
31
+
32
+
33
+ # Common configuration for schema collector
34
+ # Individual DBMS implementations should map their specific
35
+ # configuration to this type
36
+ class SchemaCollectorConfig:
37
+ def __init__(self):
38
+ self.collection_interval = 3600
39
+ self.payload_chunk_size = 10_000
40
+
41
+
42
+ class SchemaCollector(ABC):
43
+ """
44
+ Abstract base class for DBM schema collectors.
45
+ """
46
+
47
+ def __init__(self, check: DatabaseCheck, config: SchemaCollectorConfig):
48
+ self._check = check
49
+ self._log = check.log
50
+ self._config = config
51
+ self._reset()
52
+
53
+ def _reset(self):
54
+ # Timestamp in whole milliseconds when the current collection started.
55
+ self._collection_started_at = None
56
+ self._collection_payloads_count = 0
57
+ self._queued_rows = []
58
+ self._total_rows_count = 0
59
+
60
+ def collect_schemas(self) -> bool:
61
+ """
62
+ Collects and submits all applicable schema metadata to the agent.
63
+ This class relies on the owning check to handle scheduling this method.
64
+ """
65
+ status = "success"
66
+ try:
67
+ self._collection_started_at = now_ms()
68
+ databases = self._get_databases()
69
+ self._log.debug("Collecting schemas for %d databases", len(databases))
70
+ for database in databases:
71
+ self._log.debug("Starting collection of schemas for database %s", database['name'])
72
+ database_name = database['name']
73
+ if not database_name:
74
+ self._log.warning("database has no name %v", database)
75
+ continue
76
+ with self._get_cursor(database_name) as cursor:
77
+ # Get the next row from the cursor
78
+ # We need to know when we've reached the last row so we can efficiently flush the last payload
79
+ # without an empty final payload
80
+ next_row = self._get_next(cursor)
81
+ while next_row:
82
+ self._queued_rows.append(self._map_row(database, next_row))
83
+ self._total_rows_count += 1
84
+ # Because we're iterating over a cursor we need to try to get
85
+ # the next row to see if we've reached the last row
86
+ next_row = self._get_next(cursor)
87
+ is_last_payload = database == databases[-1] and next_row is None
88
+ self.maybe_flush(is_last_payload)
89
+ self._log.debug("Completed collection of schemas for database %s", database_name)
90
+ except Exception as e:
91
+ status = "error"
92
+ self._log.error("Error collecting schema: %s", e)
93
+ raise e
94
+ finally:
95
+ self._check.histogram(
96
+ f"dd.{self._check.dbms}.schema.time",
97
+ now_ms() - self._collection_started_at,
98
+ tags=self._check.tags + ["status:" + status],
99
+ hostname=self._check.reported_hostname,
100
+ raw=True,
101
+ )
102
+ self._check.gauge(
103
+ f"dd.{self._check.dbms}.schema.tables_count",
104
+ self._total_rows_count,
105
+ tags=self._check.tags + ["status:" + status],
106
+ hostname=self._check.reported_hostname,
107
+ raw=True,
108
+ )
109
+ self._check.gauge(
110
+ f"dd.{self._check.dbms}.schema.payloads_count",
111
+ self._collection_payloads_count,
112
+ tags=self._check.tags + ["status:" + status],
113
+ hostname=self._check.reported_hostname,
114
+ raw=True,
115
+ )
116
+
117
+ self._reset()
118
+ return True
119
+
120
+ @property
121
+ def base_event(self):
122
+ return {
123
+ "host": self._check.reported_hostname,
124
+ "database_instance": self._check.database_identifier,
125
+ "kind": self.kind,
126
+ "agent_version": datadog_agent.get_version(),
127
+ "collection_interval": self._config.collection_interval,
128
+ "dbms": self._check.dbms,
129
+ "dbms_version": str(self._check.dbms_version),
130
+ "tags": self._check.tags,
131
+ "cloud_metadata": self._check.cloud_metadata,
132
+ "collection_started_at": self._collection_started_at,
133
+ }
134
+
135
+ def maybe_flush(self, is_last_payload):
136
+ if is_last_payload or len(self._queued_rows) >= self._config.payload_chunk_size:
137
+ event = self.base_event
138
+ event["timestamp"] = now_ms()
139
+ # DBM backend expects metadata to be an array of database objects
140
+ event["metadata"] = self._queued_rows
141
+ self._collection_payloads_count += 1
142
+ if is_last_payload:
143
+ # For the last payload, we need to include the total number of payloads collected
144
+ # This is used for snapshotting to ensure that all payloads have been received
145
+ event["collection_payloads_count"] = self._collection_payloads_count
146
+ self._check.database_monitoring_metadata(json.dumps(event))
147
+
148
+ self._queued_rows = []
149
+
150
+ @property
151
+ @abstractmethod
152
+ def kind(self) -> str:
153
+ """
154
+ Returns the kind property of the schema metadata event.
155
+ Subclasses should override this property to return the kind of schema being collected.
156
+ """
157
+ raise NotImplementedError("Subclasses must implement kind")
158
+
159
+ @abstractmethod
160
+ def _get_databases(self) -> list[DatabaseInfo]:
161
+ """
162
+ Returns a list of database dictionaries.
163
+ Subclasses should override this method to return the list of databases to collect schema metadata for.
164
+ """
165
+ raise NotImplementedError("Subclasses must implement _get_databases")
166
+
167
+ @abstractmethod
168
+ def _get_cursor(self, database):
169
+ """
170
+ Returns a cursor for the given database.
171
+ Subclasses should override this method to return the cursor for the given database.
172
+ """
173
+ raise NotImplementedError("Subclasses must implement _get_cursor")
174
+
175
+ @abstractmethod
176
+ def _get_next(self, cursor):
177
+ """
178
+ Returns the next row from the cursor.
179
+ Subclasses should override this method to return the next row from the cursor.
180
+ """
181
+ raise NotImplementedError("Subclasses must implement _get_next")
182
+
183
+ def _map_row(self, database: DatabaseInfo, _cursor_row) -> DatabaseObject:
184
+ """
185
+ Maps a cursor row to a dict that matches the schema expected by DBM.
186
+ The base implementation of this method returns just the database dictionary.
187
+ Subclasses should override this method to add schema and table data based on the cursor row.
188
+ """
189
+ return {**database}
@@ -647,3 +647,10 @@ class TagManager:
647
647
  # Generate and cache regular tags
648
648
  self._cached_tag_list = self._generate_tag_strings(self._tags)
649
649
  return list(self._cached_tag_list)
650
+
651
+
652
+ def now_ms() -> int:
653
+ """
654
+ Get the current time in whole milliseconds.
655
+ """
656
+ return int(time.time() * 1000)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datadog-checks-base
3
- Version: 37.23.2
3
+ Version: 37.24.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>
@@ -31,7 +31,7 @@ Requires-Dist: requests-toolbelt==1.0.0; extra == 'deps'
31
31
  Requires-Dist: requests-unixsocket2==1.0.0; extra == 'deps'
32
32
  Requires-Dist: requests==2.32.5; extra == 'deps'
33
33
  Requires-Dist: simplejson==3.20.1; extra == 'deps'
34
- Requires-Dist: urllib3==2.6.2; extra == 'deps'
34
+ Requires-Dist: urllib3==2.5.0; extra == 'deps'
35
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'
@@ -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=mxfnF5UtdjcBXByAkU2G2evIXh0grpahewFqPQLc1RA,139
6
+ datadog_checks/base/__about__.py,sha256=wSZGCjyvIvIxmZigNmkP1nHZ-mq9lRhQoAtnr48RZq8,139
7
7
  datadog_checks/base/__init__.py,sha256=yWegSLE-TZWIGSvAiJj9PSrUxzlOo_UVJLt2zORZ8Ek,363
8
8
  datadog_checks/base/__init__.pyi,sha256=a4Y1JIcPJ8pz9tRkBAvjWdtvSQwZxbMZBuRmIiSs_4E,1031
9
9
  datadog_checks/base/agent.py,sha256=nX9x_BYYizRKGNYfXq5z7S0FZ9xcX_wd2tuxpGe3_8k,350
@@ -15,8 +15,8 @@ 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=ydetl6kEFCSChppYQhs8mvIP5l6vnZD5AbLABGhbFcM,309
17
17
  datadog_checks/base/checks/_config_ast.py,sha256=v1rAhwORF80b3kfZKhf6zXZ7S5D3A2QPUK4tSo8eo-Y,3268
18
- datadog_checks/base/checks/base.py,sha256=mnh61HRvHFisSP4IvUtoDPswxB3_ybX-nWkfXMyzWJE,60721
19
- datadog_checks/base/checks/db.py,sha256=HzEOH4uZaMDAaUTJYy0K5wV9FryNQDXsSMAOHXPVaf4,794
18
+ datadog_checks/base/checks/base.py,sha256=UgQmWpClcMQ9hawWNcOFGMPrfSKu8YP22ovTEB1dAUg,60965
19
+ datadog_checks/base/checks/db.py,sha256=9BeEwuDJ5TDXlq6yJXYVs9T_UlbCa3bWrSOq5ZshDKc,1350
20
20
  datadog_checks/base/checks/network.py,sha256=UkgqkVHaoX7Hqi0WKEx-TvaFiF6-37VyF9A3m2aSaJM,1966
21
21
  datadog_checks/base/checks/kube_leader/__init__.py,sha256=q7V6v-FwQWkQC1QWaVzKaPjZMaxPJHJcLd71C0uM7bA,211
22
22
  datadog_checks/base/checks/kube_leader/__init__.pyi,sha256=UGDywoRwmCIz3Zii1uHsp7jiFGWRdn5fFMZZxgGGlQs,398
@@ -75,7 +75,7 @@ datadog_checks/base/checks/win/winpdh_base.py,sha256=z3pPHG0H5ixwjeGi08cLe00VbZ3
75
75
  datadog_checks/base/checks/win/winpdh_stub.py,sha256=M5fyBkzAuEKvoZrG9ktQapwkH_7K-KOIYF5VpS83LMk,391
76
76
  datadog_checks/base/checks/win/wmi/__init__.py,sha256=q7V6v-FwQWkQC1QWaVzKaPjZMaxPJHJcLd71C0uM7bA,211
77
77
  datadog_checks/base/checks/win/wmi/__init__.pyi,sha256=2lgW_cDX36mGgwjBQ4jcUUkD4pIN73QfXvlPO7oK-X8,594
78
- datadog_checks/base/checks/win/wmi/base.py,sha256=QzwCEgzu9DF8hZwcwTNpomq0ApUWwZSNRS-oqbeJXG8,15155
78
+ datadog_checks/base/checks/win/wmi/base.py,sha256=xbY8S4mvquI5m7o1b6baeauj6PxEr9eCKlugO_xsi1I,17152
79
79
  datadog_checks/base/checks/win/wmi/counter_type.py,sha256=7772XGtWyPJXewyvaYyowVmDy9DxZ42ki9WD5XabuVE,5773
80
80
  datadog_checks/base/checks/win/wmi/sampler.py,sha256=NJlkALF8y1khAWRocpbH2LpwxtQb2F8fzBhCavvRX4w,23490
81
81
  datadog_checks/base/checks/win/wmi/types.py,sha256=4E8e1ypp2P-eOxgLsRrftlauqvapWCuVaAPocqCrwVg,412
@@ -143,13 +143,14 @@ datadog_checks/base/utils/db/__init__.pyi,sha256=ewmGxxyJ52wAaYxNZahi2koEUnddfvH
143
143
  datadog_checks/base/utils/db/core.py,sha256=bYanwXIqBzsSxK7b-Ofb0W1WiHbFBtKyYdUBonBLe_Q,11165
144
144
  datadog_checks/base/utils/db/health.py,sha256=riJaJInOuYFK3y0wNH19HojIkXPwQaMtvxuyPCRxnZY,4182
145
145
  datadog_checks/base/utils/db/query.py,sha256=-PyxdqpbShkQ78h7sWnghQZVtjdLGVrm71n8OpHuPW4,14432
146
+ datadog_checks/base/utils/db/schemas.py,sha256=RqEhbX-bZr335Ah6XdvPoB4XUQ-hE72tI0jNFCusXF4,7435
146
147
  datadog_checks/base/utils/db/sql.py,sha256=oiEzQa_vC_w3U65VFrFCoQHWj5GQLLRlSO0CfiSlp4A,2490
147
148
  datadog_checks/base/utils/db/sql_commenter.py,sha256=r_efK6TGRQxM_-Qj-ndEJdECk47J4nCFjkVyxu1XmvU,1522
148
149
  datadog_checks/base/utils/db/statement_metrics.py,sha256=U7EtERkmFzfCtfyd3094fBaKQ-CuJxoRt-3AcDBCkIA,7087
149
150
  datadog_checks/base/utils/db/timed_cache.py,sha256=a9Ks5KKUvExB6GOATXTSCLamVtLD919Dn6HpweGKtFw,2114
150
151
  datadog_checks/base/utils/db/transform.py,sha256=H3JN8_MF0Pk0HaXvIZeX1A8iQrP8KBgS741MPeBiWDo,23969
151
152
  datadog_checks/base/utils/db/types.py,sha256=OLX2Oq58JQPFBD4oqUpCLkAP7ovRGN_i1vFk1E0N8Lg,267
152
- datadog_checks/base/utils/db/utils.py,sha256=fJZrf2YcAbWmX4IRqLf4r0Rt8tGLDwgdIVmSMSft1co,26464
153
+ datadog_checks/base/utils/db/utils.py,sha256=7h8kk7BdGcxC7EcySAS-fbZXp2vcTSGepO7u04U42SE,26586
153
154
  datadog_checks/base/utils/discovery/__init__.py,sha256=vPCOdsThBcBjFJRPhDm6IsZGOwk8HlvciwCe_l8dKLk,211
154
155
  datadog_checks/base/utils/discovery/__init__.pyi,sha256=ScVLU1Njj9ekZmewltb0cULI6BylssVHfn4CcPNeyr8,173
155
156
  datadog_checks/base/utils/discovery/cache.py,sha256=f9L3A7YZpZ-mpZpFIwjsa5ab9cZMGkqdetdr9EpalbI,887
@@ -223,6 +224,6 @@ datadog_checks/utils/tracing.py,sha256=HQbQakKM-Lw75MDkItaYJYipS6YO24Z_ymDVxDsx5
223
224
  datadog_checks/utils/prometheus/__init__.py,sha256=8WwXnM9g1sfS5267QYCJX_hd8MZl5kRgBgQ_SzdNdXs,161
224
225
  datadog_checks/utils/prometheus/functions.py,sha256=4vWsTGLgujHwdYZo0tlAQkqDPHofqUJM3k9eItJqERQ,197
225
226
  datadog_checks/utils/prometheus/metrics_pb2.py,sha256=xg3UdUHe4TjeR4s13LUKZ2U1WVSt6U6zjsVRG6lX6dc,173
226
- datadog_checks_base-37.23.2.dist-info/METADATA,sha256=zlabqwys0YOujr_DtntwAehdAzCahH89eqs7yxVzzms,4245
227
- datadog_checks_base-37.23.2.dist-info/WHEEL,sha256=aha0VrrYvgDJ3Xxl3db_g_MDIW-ZexDdrc_m-Hk8YY4,105
228
- datadog_checks_base-37.23.2.dist-info/RECORD,,
227
+ datadog_checks_base-37.24.0.dist-info/METADATA,sha256=NONVEvQ8UyQLnGpL067F7u_Tp74pZRJME9rCn1f6THg,4245
228
+ datadog_checks_base-37.24.0.dist-info/WHEEL,sha256=tkmg4JIqwd9H8mL30xA7crRmoStyCtGp0VWshokd1Jc,105
229
+ datadog_checks_base-37.24.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.28.0
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py2-none-any
5
5
  Tag: py3-none-any