Skip to content

Commit 8d7cba0

Browse files
alrexocelotl
alrex
andauthored
Adding Resource to MetricRecord (open-telemetry#1209)
Co-authored-by: Diego Hurtado <ocelotl@users.noreply.github.com>
1 parent 803f582 commit 8d7cba0

File tree

11 files changed

+98
-45
lines changed

11 files changed

+98
-45
lines changed

exporter/opentelemetry-exporter-opencensus/src/opentelemetry/exporter/opencensus/metrics_exporter/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ def get_collector_point(metric_record: MetricRecord) -> metrics_pb2.Point:
191191

192192

193193
def get_resource(metric_record: MetricRecord) -> resource_pb2.Resource:
194-
resource_attributes = metric_record.instrument.meter.resource.attributes
194+
resource_attributes = metric_record.resource.attributes
195195
return resource_pb2.Resource(
196196
type=infer_oc_resource_type(resource_attributes),
197197
labels={k: str(v) for k, v in resource_attributes.items()},

exporter/opentelemetry-exporter-opencensus/tests/test_otcollector_metrics_exporter.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,21 +100,36 @@ def test_get_collector_point(self):
100100
"testName", "testDescription", "unit", float, ValueRecorder
101101
)
102102
result = metrics_exporter.get_collector_point(
103-
MetricRecord(int_counter, self._key_labels, aggregator)
103+
MetricRecord(
104+
int_counter,
105+
self._key_labels,
106+
aggregator,
107+
metrics.get_meter_provider().resource,
108+
)
104109
)
105110
self.assertIsInstance(result, metrics_pb2.Point)
106111
self.assertIsInstance(result.timestamp, Timestamp)
107112
self.assertEqual(result.int64_value, 0)
108113
aggregator.update(123.5)
109114
aggregator.take_checkpoint()
110115
result = metrics_exporter.get_collector_point(
111-
MetricRecord(float_counter, self._key_labels, aggregator)
116+
MetricRecord(
117+
float_counter,
118+
self._key_labels,
119+
aggregator,
120+
metrics.get_meter_provider().resource,
121+
)
112122
)
113123
self.assertEqual(result.double_value, 123.5)
114124
self.assertRaises(
115125
TypeError,
116126
metrics_exporter.get_collector_point(
117-
MetricRecord(valuerecorder, self._key_labels, aggregator)
127+
MetricRecord(
128+
valuerecorder,
129+
self._key_labels,
130+
aggregator,
131+
metrics.get_meter_provider().resource,
132+
)
118133
),
119134
)
120135

@@ -130,7 +145,10 @@ def test_export(self):
130145
"testname", "testdesc", "unit", int, Counter, self._labels.keys(),
131146
)
132147
record = MetricRecord(
133-
test_metric, self._key_labels, aggregate.SumAggregator(),
148+
test_metric,
149+
self._key_labels,
150+
aggregate.SumAggregator(),
151+
metrics.get_meter_provider().resource,
134152
)
135153

136154
result = collector_exporter.export([record])
@@ -155,7 +173,12 @@ def test_translate_to_collector(self):
155173
aggregator = aggregate.SumAggregator()
156174
aggregator.update(123)
157175
aggregator.take_checkpoint()
158-
record = MetricRecord(test_metric, self._key_labels, aggregator,)
176+
record = MetricRecord(
177+
test_metric,
178+
self._key_labels,
179+
aggregator,
180+
metrics.get_meter_provider().resource,
181+
)
159182
start_timestamp = Timestamp()
160183
output_metrics = metrics_exporter.translate_to_collector(
161184
[record], start_timestamp,

exporter/opentelemetry-exporter-otlp/src/opentelemetry/exporter/otlp/metrics_exporter/__init__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,11 @@ def _translate_data(
137137
# ValueObserver Gauge()
138138
for sdk_metric in data:
139139

140-
if sdk_metric.instrument.meter.resource not in (
140+
if sdk_metric.resource not in (
141141
sdk_resource_instrumentation_library_metrics.keys()
142142
):
143143
sdk_resource_instrumentation_library_metrics[
144-
sdk_metric.instrument.meter.resource
144+
sdk_metric.resource
145145
] = InstrumentationLibraryMetrics()
146146

147147
type_class = {
@@ -217,7 +217,7 @@ def _translate_data(
217217
argument = type_class[value_type]["gauge"]["argument"]
218218

219219
sdk_resource_instrumentation_library_metrics[
220-
sdk_metric.instrument.meter.resource
220+
sdk_metric.resource
221221
].metrics.append(
222222
OTLPMetric(
223223
**{

exporter/opentelemetry-exporter-otlp/tests/test_otlp_metric_exporter.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,20 +44,19 @@
4444
class TestOTLPMetricExporter(TestCase):
4545
def setUp(self):
4646
self.exporter = OTLPMetricsExporter()
47-
47+
resource = SDKResource(OrderedDict([("a", 1), ("b", False)]))
4848
self.counter_metric_record = MetricRecord(
4949
Counter(
5050
"a",
5151
"b",
5252
"c",
5353
int,
54-
MeterProvider(
55-
resource=SDKResource(OrderedDict([("a", 1), ("b", False)]))
56-
).get_meter(__name__),
54+
MeterProvider(resource=resource,).get_meter(__name__),
5755
("d",),
5856
),
5957
OrderedDict([("e", "f")]),
6058
SumAggregator(),
59+
resource,
6160
)
6261

6362
def test_translate_metrics(self):

exporter/opentelemetry-exporter-prometheus/tests/test_prometheus_exporter.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,10 @@ def test_shutdown(self):
6767
def test_export(self):
6868
with self._registry_register_patch:
6969
record = MetricRecord(
70-
self._test_metric, self._labels_key, SumAggregator(),
70+
self._test_metric,
71+
self._labels_key,
72+
SumAggregator(),
73+
get_meter_provider().resource,
7174
)
7275
exporter = PrometheusMetricsExporter()
7376
result = exporter.export([record])
@@ -86,7 +89,9 @@ def test_min_max_sum_aggregator_to_prometheus(self):
8689
aggregator.update(123)
8790
aggregator.update(456)
8891
aggregator.take_checkpoint()
89-
record = MetricRecord(metric, key_labels, aggregator)
92+
record = MetricRecord(
93+
metric, key_labels, aggregator, get_meter_provider().resource
94+
)
9095
collector = CustomCollector("testprefix")
9196
collector.add_metrics_data([record])
9297
result_bytes = generate_latest(collector)
@@ -104,7 +109,9 @@ def test_counter_to_prometheus(self):
104109
aggregator = SumAggregator()
105110
aggregator.update(123)
106111
aggregator.take_checkpoint()
107-
record = MetricRecord(metric, key_labels, aggregator)
112+
record = MetricRecord(
113+
metric, key_labels, aggregator, get_meter_provider().resource
114+
)
108115
collector = CustomCollector("testprefix")
109116
collector.add_metrics_data([record])
110117

@@ -132,7 +139,9 @@ def test_invalid_metric(self):
132139
)
133140
labels = {"environment": "staging"}
134141
key_labels = get_dict_as_key(labels)
135-
record = MetricRecord(metric, key_labels, None)
142+
record = MetricRecord(
143+
metric, key_labels, None, get_meter_provider().resource
144+
)
136145
collector = CustomCollector("testprefix")
137146
collector.add_metrics_data([record])
138147
collector.collect()

opentelemetry-sdk/CHANGELOG.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414
([#1203](https://github.com/open-telemetry/opentelemetry-python/pull/1203))
1515
- Protect access to Span implementation
1616
([#1188](https://github.com/open-telemetry/opentelemetry-python/pull/1188))
17-
- `start_as_current_span` and `use_span` can now optionally auto-record any exceptions raised inside the context manager. ([#1162](https://github.com/open-telemetry/opentelemetry-python/pull/1162))
17+
- `start_as_current_span` and `use_span` can now optionally auto-record any exceptions raised inside the context manager.
18+
([#1162](https://github.com/open-telemetry/opentelemetry-python/pull/1162))
19+
- Adding Resource to MeterRecord
20+
([#1209](https://github.com/open-telemetry/opentelemetry-python/pull/1209))
1821

1922
## Version 0.13b0
2023

opentelemetry-sdk/src/opentelemetry/sdk/metrics/__init__.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,7 @@ def __init__(
352352
instrumentation_info: "InstrumentationInfo",
353353
):
354354
self.instrumentation_info = instrumentation_info
355-
self.processor = Processor(source.stateful)
356-
self.resource = source.resource
355+
self.processor = Processor(source.stateful, source.resource)
357356
self.metrics = set()
358357
self.observers = set()
359358
self.metrics_lock = threading.Lock()

opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/__init__.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
from opentelemetry import metrics as metrics_api
1919
from opentelemetry.sdk.metrics.export.aggregate import Aggregator
20+
from opentelemetry.sdk.resources import Resource
2021

2122

2223
class MetricsExportResult(Enum):
@@ -30,10 +31,12 @@ def __init__(
3031
instrument: metrics_api.InstrumentT,
3132
labels: Tuple[Tuple[str, str]],
3233
aggregator: Aggregator,
34+
resource: Resource,
3335
):
3436
self.instrument = instrument
3537
self.labels = labels
3638
self.aggregator = aggregator
39+
self.resource = resource
3740

3841

3942
class MetricsExporter:
@@ -77,11 +80,12 @@ def export(
7780
) -> "MetricsExportResult":
7881
for record in metric_records:
7982
print(
80-
'{}(data="{}", labels="{}", value={})'.format(
83+
'{}(data="{}", labels="{}", value={}, resource={})'.format(
8184
type(self).__name__,
8285
record.instrument,
8386
record.labels,
8487
record.aggregator.checkpoint,
88+
record.resource.attributes,
8589
)
8690
)
8791
return MetricsExportResult.SUCCESS

opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/processor.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
from typing import Sequence
1616

1717
from opentelemetry.sdk.metrics.export import MetricRecord
18+
from opentelemetry.sdk.resources import Resource
1819
from opentelemetry.sdk.util import get_dict_as_key
1920

2021

@@ -26,13 +27,14 @@ class Processor:
2627
will be sent to an exporter for exporting.
2728
"""
2829

29-
def __init__(self, stateful: bool):
30+
def __init__(self, stateful: bool, resource: Resource):
3031
self._batch_map = {}
3132
# stateful=True indicates the processor computes checkpoints from over
3233
# the process lifetime. False indicates the processor computes
3334
# checkpoints which describe the updates of a single collection period
3435
# (deltas)
3536
self.stateful = stateful
37+
self._resource = resource
3638

3739
def checkpoint_set(self) -> Sequence[MetricRecord]:
3840
"""Returns a list of MetricRecords used for exporting.
@@ -46,7 +48,9 @@ def checkpoint_set(self) -> Sequence[MetricRecord]:
4648
(instrument, aggregator_type, _, labels),
4749
aggregator,
4850
) in self._batch_map.items():
49-
metric_records.append(MetricRecord(instrument, labels, aggregator))
51+
metric_records.append(
52+
MetricRecord(instrument, labels, aggregator, self._resource)
53+
)
5054
return metric_records
5155

5256
def finished_collection(self):

opentelemetry-sdk/tests/metrics/export/test_export.py

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,15 @@
3131
)
3232
from opentelemetry.sdk.metrics.export.controller import PushController
3333
from opentelemetry.sdk.metrics.export.processor import Processor
34+
from opentelemetry.sdk.resources import Resource
3435

3536

3637
# pylint: disable=protected-access
3738
class TestConsoleMetricsExporter(unittest.TestCase):
3839
# pylint: disable=no-self-use
3940
def test_export(self):
40-
meter = metrics.MeterProvider().get_meter(__name__)
41+
meter_provider = metrics.MeterProvider()
42+
meter = meter_provider.get_meter(__name__)
4143
exporter = ConsoleMetricsExporter()
4244
metric = metrics.Counter(
4345
"available memory",
@@ -49,12 +51,15 @@ def test_export(self):
4951
)
5052
labels = {"environment": "staging"}
5153
aggregator = SumAggregator()
52-
record = MetricRecord(metric, labels, aggregator)
53-
result = '{}(data="{}", labels="{}", value={})'.format(
54+
record = MetricRecord(
55+
metric, labels, aggregator, meter_provider.resource
56+
)
57+
result = '{}(data="{}", labels="{}", value={}, resource={})'.format(
5458
ConsoleMetricsExporter.__name__,
5559
metric,
5660
labels,
5761
aggregator.checkpoint,
62+
meter_provider.resource.attributes,
5863
)
5964
with mock.patch("sys.stdout") as mock_stdout:
6065
exporter.export([record])
@@ -63,8 +68,9 @@ def test_export(self):
6368

6469
class TestProcessor(unittest.TestCase):
6570
def test_checkpoint_set(self):
66-
meter = metrics.MeterProvider().get_meter(__name__)
67-
processor = Processor(True)
71+
meter_provider = metrics.MeterProvider()
72+
meter = meter_provider.get_meter(__name__)
73+
processor = Processor(True, meter_provider.resource)
6874
aggregator = SumAggregator()
6975
metric = metrics.Counter(
7076
"available memory", "available memory", "bytes", int, meter
@@ -81,13 +87,14 @@ def test_checkpoint_set(self):
8187
self.assertEqual(records[0].aggregator, aggregator)
8288

8389
def test_checkpoint_set_empty(self):
84-
processor = Processor(True)
90+
processor = Processor(True, Resource.create_empty())
8591
records = processor.checkpoint_set()
8692
self.assertEqual(len(records), 0)
8793

8894
def test_finished_collection_stateless(self):
89-
meter = metrics.MeterProvider().get_meter(__name__)
90-
processor = Processor(False)
95+
meter_provider = metrics.MeterProvider()
96+
meter = meter_provider.get_meter(__name__)
97+
processor = Processor(False, meter_provider.resource)
9198
aggregator = SumAggregator()
9299
metric = metrics.Counter(
93100
"available memory", "available memory", "bytes", int, meter
@@ -101,8 +108,9 @@ def test_finished_collection_stateless(self):
101108
self.assertEqual(len(processor._batch_map), 0)
102109

103110
def test_finished_collection_stateful(self):
104-
meter = metrics.MeterProvider().get_meter(__name__)
105-
processor = Processor(True)
111+
meter_provider = metrics.MeterProvider()
112+
meter = meter_provider.get_meter(__name__)
113+
processor = Processor(True, meter_provider.resource)
106114
aggregator = SumAggregator()
107115
metric = metrics.Counter(
108116
"available memory", "available memory", "bytes", int, meter
@@ -116,8 +124,9 @@ def test_finished_collection_stateful(self):
116124
self.assertEqual(len(processor._batch_map), 1)
117125

118126
def test_processor_process_exists(self):
119-
meter = metrics.MeterProvider().get_meter(__name__)
120-
processor = Processor(True)
127+
meter_provider = metrics.MeterProvider()
128+
meter = meter_provider.get_meter(__name__)
129+
processor = Processor(True, meter_provider.resource)
121130
aggregator = SumAggregator()
122131
aggregator2 = SumAggregator()
123132
metric = metrics.Counter(
@@ -137,8 +146,9 @@ def test_processor_process_exists(self):
137146
self.assertEqual(processor._batch_map.get(batch_key).checkpoint, 1.0)
138147

139148
def test_processor_process_not_exists(self):
140-
meter = metrics.MeterProvider().get_meter(__name__)
141-
processor = Processor(True)
149+
meter_provider = metrics.MeterProvider()
150+
meter = meter_provider.get_meter(__name__)
151+
processor = Processor(True, meter_provider.resource)
142152
aggregator = SumAggregator()
143153
metric = metrics.Counter(
144154
"available memory", "available memory", "bytes", int, meter
@@ -156,11 +166,15 @@ def test_processor_process_not_exists(self):
156166
self.assertEqual(processor._batch_map.get(batch_key).checkpoint, 1.0)
157167

158168
def test_processor_process_not_stateful(self):
159-
meter = metrics.MeterProvider().get_meter(__name__)
160-
processor = Processor(True)
169+
meter_provider = metrics.MeterProvider()
170+
processor = Processor(True, meter_provider.resource)
161171
aggregator = SumAggregator()
162172
metric = metrics.Counter(
163-
"available memory", "available memory", "bytes", int, meter
173+
"available memory",
174+
"available memory",
175+
"bytes",
176+
int,
177+
meter_provider.get_meter(__name__),
164178
)
165179
labels = ()
166180
_batch_map = {}

0 commit comments

Comments
 (0)