Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fb11568

Browse files
authored
Metrics API with RFC 0003 (open-telemetry#87)
* Create functions Comments for Meter More comments Add more comments Fix typos * fix lint * Fix lint * fix typing * Remove options, constructors, seperate labels * Consistent naming for float and int * Abstract time series * Use ABC * Fix typo * Fix docs * seperate measure classes * Add examples * fix lint * Update to RFC 0003 * Add spancontext, measurebatch * Fix docs * Fix comments * fix lint * fix lint * fix lint * skip examples * white space * fix spacing * fix imports * fix imports * LabelValues to str * Black formatting * fix isort * Remove aggregation * Fix names * Remove aggregation from docs * Fix lint
1 parent 5ca9e06 commit fb11568

File tree

7 files changed

+444
-0
lines changed

7 files changed

+444
-0
lines changed

docs/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ abstract types for OpenTelemetry implementations.
1717

1818
opentelemetry.context
1919
opentelemetry.loader
20+
opentelemetry.metrics
2021
opentelemetry.trace
2122

2223

docs/opentelemetry.metrics.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
opentelemetry.metrics package
2+
=============================
3+
4+
Submodules
5+
----------
6+
7+
.. toctree::
8+
9+
opentelemetry.metrics.time_series
10+
11+
Module contents
12+
---------------
13+
14+
.. automodule:: opentelemetry.metrics
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
opentelemetry.metrics.time\_series module
2+
==========================================
3+
4+
.. automodule:: opentelemetry.metrics.time_series
5+

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

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,307 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
15+
"""
16+
The OpenTelemetry metrics API describes the classes used to report raw
17+
measurements, as well as metrics with known aggregation and labels.
18+
19+
The `Meter` class is used to construct `Metric` s to record raw statistics
20+
as well as metrics with predefined aggregation.
21+
22+
See the `metrics api`_ spec for terminology and context clarification.
23+
24+
.. _metrics api:
25+
https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/api-metrics.md
26+
27+
28+
"""
29+
30+
from abc import ABC, abstractmethod
31+
from typing import List
32+
33+
from opentelemetry.metrics.time_series import (
34+
CounterTimeSeries,
35+
GaugeTimeSeries,
36+
MeasureTimeSeries,
37+
)
38+
from opentelemetry.trace import SpanContext
39+
40+
LabelKeys = List["LabelKey"]
41+
LabelValues = List[str]
42+
43+
44+
class Meter:
45+
"""An interface to allow the recording of metrics.
46+
47+
`Metric` s are used for recording pre-defined aggregation (gauge and
48+
counter), or raw values (measure) in which the aggregation and labels
49+
for the exported metric are deferred.
50+
"""
51+
52+
def create_float_counter(
53+
self,
54+
name: str,
55+
description: str,
56+
unit: str,
57+
label_keys: LabelKeys,
58+
span_context: SpanContext = None,
59+
) -> "FloatCounter":
60+
"""Creates a counter type metric that contains float values.
61+
62+
Args:
63+
name: The name of the counter.
64+
description: Human readable description of the metric.
65+
unit: Unit of the metric values.
66+
label_keys: list of keys for the labels with dynamic values.
67+
Order of the list is important as the same order MUST be used
68+
on recording when suppling values for these labels.
69+
span_context: The `SpanContext` that identifies the `Span`
70+
that the metric is associated with.
71+
72+
Returns: A new `FloatCounter`
73+
"""
74+
75+
def create_int_counter(
76+
self,
77+
name: str,
78+
description: str,
79+
unit: str,
80+
label_keys: LabelKeys,
81+
span_context: SpanContext = None,
82+
) -> "IntCounter":
83+
"""Creates a counter type metric that contains int values.
84+
85+
Args:
86+
name: The name of the counter.
87+
description: Human readable description of the metric.
88+
unit: Unit of the metric values.
89+
label_keys: list of keys for the labels with dynamic values.
90+
Order of the list is important as the same order MUST be used
91+
on recording when suppling values for these labels.
92+
span_context: The `SpanContext` that identifies the `Span`
93+
that the metric is associated with.
94+
95+
Returns:
96+
A new `IntCounter`
97+
"""
98+
99+
def create_float_gauge(
100+
self,
101+
name: str,
102+
description: str,
103+
unit: str,
104+
label_keys: LabelKeys,
105+
span_context: SpanContext = None,
106+
) -> "FloatGauge":
107+
"""Creates a gauge type metric that contains float values.
108+
109+
Args:
110+
name: The name of the counter.
111+
description: Human readable description of the metric.
112+
unit: Unit of the metric values.
113+
label_keys: list of keys for the labels with dynamic values.
114+
Order of the list is important as the same order MUST be used
115+
on recording when suppling values for these labels.
116+
span_context: The `SpanContext` that identifies the `Span`
117+
that the metric is associated with.
118+
119+
Returns:
120+
A new `FloatGauge`
121+
"""
122+
123+
def create_int_gauge(
124+
self,
125+
name: str,
126+
description: str,
127+
unit: str,
128+
label_keys: LabelKeys,
129+
span_context: SpanContext = None,
130+
) -> "IntGauge":
131+
"""Creates a gauge type metric that contains int values.
132+
133+
Args:
134+
name: The name of the counter.
135+
description: Human readable description of the metric.
136+
unit: Unit of the metric values.
137+
label_keys: list of keys for the labels with dynamic values.
138+
Order of the list is important as the same order MUST be used
139+
on recording when suppling values for these labels.
140+
span_context: The `SpanContext` that identifies the `Span`
141+
that the metric is associated with.
142+
143+
Returns:
144+
A new `IntGauge`
145+
"""
146+
147+
def create_int_measure(
148+
self,
149+
name: str,
150+
description: str,
151+
unit: str,
152+
label_keys: LabelKeys,
153+
span_context: SpanContext = None,
154+
) -> "IntMeasure":
155+
"""Creates a measure used to record raw int values.
156+
157+
Args:
158+
name: The name of the measure.
159+
description: Human readable description of this measure.
160+
unit: Unit of the measure values.
161+
label_keys: list of keys for the labels with dynamic values.
162+
Order of the list is important as the same order MUST be used
163+
on recording when suppling values for these labels.
164+
span_context: The `SpanContext` that identifies the `Span`
165+
that the metric is associated with.
166+
167+
Returns:
168+
A new `IntMeasure`
169+
"""
170+
171+
def create_float_measure(
172+
self,
173+
name: str,
174+
description: str,
175+
unit: str,
176+
label_keys: LabelKeys,
177+
span_context: SpanContext = None,
178+
) -> "FloatMeasure":
179+
"""Creates a Measure used to record raw float values.
180+
181+
Args:
182+
name: the name of the measure
183+
description: Human readable description of this measure.
184+
unit: Unit of the measure values.
185+
label_keys: list of keys for the labels with dynamic values.
186+
Order of the list is important as the same order MUST be used
187+
on recording when suppling values for these labels.
188+
span_context: The `SpanContext` that identifies the `Span`
189+
that the metric is associated with.
190+
191+
Returns:
192+
A new `FloatMeasure`
193+
"""
194+
195+
196+
class Metric(ABC):
197+
"""Base class for various types of metrics.
198+
199+
Metric class that inherit from this class are specialized with the type of
200+
time series that the metric holds. Metric is constructed from the meter.
201+
"""
202+
203+
@abstractmethod
204+
def get_or_create_time_series(self, label_values: LabelValues) -> "object":
205+
"""Gets and returns a timeseries, a container for a cumulative value.
206+
207+
If the provided label values are not already associated with this
208+
metric, a new timeseries is returned, otherwise it returns the existing
209+
timeseries with the exact label values. The timeseries returned
210+
contains logic and behaviour specific to the type of metric that
211+
overrides this function.
212+
213+
Args:
214+
label_values: A list of label values that will be associated
215+
with the return timeseries.
216+
"""
217+
218+
def remove_time_series(self, label_values: LabelValues) -> None:
219+
"""Removes the timeseries from the Metric, if present.
220+
221+
The timeseries with matching label values will be removed.
222+
223+
args:
224+
label_values: The list of label values to match against.
225+
"""
226+
227+
def clear(self) -> None:
228+
"""Removes all timeseries from the `Metric`."""
229+
230+
231+
class FloatCounter(Metric):
232+
"""A counter type metric that holds float values.
233+
234+
Cumulative values can go up or stay the same, but can never go down.
235+
Cumulative values cannot be negative.
236+
"""
237+
238+
def get_or_create_time_series(
239+
self, label_values: LabelValues
240+
) -> "CounterTimeSeries":
241+
"""Gets a `CounterTimeSeries` with a cumulative float value."""
242+
243+
244+
class IntCounter(Metric):
245+
"""A counter type metric that holds int values.
246+
247+
Cumulative values can go up or stay the same, but can never go down.
248+
Cumulative values cannot be negative.
249+
"""
250+
251+
def get_or_create_time_series(
252+
self, label_values: LabelValues
253+
) -> "CounterTimeSeries":
254+
"""Gets a `CounterTimeSeries` with a cumulative int value."""
255+
256+
257+
class FloatGauge(Metric):
258+
"""A gauge type metric that holds float values.
259+
260+
Cumulative value can go both up and down. Values can be negative.
261+
"""
262+
263+
def get_or_create_time_series(
264+
self, label_values: LabelValues
265+
) -> "GaugeTimeSeries":
266+
"""Gets a `GaugeTimeSeries` with a cumulative float value."""
267+
268+
269+
class IntGauge(Metric):
270+
"""A gauge type metric that holds int values.
271+
272+
Cumulative value can go both up and down. Values can be negative.
273+
"""
274+
275+
def get_or_create_time_series(
276+
self, label_values: LabelValues
277+
) -> "GaugeTimeSeries":
278+
"""Gets a `GaugeTimeSeries` with a cumulative int value."""
279+
280+
281+
class FloatMeasure(Metric):
282+
"""A measure type metric that holds float values.
283+
284+
Measure metrics represent raw statistics that are recorded.
285+
"""
286+
287+
def get_or_create_time_series(
288+
self, label_values: LabelValues
289+
) -> "MeasureTimeSeries":
290+
"""Gets a `MeasureTimeSeries` with a cumulated float value."""
291+
292+
293+
class IntMeasure(Metric):
294+
"""A measure type metric that holds int values.
295+
296+
Measure metrics represent raw statistics that are recorded.
297+
"""
298+
299+
def get_or_create_time_series(
300+
self, label_values: LabelValues
301+
) -> "MeasureTimeSeries":
302+
"""Gets a `MeasureTimeSeries` with a cumulated int value."""
303+
304+
305+
class LabelKey:
306+
"""The label keys associated with the metric.
307+
308+
:type key: str
309+
:param key: the key for the label
310+
311+
:type description: str
312+
:param description: description of the label
313+
"""
314+
315+
def __init__(self, key: str, description: str) -> None:
316+
self.key = key
317+
self.description = description
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Copyright 2019, OpenTelemetry Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# pylint: skip-file
16+
from opentelemetry.metrics import LabelKey, LabelValue, Meter
17+
18+
METER = Meter()
19+
LABEL_KEYS = [
20+
LabelKey("environment", "the environment the application is running in")
21+
]
22+
COUNTER = METER.create_int_counter(
23+
"sum numbers", # pragma: no cover
24+
"sum numbers over time",
25+
"number",
26+
LABEL_KEYS,
27+
)
28+
LABEL_VALUE_TESTING = [LabelValue("Testing")]
29+
LABEL_VALUE_STAGING = [LabelValue("Staging")]
30+
31+
# Metrics sent to some exporter
32+
METRIC_TESTING = COUNTER.get_or_create_time_series(LABEL_VALUE_TESTING)
33+
METRIC_STAGING = COUNTER.get_or_create_time_series(LABEL_VALUE_STAGING)
34+
35+
for i in range(100):
36+
METRIC_STAGING.add(i)

0 commit comments

Comments
 (0)