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 target-info metric type #19368

Closed
wants to merge 11 commits into from
Closed
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
1 change: 1 addition & 0 deletions datadog_checks_base/changelog.d/19368.added
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for target_info metric type
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ def scrape(self):
transformer(metric, self.generate_sample_data(metric), runtime_data)

self.flush_first_value = True
self.info_labels = []

def consume_metrics(self, runtime_data):
"""
Expand All @@ -271,8 +272,9 @@ def parse_metrics(self):
"""
Get the line streamer and yield processed metrics.
"""

line_streamer = self.stream_connection_lines()
raw_metric_payload = self.get_connection()
self.info_labels = self.extract_target_info(raw_metric_payload)
line_streamer = self.stream_connection_lines(raw_metric_payload)
if self.raw_line_filter is not None:
line_streamer = self.filter_connection_lines(line_streamer)

Expand All @@ -287,7 +289,6 @@ def parse_metrics(self):

for metric in self.parse_metric_families(line_streamer):
self.submit_telemetry_number_of_total_metric_samples(metric)

# It is critical that the prefix is removed immediately so that
# all other configuration may reference the trimmed metric name
if self.raw_metric_prefix and metric.name.startswith(self.raw_metric_prefix):
Expand Down Expand Up @@ -344,6 +345,7 @@ def generate_sample_data(self, metric):
continue

tags.extend(self.tags)
tags.extend(self.info_labels)

hostname = ""
if self.hostname_label and self.hostname_label in labels:
Expand All @@ -354,13 +356,29 @@ def generate_sample_data(self, metric):
self.submit_telemetry_number_of_processed_metric_samples()
yield sample, tags, hostname

def stream_connection_lines(self):
def extract_target_info(self, payload):
"""
Yield the connection line.
Extract target_info information from the payload using regex search
on raw bytes and parse labels
"""
combined_pattern = re.compile(
rb"# (?:HELP|TYPE) target.*|target_info\{(.*?)\}"
) # Match HELP, TYPE, or target_info with labels in bytes

key_value_pattern = re.compile(rb'(\w+)="([^"]*)"') # Match key-value pairs
extracted_labels = tuple(
f"{key.decode('utf-8')}:{value.decode('utf-8')}"
for match in combined_pattern.finditer(payload.content)
for key, value in key_value_pattern.findall(match.group(1) or b"")
)
return extracted_labels

def stream_connection_lines(self, payload):
"""
Yield the connection lines.
"""
try:
with self.get_connection() as connection:
with payload as connection:
# Media type will be used to select parser dynamically
self._content_type = connection.headers.get('Content-Type', '')
for line in connection.iter_lines(decode_unicode=True):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@


def test_submission(dd_run_check, datadog_agent):

class TestLogStream(LogStream):
def __init__(self, start, **kwargs):
super().__init__(**kwargs)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# (C) Datadog, Inc. 2020-present
# All rights reserved
# Licensed under a 3-clause BSD style license (see LICENSE)

from .utils import get_check


def test_target_info_tags_propagation(aggregator, dd_run_check, mock_http_response):

check = get_check({'metrics': ['.+']})

mock_http_response(
"""
# HELP go_memstats_alloc_bytes Number of bytes allocated and still in use.
# TYPE go_memstats_alloc_bytes gauge
go_memstats_alloc_bytes{foo="bar"} 6.396288e+06
# HELP target Target metadata
# TYPE target info
target_info{env="prod", region="europe"} 1.0
"""
)

dd_run_check(check)

aggregator.assert_metric(
'test.go_memstats_alloc_bytes',
value=6396288,
tags=['endpoint:test', 'foo:bar', 'env:prod', 'region:europe'],
metric_type=aggregator.GAUGE,
)

aggregator.assert_all_metrics_covered()
Loading