Skip to content
This repository was archived by the owner on Sep 17, 2025. It is now read-only.

Commit 551522d

Browse files
authored
Fix stackdriver k8s label keys (#656)
1 parent 188b204 commit 551522d

File tree

6 files changed

+121
-123
lines changed

6 files changed

+121
-123
lines changed

contrib/opencensus-ext-stackdriver/opencensus/ext/stackdriver/stats_exporter/__init__.py

Lines changed: 57 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
import google.auth
2626

2727
from opencensus.common import utils
28+
from opencensus.common.monitored_resource import aws_identity_doc_utils
29+
from opencensus.common.monitored_resource import gcp_metadata_config
30+
from opencensus.common.monitored_resource import k8s_utils
2831
from opencensus.common.monitored_resource import monitored_resource
2932
from opencensus.common.version import __version__
3033
from opencensus.metrics import label_key
@@ -300,62 +303,65 @@ def register_metric_descriptor(self, oc_md):
300303

301304

302305
def set_monitored_resource(series, option_resource_type):
303-
"""Set a resource(type and labels) that can be used for monitoring.
306+
"""Set this series' monitored resource and labels.
307+
304308
:param series: TimeSeries object based on view data
305309
:param option_resource_type: Resource is an optional field that
306310
represents the Stackdriver MonitoredResource type.
307311
"""
308-
resource_type = GLOBAL_RESOURCE_TYPE
309-
310-
if option_resource_type == "":
311-
resource = monitored_resource.get_instance()
312-
if resource is not None:
313-
resource_labels = resource.get_labels()
314-
315-
if resource.get_type() == 'gke_container':
316-
resource_type = 'k8s_container'
317-
set_attribute_label(series, resource_labels, 'project_id')
318-
set_attribute_label(series, resource_labels, 'cluster_name')
319-
set_attribute_label(series, resource_labels, 'container_name')
320-
set_attribute_label(series, resource_labels, 'namespace_id',
321-
'namespace_name')
322-
set_attribute_label(series, resource_labels, 'pod_id',
323-
'pod_name')
324-
set_attribute_label(series, resource_labels, 'zone',
325-
'location')
326-
327-
elif resource.get_type() == 'gce_instance':
328-
resource_type = 'gce_instance'
329-
set_attribute_label(series, resource_labels, 'project_id')
330-
set_attribute_label(series, resource_labels, 'instance_id')
331-
set_attribute_label(series, resource_labels, 'zone')
332-
333-
elif resource.get_type() == 'aws_ec2_instance':
334-
resource_type = 'aws_ec2_instance'
335-
set_attribute_label(series, resource_labels, 'aws_account')
336-
set_attribute_label(series, resource_labels, 'instance_id')
337-
set_attribute_label(series, resource_labels, 'region',
338-
label_value_prefix='aws:')
339-
else:
340-
resource_type = option_resource_type
341-
series.resource.type = resource_type
312+
if option_resource_type != "":
313+
series.resource.type = option_resource_type
314+
return
315+
316+
resource = monitored_resource.get_instance()
317+
if resource is None:
318+
series.resource.type = GLOBAL_RESOURCE_TYPE
319+
return
320+
321+
resource_type = resource.get_type()
322+
resource_labels = resource.get_labels()
323+
324+
def set_attribute_label(attribute_key, label_key, label_value_prefix=''):
325+
"""Set a label to timeseries that can be used for monitoring.
326+
327+
:param series: TimeSeries object based on view data
328+
:param resource_labels: collection of labels
329+
:param attribute_key: actual label key
330+
:param label_key: optional exporter-specific label key
331+
:param label_value_prefix: optional exporter-specific prefix
332+
"""
333+
if attribute_key not in resource_labels:
334+
return
335+
336+
series.resource.labels[label_key] = (label_value_prefix +
337+
resource_labels[attribute_key])
338+
339+
if resource_type == 'k8s_container':
340+
series.resource.type = 'k8s_container'
341+
set_attribute_label(gcp_metadata_config.PROJECT_ID_KEY, 'project_id')
342+
set_attribute_label(k8s_utils.CLUSTER_NAME_KEY, 'cluster_name')
343+
set_attribute_label(k8s_utils.CONTAINER_NAME_KEY, 'container_name')
344+
set_attribute_label(k8s_utils.NAMESPACE_NAME_KEY, 'namespace_name')
345+
set_attribute_label(k8s_utils.POD_NAME_KEY, 'pod_name')
346+
set_attribute_label(gcp_metadata_config.ZONE_KEY, 'location')
347+
348+
elif resource_type == 'gce_instance':
349+
series.resource.type = 'gce_instance'
350+
set_attribute_label(gcp_metadata_config.PROJECT_ID_KEY, 'project_id')
351+
set_attribute_label(gcp_metadata_config.INSTANCE_ID_KEY, 'instance_id')
352+
set_attribute_label(gcp_metadata_config.ZONE_KEY, 'zone')
353+
354+
elif resource_type == 'aws_ec2_instance':
355+
series.resource.type = 'aws_ec2_instance'
356+
set_attribute_label(aws_identity_doc_utils.ACCOUNT_ID_KEY,
357+
'aws_account')
358+
set_attribute_label(aws_identity_doc_utils.INSTANCE_ID_KEY,
359+
'instance_id')
360+
set_attribute_label(aws_identity_doc_utils.REGION_KEY, 'region',
361+
label_value_prefix='aws:')
342362

343-
344-
def set_attribute_label(series, resource_labels, attribute_key,
345-
canonical_key=None, label_value_prefix=''):
346-
"""Set a label to timeseries that can be used for monitoring
347-
:param series: TimeSeries object based on view data
348-
:param resource_labels: collection of labels
349-
:param attribute_key: actual label key
350-
:param canonical_key: exporter specific label key, Optional
351-
:param label_value_prefix: exporter specific label value prefix, Optional
352-
"""
353-
if attribute_key in resource_labels:
354-
if canonical_key is None:
355-
canonical_key = attribute_key
356-
357-
series.resource.labels[canonical_key] = \
358-
label_value_prefix + resource_labels[attribute_key]
363+
else:
364+
series.resource.type = GLOBAL_RESOURCE_TYPE
359365

360366

361367
def get_user_agent_slug():

contrib/opencensus-ext-stackdriver/opencensus/ext/stackdriver/trace_exporter/__init__.py

Lines changed: 39 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
from google.cloud.trace.client import Client
1919

20+
from opencensus.common.monitored_resource import aws_identity_doc_utils
21+
from opencensus.common.monitored_resource import gcp_metadata_config
22+
from opencensus.common.monitored_resource import k8s_utils
2023
from opencensus.common.monitored_resource import monitored_resource
2124
from opencensus.common.transports import sync
2225
from opencensus.common.version import __version__
@@ -79,65 +82,51 @@ def set_monitored_resource_attributes(span):
7982
:param span: Span object
8083
"""
8184
resource = monitored_resource.get_instance()
82-
if resource is not None:
83-
resource_type = resource.get_type()
84-
resource_labels = resource.get_labels()
85-
86-
if resource_type == 'gke_container':
87-
resource_type = 'k8s_container'
88-
set_attribute_label(span, resource_type, resource_labels,
89-
'project_id')
90-
set_attribute_label(span, resource_type, resource_labels,
91-
'cluster_name')
92-
set_attribute_label(span, resource_type, resource_labels,
93-
'container_name')
94-
set_attribute_label(span, resource_type, resource_labels,
95-
'namespace_id', 'namespace_name')
96-
set_attribute_label(span, resource_type, resource_labels,
97-
'pod_id', 'pod_name')
98-
set_attribute_label(span, resource_type, resource_labels,
99-
'zone', 'location')
100-
101-
elif resource_type == 'gce_instance':
102-
set_attribute_label(span, resource_type, resource_labels,
103-
'project_id')
104-
set_attribute_label(span, resource_type, resource_labels,
105-
'instance_id')
106-
set_attribute_label(span, resource_type, resource_labels,
107-
'zone')
108-
109-
elif resource_type == 'aws_ec2_instance':
110-
set_attribute_label(span, resource_type, resource_labels,
111-
'aws_account')
112-
set_attribute_label(span, resource_type, resource_labels,
113-
'instance_id')
114-
set_attribute_label(span, resource_type, resource_labels,
115-
'region', label_value_prefix='aws:')
116-
117-
118-
def set_attribute_label(span, resource_type, resource_labels, attribute_key,
119-
canonical_key=None, label_value_prefix=''):
120-
"""Set a label to span that can be used for tracing.
121-
:param span: Span object
122-
:param resource_type: resource type
123-
:param resource_labels: collection of labels
124-
:param attribute_key: actual label key
125-
:param canonical_key: exporter specific label key, Optional
126-
:param label_value_prefix: exporter specific label value prefix, Optional
127-
"""
85+
if resource is None:
86+
return
87+
88+
resource_type = resource.get_type()
89+
resource_labels = resource.get_labels()
12890

129-
if attribute_key in resource_labels:
130-
if canonical_key is None:
131-
canonical_key = attribute_key
91+
def set_attribute_label(attribute_key, label_key,
92+
label_value_prefix=''):
93+
"""Add the attribute to the span attribute map.
13294
133-
pair = {RESOURCE_LABEL % (resource_type, canonical_key):
95+
Update the span attribute map (`span['attributes']['attributeMap']`) to
96+
include a given resource label.
97+
"""
98+
if attribute_key not in resource_labels:
99+
return
100+
101+
pair = {RESOURCE_LABEL % (resource_type, label_key):
134102
label_value_prefix + resource_labels[attribute_key]
135103
}
136104
pair_attrs = Attributes(pair).format_attributes_json()\
137105
.get('attributeMap')
138106

139107
_update_attr_map(span, pair_attrs)
140108

109+
if resource_type == 'k8s_container':
110+
set_attribute_label(gcp_metadata_config.PROJECT_ID_KEY, 'project_id')
111+
set_attribute_label(k8s_utils.CLUSTER_NAME_KEY, 'cluster_name')
112+
set_attribute_label(k8s_utils.CONTAINER_NAME_KEY, 'container_name')
113+
set_attribute_label(k8s_utils.NAMESPACE_NAME_KEY, 'namespace_name')
114+
set_attribute_label(k8s_utils.POD_NAME_KEY, 'pod_name')
115+
set_attribute_label(gcp_metadata_config.ZONE_KEY, 'location')
116+
117+
elif resource_type == 'gce_instance':
118+
set_attribute_label(gcp_metadata_config.PROJECT_ID_KEY, 'project_id')
119+
set_attribute_label(gcp_metadata_config.INSTANCE_ID_KEY, 'instance_id')
120+
set_attribute_label(gcp_metadata_config.ZONE_KEY, 'zone')
121+
122+
elif resource_type == 'aws_ec2_instance':
123+
set_attribute_label(aws_identity_doc_utils.ACCOUNT_ID_KEY,
124+
'aws_account')
125+
set_attribute_label(aws_identity_doc_utils.INSTANCE_ID_KEY,
126+
'instance_id')
127+
set_attribute_label(aws_identity_doc_utils.REGION_KEY, 'region',
128+
label_value_prefix='aws:')
129+
141130

142131
def set_common_attributes(span):
143132
"""Set the common attributes."""

contrib/opencensus-ext-stackdriver/tests/test_stackdriver_exporter.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -678,14 +678,13 @@ def test_monitored_resource_attributes_gke(self, gmr_mock):
678678
}
679679

680680
mock_resource = mock.Mock()
681-
mock_resource.get_type.return_value = 'gke_container'
681+
mock_resource.get_type.return_value = 'k8s_container'
682682
mock_resource.get_labels.return_value = {
683-
'pod_id': 'pod',
684-
'cluster_name': 'cluster',
685-
'namespace_id': 'namespace',
686-
'container_name': 'c1',
683+
'k8s.io/pod/name': 'pod',
684+
'k8s.io/cluster/name': 'cluster',
685+
'k8s.io/namespace/name': 'namespace',
686+
'k8s.io/container/name': 'c1',
687687
'project_id': 'my_project',
688-
'instance_id': 'instance',
689688
'zone': 'zone1'
690689
}
691690
gmr_mock.return_value = mock_resource

contrib/opencensus-ext-stackdriver/tests/test_stackdriver_stats.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ def test_options_parameters(self):
9393

9494
def test_default_monitoring_labels(self):
9595
options = stackdriver.Options(default_monitoring_labels={
96-
label_key.LabelKey('lk_key', 'lk_desc'):
97-
label_value.LabelValue('lk_value')
96+
label_key.LabelKey('lk_key', 'lk_desc'):
97+
label_value.LabelValue('lk_value')
9898
})
9999

100100
self.assertEqual(len(options.default_monitoring_labels), 1)
@@ -876,8 +876,8 @@ def test_create_timeseries_with_resource(self, monitor_resource_mock):
876876
'instance_id': 'my-instance',
877877
'project_id': 'my-project',
878878
'zone': 'us-east1',
879-
'pod_id': 'localhost',
880-
'namespace_id': 'namespace'
879+
'k8s.io/pod/name': 'localhost',
880+
'k8s.io/namespace/name': 'namespace',
881881
}
882882

883883
mock_resource = mock.Mock()
@@ -908,18 +908,18 @@ def test_create_timeseries_with_resource(self, monitor_resource_mock):
908908
time_series.metric.type,
909909
"custom.googleapis.com/opencensus/my.org/views/video_size_test2")
910910

911-
# check for gke_container monitored resource
911+
# check for k8s_container monitored resource
912912
mocked_labels = {
913913
'instance_id': 'my-instance',
914914
'project_id': 'my-project',
915915
'zone': 'us-east1',
916-
'pod_id': 'localhost',
917-
'cluster_name': 'cluster',
918-
'namespace_id': 'namespace'
916+
'k8s.io/pod/name': 'localhost',
917+
'k8s.io/cluster/name': 'cluster',
918+
'k8s.io/namespace/name': 'namespace',
919919
}
920920

921921
mock_resource = mock.Mock()
922-
mock_resource.get_type.return_value = 'gke_container'
922+
mock_resource.get_type.return_value = 'k8s_container'
923923
mock_resource.get_labels.return_value = mocked_labels
924924
monitor_resource_mock.return_value = mock_resource
925925

opencensus/common/monitored_resource/aws_identity_doc_utils.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
from opencensus.common.http_handler import get_request
1616
import json
1717

18+
REGION_KEY = 'region'
19+
ACCOUNT_ID_KEY = 'aws_account'
20+
INSTANCE_ID_KEY = 'instance_id'
21+
1822
# AWS provides Instance Metadata via below url
1923
_AWS_INSTANCE_IDENTITY_DOCUMENT_URI = \
2024
"http://169.254.169.254/latest/dynamic/instance-identity/document"
@@ -23,13 +27,13 @@
2327
# Region is the AWS region for the VM. The format of this field is
2428
# "aws:{region}", where supported values for {region} are listed at
2529
# http://docs.aws.amazon.com/general/latest/gr/rande.html.
26-
'region': 'region',
30+
'region': REGION_KEY,
2731

2832
# accountId is the AWS account number for the VM.
29-
'accountId': 'aws_account',
33+
'accountId': ACCOUNT_ID_KEY,
3034

3135
# instanceId is the instance id of the instance.
32-
'instanceId': 'instance_id'
36+
'instanceId': INSTANCE_ID_KEY
3337
}
3438

3539
# inited is used to make sure AWS initialize executes only once.

tests/unit/common/monitored_resource_util/test_monitored_resource.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,12 @@ def test_gcp_k8s_monitored_resource(self, gcp_md_mock):
112112

113113
mocked_labels = {
114114
'instance_id': 'my-instance',
115-
'cluster_name': 'cluster',
116115
'project_id': 'my-project',
117116
'zone': 'us-east1',
118-
'pod_id': 'localhost',
119-
'namespace_id': 'namespace',
120-
'container_name': 'container'
117+
'k8s.io/cluster/name': 'cluster',
118+
'k8s.io/pod/name': 'localhost',
119+
'k8s.io/namespace/name': 'namespace',
120+
'k8s.io/container/name': 'container'
121121
}
122122
cluster_name_key = 'instance/attributes/cluster-name'
123123
cluster_name_val = 'cluster'

0 commit comments

Comments
 (0)