Skip to content

Commit 22f0280

Browse files
iliakurNouemanKHAL
andauthored
Add option to lowercase "device" tag (#19964)
* Add option to lowercase "device" tag * add changelog * Limit to linux * Update disk/assets/configuration/spec.yaml Co-authored-by: NouemanKHAL <[email protected]> * sync config * fix style --------- Co-authored-by: NouemanKHAL <[email protected]>
1 parent 6d492b0 commit 22f0280

File tree

7 files changed

+83
-4
lines changed

7 files changed

+83
-4
lines changed

disk/assets/configuration/spec.yaml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ files:
200200
Works on Linux only.
201201
value:
202202
example: false
203-
type: boolean
203+
type: boolean
204204
- name: device_tag_re
205205
description: |
206206
Instruct the check to apply additional tags to matching
@@ -263,3 +263,13 @@ files:
263263
type: string
264264
- name: type
265265
type: string
266+
267+
- name: lowercase_device_tag
268+
description: |
269+
Enable this to lowercase the "device" tags for both partition and disk metrics.
270+
This is useful only in very specific circumstances:
271+
1. Your "device" tag value is uppercase and your host is running on Linux.
272+
2. You cannot use the "device_name" tag.
273+
value:
274+
type: boolean
275+
example: false

disk/changelog.d/19964.added

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add option to lowercase "device" tag. Useful for those who cannot use the "device_name" tag and need "device" to only be lowercase.

disk/datadog_checks/disk/config_models/defaults.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ def instance_include_all_devices():
2424
return True
2525

2626

27+
def instance_lowercase_device_tag():
28+
return False
29+
30+
2731
def instance_min_collection_interval():
2832
return 15
2933

disk/datadog_checks/disk/config_models/instance.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class InstanceConfig(BaseModel):
5959
file_system_exclude: Optional[tuple[str, ...]] = None
6060
file_system_include: Optional[tuple[str, ...]] = None
6161
include_all_devices: Optional[bool] = None
62+
lowercase_device_tag: Optional[bool] = None
6263
metric_patterns: Optional[MetricPatterns] = None
6364
min_collection_interval: Optional[float] = None
6465
min_disk_size: Optional[float] = None

disk/datadog_checks/disk/data/conf.yaml.default

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,3 +252,11 @@ instances:
252252
# host: nfsserver
253253
# share: /mnt/nfs_share
254254
# type: nfs
255+
256+
## @param lowercase_device_tag - boolean - optional - default: false
257+
## Enable this to lowercase the "device" tags for both partition and disk metrics.
258+
## This is useful only in very specific circumstances:
259+
## 1. Your "device" tag value is uppercase and your host is running on Linux.
260+
## 2. You cannot use the "device_name" tag.
261+
#
262+
# lowercase_device_tag: false

disk/datadog_checks/disk/disk.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ def __init__(self, name, init_config, instances):
6565
self._compile_pattern_filters(instance)
6666
self._compile_tag_re()
6767
self._blkid_label_re = re.compile('LABEL=\"(.*?)\"', re.I)
68+
self._lowercase_device_tag = is_affirmative(instance.get('lowercase_device_tag', False))
6869

6970
if self._use_lsblk and self._blkid_cache_file:
7071
raise ConfigurationError("Only one of 'use_lsblk' and 'blkid_cache_file' can be set at the same time.")
@@ -183,7 +184,7 @@ def _get_tags(self, part):
183184
if Platform.is_win32():
184185
device_name = device_name.strip('\\').lower()
185186

186-
tags.append('device:{}'.format(device_name))
187+
tags.append('device:{}'.format(device_name.lower() if self._lowercase_device_tag else device_name))
187188
tags.append('device_name:{}'.format(_base_device_name(part.device)))
188189
return tags
189190

@@ -331,7 +332,7 @@ def collect_latency_metrics(self):
331332
device_specific_tags = self._get_device_specific_tags(disk_name)
332333
metric_tags.extend(device_specific_tags)
333334

334-
metric_tags.append('device:{}'.format(disk_name))
335+
metric_tags.append('device:{}'.format(disk_name.lower() if self._lowercase_device_tag else disk_name))
335336
metric_tags.append('device_name:{}'.format(_base_device_name(disk_name)))
336337
if self.devices_label.get(disk_name):
337338
metric_tags.extend(self.devices_label.get(disk_name))

disk/tests/test_unit.py

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
from datadog_checks.base.utils.platform import Platform
1212
from datadog_checks.base.utils.timeout import TimeoutException
13-
from datadog_checks.dev.testing import requires_windows
13+
from datadog_checks.dev.testing import requires_linux, requires_windows
1414
from datadog_checks.dev.utils import ON_WINDOWS, get_metadata_metrics, mock_context_manager
1515
from datadog_checks.disk import Disk
1616
from datadog_checks.disk.disk import IGNORE_CASE
@@ -223,6 +223,60 @@ def test_use_mount(aggregator, instance_basic_mount, gauge_metrics, rate_metrics
223223
aggregator.assert_metrics_using_metadata(get_metadata_metrics())
224224

225225

226+
@requires_linux # Only linux cares about upper/lower case for paths.
227+
@pytest.mark.parametrize(
228+
'lc_device_tag, expected_dev_path',
229+
[
230+
pytest.param(None, '//CIFS/DEV1', id='Default behavior, keep case'),
231+
pytest.param(False, '//CIFS/DEV1', id='Disabled, keep case'),
232+
pytest.param(True, '//cifs/dev1', id='Enabled, lowercase'),
233+
],
234+
)
235+
def test_lowercase_device_tag(
236+
aggregator,
237+
instance_basic_volume,
238+
gauge_metrics,
239+
rate_metrics,
240+
count_metrics,
241+
dd_run_check,
242+
mocker,
243+
lc_device_tag,
244+
expected_dev_path,
245+
):
246+
"""
247+
If explicitly configured, we will lowercase the "device" tag value.
248+
249+
For metrics with uppercase "device" tag values, our backend introduces a lowercase version of the tag.
250+
Some customers don't like this and cannot use the "device_name" tag instead.
251+
They requested that we add a switch for them to lowercase the "device" tag before we submit it.
252+
This flag MUST be off by default to avoid breaking anyone else.
253+
"""
254+
if lc_device_tag is not None:
255+
instance_basic_volume['lowercase_device_tag'] = lc_device_tag
256+
c = Disk('disk', {}, [instance_basic_volume])
257+
258+
if ON_WINDOWS:
259+
mock_statvfs = mock_context_manager()
260+
else:
261+
mock_statvfs = mock.patch('os.statvfs', return_value=MockInodesMetrics(), __name__='statvfs')
262+
263+
full_dev_path = '//CIFS/DEV1'
264+
mocker.patch(
265+
'psutil.disk_partitions',
266+
return_value=[MockPart(device=full_dev_path, fstype="cifs")],
267+
__name__='disk_partitions',
268+
)
269+
mocker.patch('psutil.disk_usage', return_value=MockDiskMetrics(), __name__='disk_usage')
270+
mocker.patch('psutil.disk_io_counters', return_value=MockDiskIOMetrics(full_dev_path))
271+
with mock_statvfs:
272+
dd_run_check(c)
273+
274+
for name in chain(gauge_metrics, rate_metrics, count_metrics):
275+
aggregator.assert_metric_has_tag(name, f'device:{expected_dev_path}')
276+
# Make sure the "device_name" tag isn't affected.
277+
aggregator.assert_metric_has_tag(name, 'device_name:DEV1')
278+
279+
226280
@pytest.mark.usefixtures('psutil_mocks')
227281
def test_device_tagging(aggregator, gauge_metrics, rate_metrics, count_metrics, dd_run_check):
228282
instance = {

0 commit comments

Comments
 (0)