Skip to content

Commit

Permalink
nits
Browse files Browse the repository at this point in the history
  • Loading branch information
cnnradams committed Aug 7, 2020
1 parent b158e59 commit e4e8c20
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 43 deletions.
1 change: 1 addition & 0 deletions docs/examples/exemplars/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ and they may focus on measurements with abnormally high/low values.
.. literalinclude:: trace_exemplars.py
:language: python
:lines: 1-

Currently only the Google Cloud Monitoring exporter supports uploading these exemplars.
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def __init__(self, config=None):
self.config = config
else:
self.config = {}
self.checkpoint_exemplars = list()
self.checkpoint_exemplars = []

@abc.abstractmethod
def update(self, value, dropped_labels=None):
Expand Down
65 changes: 23 additions & 42 deletions opentelemetry-sdk/src/opentelemetry/sdk/metrics/export/exemplars.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Exemplars are sample data points for aggregators. For more information, see the `spec <https://github.com/open-telemetry/oteps/pull/113>`_
"""Exemplars are sample data points for aggregators. For more information, see the `spec <https://github.com/open-telemetry/oteps/pull/113>`_
Every synchronous aggregator is instrumented with two exemplar recorders:
1. A "trace" exemplar sampler, which only samples exemplars if they have a sampled trace context (and can pick exemplars with other biases, ie min + max).
2. A "statistical" exemplar sampler, which samples exemplars without bias (ie no preferenced for traced exemplars)
Every synchronous aggregator is instrumented with two exemplar recorders:
1. A "trace" exemplar sampler, which only samples exemplars if they have a sampled trace context (and can pick exemplars with other biases, ie min + max).
2. A "statistical" exemplar sampler, which samples exemplars without bias (ie no preferenced for traced exemplars)
To use an exemplar recorder, pass in two arguments to the aggregator config in views (see the :ref:`Exemplars` example for an example):
"num_exemplars": The number of exemplars to record (if applicable, in each bucket). Note that in non-statistical mode the recorder may not use "num_exemplars"
"statistical_exemplars": If exemplars should be recorded statistically
To use an exemplar recorder, pass in two arguments to the aggregator config in views (see the :ref:`Exemplars` example for an example):
"num_exemplars": The number of exemplars to record (if applicable, in each bucket). Note that in non-statistical mode the recorder may not use "num_exemplars"
"statistical_exemplars": If exemplars should be recorded statistically
For exemplars to be recorded, `num_exemplars` must be greater than 0.
For exemplars to be recorded, `num_exemplars` must be greater than 0.
"""

import abc
import itertools
import random
from typing import List, Optional, Tuple, Union
from typing import List, Optional, Tuple, Type, Union

from opentelemetry.context import get_current
from opentelemetry.util import time_ns
Expand Down Expand Up @@ -95,7 +94,8 @@ def sample_count(self):
"""For statistical exemplars, how many measurements a single exemplar represents"""
return self._sample_count

def set_sample_count(self, count: float):
@sample_count.setter
def sample_count(self, count: float):
self._sample_count = count


Expand All @@ -122,11 +122,14 @@ def sample_set(self):
Return the list of exemplars that have been sampled
"""

@abc.abstractmethod
def merge(self, set1: List[Exemplar], set2: List[Exemplar]):
"""
Given two lists of sampled exemplars, merge them while maintaining the invariants specified by this sampler
Assume that set2 is the latest set of exemplars.
For simplicity, we will just keep set2 and assume set1 has already been exported.
This may need to change with a different SDK implementation.
"""
#pylint: disable=unused-argument,no-self-use
return set2

@abc.abstractmethod
def reset(self):
Expand Down Expand Up @@ -162,14 +165,6 @@ def sample(self, exemplar: Exemplar, **kwargs):
if replace_index < self._k:
self._sample_set[replace_index] = exemplar

def merge(self, set1: List[Exemplar], set2: List[Exemplar]):
"""
Assume that set2 is the latest set of exemplars.
For simplicity, we will just keep set2 and assume set1 has already been exported.
This may need to change with a different SDK implementation.
"""
return set2

@property
def sample_set(self):
if self._statistical:
Expand Down Expand Up @@ -212,14 +207,6 @@ def sample(self, exemplar: Exemplar, **kwargs):
def sample_set(self):
return self._sample_set

def merge(self, set1: List[Exemplar], set2: List[Exemplar]):
"""
Assume that set2 is the latest set of exemplars.
For simplicity, we will just keep set2 and assume set1 has already been exported.
This may need to change with a different SDK implementation.
"""
return set2

def reset(self):
self._sample_set = []

Expand All @@ -233,7 +220,7 @@ class BucketedExemplarSampler(ExemplarSampler):
"""

def __init__(
self, k: int, statistical: bool = False, boundaries: list = None
self, k: int, statistical: bool = False, boundaries: List[float] = None
):
super().__init__(k)
self._boundaries = boundaries
Expand All @@ -242,7 +229,9 @@ def __init__(
for _ in range(len(self._boundaries) + 1)
]

def sample(self, exemplar: Exemplar, **kwargs):
def sample(
self, exemplar: Exemplar, **kwargs
):
bucket_index = kwargs.get("bucket_index")
if bucket_index is None:
return
Expand All @@ -253,18 +242,10 @@ def sample(self, exemplar: Exemplar, **kwargs):
def sample_set(self):
return list(
itertools.chain.from_iterable(
[sampler.sample_set for sampler in self._sample_set]
sampler.sample_set for sampler in self._sample_set
)
)

def merge(self, set1: List[Exemplar], set2: List[Exemplar]):
"""
Assume that set2 is the latest set of exemplars.
For simplicity, we will just keep set2 and assume set1 has already been exported.
This may need to change with a different SDK implementation.
"""
return set2

def reset(self):
for sampler in self._sample_set:
sampler.reset()
Expand All @@ -280,8 +261,8 @@ class ExemplarManager:
def __init__(
self,
config: dict,
default_exemplar_sampler: ExemplarSampler,
statistical_exemplar_sampler: ExemplarSampler,
default_exemplar_sampler: Type[ExemplarSampler],
statistical_exemplar_sampler: Type[ExemplarSampler],
**kwargs
):
if config:
Expand Down

0 comments on commit e4e8c20

Please sign in to comment.