Add files using upload-large-folder tool
Browse filesThis view is limited to 50 files because it contains too many changes.
See raw diff
- .venv/lib/python3.11/site-packages/opencensus/__init__.py +1 -0
- .venv/lib/python3.11/site-packages/opencensus/log/__init__.py +115 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__init__.py +13 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/aggregation.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/aggregation_data.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/base_exporter.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/bucket_boundaries.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/execution_context.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measure.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measure_to_view_map.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measurement.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measurement_map.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/metric_utils.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/stats.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/stats_recorder.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/view.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/view_data.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/view_manager.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/aggregation.py +144 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/aggregation_data.py +399 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/base_exporter.py +42 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/bucket_boundaries.py +41 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/execution_context.py +32 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/measure.py +60 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/measure_to_view_map.py +163 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/measurement.py +50 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/measurement_map.py +118 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/metric_utils.py +79 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/stats.py +43 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/stats_recorder.py +34 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/view.py +106 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/view_data.py +96 -0
- .venv/lib/python3.11/site-packages/opencensus/stats/view_manager.py +55 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/__init__.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/pem.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc1901.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc2876.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc2985.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3058.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3274.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3280.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3560.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3565.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3709.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3739.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3852.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc4010.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc4108.cpython-311.pyc +0 -0
- .venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc4211.cpython-311.pyc +0 -0
.venv/lib/python3.11/site-packages/opencensus/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__path__ = __import__('pkgutil').extend_path(__path__, __name__)
|
.venv/lib/python3.11/site-packages/opencensus/log/__init__.py
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2019, OpenCensus 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 |
+
import logging
|
| 16 |
+
from collections import namedtuple
|
| 17 |
+
from copy import copy
|
| 18 |
+
|
| 19 |
+
from opencensus.trace import execution_context
|
| 20 |
+
|
| 21 |
+
_meta_logger = logging.getLogger(__name__)
|
| 22 |
+
|
| 23 |
+
TRACE_ID_KEY = 'traceId'
|
| 24 |
+
SPAN_ID_KEY = 'spanId'
|
| 25 |
+
SAMPLING_DECISION_KEY = 'traceSampled'
|
| 26 |
+
|
| 27 |
+
LogAttrs = namedtuple('LogAttrs', ['trace_id', 'span_id', 'sampling_decision'])
|
| 28 |
+
ATTR_DEFAULTS = LogAttrs("00000000000000000000000000000000",
|
| 29 |
+
"0000000000000000", False)
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def get_log_attrs():
|
| 33 |
+
"""Get logging attributes from the opencensus context.
|
| 34 |
+
|
| 35 |
+
:rtype: :class:`LogAttrs`
|
| 36 |
+
:return: The current span's trace ID, span ID, and sampling decision.
|
| 37 |
+
"""
|
| 38 |
+
try:
|
| 39 |
+
tracer = execution_context.get_opencensus_tracer()
|
| 40 |
+
if tracer is None:
|
| 41 |
+
raise RuntimeError
|
| 42 |
+
except Exception: # noqa
|
| 43 |
+
_meta_logger.error("Failed to get opencensus tracer")
|
| 44 |
+
return ATTR_DEFAULTS
|
| 45 |
+
|
| 46 |
+
try:
|
| 47 |
+
trace_id = tracer.span_context.trace_id
|
| 48 |
+
if trace_id is None:
|
| 49 |
+
trace_id = ATTR_DEFAULTS.trace_id
|
| 50 |
+
except Exception: # noqa
|
| 51 |
+
_meta_logger.error("Failed to get opencensus trace ID")
|
| 52 |
+
trace_id = ATTR_DEFAULTS.trace_id
|
| 53 |
+
|
| 54 |
+
try:
|
| 55 |
+
span_id = tracer.span_context.span_id
|
| 56 |
+
if span_id is None:
|
| 57 |
+
span_id = ATTR_DEFAULTS.span_id
|
| 58 |
+
except Exception: # noqa
|
| 59 |
+
_meta_logger.error("Failed to get opencensus span ID")
|
| 60 |
+
span_id = ATTR_DEFAULTS.span_id
|
| 61 |
+
|
| 62 |
+
try:
|
| 63 |
+
sampling_decision = tracer.span_context.trace_options.get_enabled()
|
| 64 |
+
if sampling_decision is None:
|
| 65 |
+
sampling_decision = ATTR_DEFAULTS.sampling_decision
|
| 66 |
+
except AttributeError:
|
| 67 |
+
sampling_decision = ATTR_DEFAULTS.sampling_decision
|
| 68 |
+
except Exception: # noqa
|
| 69 |
+
_meta_logger.error("Failed to get opencensus sampling decision")
|
| 70 |
+
sampling_decision = ATTR_DEFAULTS.sampling_decision
|
| 71 |
+
|
| 72 |
+
return LogAttrs(trace_id, span_id, sampling_decision)
|
| 73 |
+
|
| 74 |
+
|
| 75 |
+
def _set_extra_attrs(extra):
|
| 76 |
+
trace_id, span_id, sampling_decision = get_log_attrs()
|
| 77 |
+
extra.setdefault(TRACE_ID_KEY, trace_id)
|
| 78 |
+
extra.setdefault(SPAN_ID_KEY, span_id)
|
| 79 |
+
extra.setdefault(SAMPLING_DECISION_KEY, sampling_decision)
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
# See
|
| 83 |
+
# https://docs.python.org/3.7/library/logging.html#loggeradapter-objects,
|
| 84 |
+
# https://docs.python.org/3.7/howto/logging-cookbook.html#context-info
|
| 85 |
+
class TraceLoggingAdapter(logging.LoggerAdapter):
|
| 86 |
+
"""Adapter to add opencensus context attrs to records."""
|
| 87 |
+
def process(self, msg, kwargs):
|
| 88 |
+
kwargs = copy(kwargs)
|
| 89 |
+
if self.extra:
|
| 90 |
+
extra = copy(self.extra)
|
| 91 |
+
else:
|
| 92 |
+
extra = {}
|
| 93 |
+
extra.update(kwargs.get('extra', {}))
|
| 94 |
+
_set_extra_attrs(extra)
|
| 95 |
+
kwargs['extra'] = extra
|
| 96 |
+
|
| 97 |
+
return (msg, kwargs)
|
| 98 |
+
|
| 99 |
+
|
| 100 |
+
# This is the idiomatic way to stack logger customizations, see
|
| 101 |
+
# https://docs.python.org/3.7/library/logging.html#logging.getLoggerClass
|
| 102 |
+
class TraceLogger(logging.getLoggerClass()):
|
| 103 |
+
"""Logger class that adds opencensus context attrs to records."""
|
| 104 |
+
def makeRecord(self, *args, **kwargs):
|
| 105 |
+
try:
|
| 106 |
+
extra = args[8]
|
| 107 |
+
if extra is None:
|
| 108 |
+
extra = {}
|
| 109 |
+
args = tuple(list(args[:8]) + [extra] + list(args[9:]))
|
| 110 |
+
except IndexError: # pragma: NO COVER
|
| 111 |
+
extra = kwargs.setdefault('extra', {})
|
| 112 |
+
if extra is None:
|
| 113 |
+
kwargs['extra'] = extra
|
| 114 |
+
_set_extra_attrs(extra)
|
| 115 |
+
return super(TraceLogger, self).makeRecord(*args, **kwargs)
|
.venv/lib/python3.11/site-packages/opencensus/stats/__init__.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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.
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (189 Bytes). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/aggregation.cpython-311.pyc
ADDED
|
Binary file (6.98 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/aggregation_data.cpython-311.pyc
ADDED
|
Binary file (19.2 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/base_exporter.cpython-311.pyc
ADDED
|
Binary file (1.52 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/bucket_boundaries.cpython-311.pyc
ADDED
|
Binary file (1.45 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/execution_context.cpython-311.pyc
ADDED
|
Binary file (1.07 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measure.cpython-311.pyc
ADDED
|
Binary file (2.92 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measure_to_view_map.cpython-311.pyc
ADDED
|
Binary file (7.68 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measurement.cpython-311.pyc
ADDED
|
Binary file (2.53 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/measurement_map.cpython-311.pyc
ADDED
|
Binary file (5.36 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/metric_utils.cpython-311.pyc
ADDED
|
Binary file (3.15 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/stats.cpython-311.pyc
ADDED
|
Binary file (1.76 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/stats_recorder.cpython-311.pyc
ADDED
|
Binary file (1.58 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/view.cpython-311.pyc
ADDED
|
Binary file (4.39 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/view_data.cpython-311.pyc
ADDED
|
Binary file (4.01 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/__pycache__/view_manager.cpython-311.pyc
ADDED
|
Binary file (3.05 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/opencensus/stats/aggregation.py
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
import logging
|
| 16 |
+
|
| 17 |
+
from opencensus.metrics.export.metric_descriptor import MetricDescriptorType
|
| 18 |
+
from opencensus.stats import aggregation_data
|
| 19 |
+
from opencensus.stats import measure as measure_module
|
| 20 |
+
|
| 21 |
+
logger = logging.getLogger(__name__)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class SumAggregation(object):
|
| 25 |
+
"""Sum Aggregation describes that data collected and aggregated with this
|
| 26 |
+
method will be summed
|
| 27 |
+
|
| 28 |
+
:type sum: int or float
|
| 29 |
+
:param sum: the initial sum to be used in the aggregation
|
| 30 |
+
|
| 31 |
+
"""
|
| 32 |
+
def __init__(self, sum=None):
|
| 33 |
+
self._initial_sum = sum or 0
|
| 34 |
+
|
| 35 |
+
def new_aggregation_data(self, measure):
|
| 36 |
+
"""Get a new AggregationData for this aggregation."""
|
| 37 |
+
value_type = MetricDescriptorType.to_type_class(
|
| 38 |
+
self.get_metric_type(measure))
|
| 39 |
+
return aggregation_data.SumAggregationData(
|
| 40 |
+
value_type=value_type, sum_data=self._initial_sum)
|
| 41 |
+
|
| 42 |
+
@staticmethod
|
| 43 |
+
def get_metric_type(measure):
|
| 44 |
+
"""Get the MetricDescriptorType for the metric produced by this
|
| 45 |
+
aggregation and measure.
|
| 46 |
+
"""
|
| 47 |
+
if isinstance(measure, measure_module.MeasureInt):
|
| 48 |
+
return MetricDescriptorType.CUMULATIVE_INT64
|
| 49 |
+
if isinstance(measure, measure_module.MeasureFloat):
|
| 50 |
+
return MetricDescriptorType.CUMULATIVE_DOUBLE
|
| 51 |
+
raise ValueError
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
class CountAggregation(object):
|
| 55 |
+
"""Describes that the data collected and aggregated with this method will
|
| 56 |
+
be turned into a count value
|
| 57 |
+
|
| 58 |
+
:type count: int
|
| 59 |
+
:param count: the initial count to be used in the aggregation
|
| 60 |
+
|
| 61 |
+
"""
|
| 62 |
+
def __init__(self, count=0):
|
| 63 |
+
self._initial_count = count
|
| 64 |
+
|
| 65 |
+
def new_aggregation_data(self, measure=None):
|
| 66 |
+
"""Get a new AggregationData for this aggregation."""
|
| 67 |
+
return aggregation_data.CountAggregationData(self._initial_count)
|
| 68 |
+
|
| 69 |
+
@staticmethod
|
| 70 |
+
def get_metric_type(measure):
|
| 71 |
+
"""Get the MetricDescriptorType for the metric produced by this
|
| 72 |
+
aggregation and measure.
|
| 73 |
+
"""
|
| 74 |
+
return MetricDescriptorType.CUMULATIVE_INT64
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
class DistributionAggregation(object):
|
| 78 |
+
"""Distribution Aggregation indicates that the desired aggregation is a
|
| 79 |
+
histogram distribution
|
| 80 |
+
|
| 81 |
+
:type boundaries: list(:class:'~opencensus.stats.bucket_boundaries.
|
| 82 |
+
BucketBoundaries')
|
| 83 |
+
:param boundaries: the bucket endpoints
|
| 84 |
+
|
| 85 |
+
"""
|
| 86 |
+
|
| 87 |
+
def __init__(self, boundaries=None):
|
| 88 |
+
if boundaries:
|
| 89 |
+
if not all(boundaries[ii] < boundaries[ii + 1]
|
| 90 |
+
for ii in range(len(boundaries) - 1)):
|
| 91 |
+
raise ValueError("bounds must be sorted in increasing order")
|
| 92 |
+
for ii, bb in enumerate(boundaries):
|
| 93 |
+
if bb > 0:
|
| 94 |
+
break
|
| 95 |
+
else:
|
| 96 |
+
ii += 1
|
| 97 |
+
if ii:
|
| 98 |
+
logger.warning("Dropping %s non-positive bucket boundaries",
|
| 99 |
+
ii)
|
| 100 |
+
boundaries = boundaries[ii:]
|
| 101 |
+
|
| 102 |
+
self._boundaries = boundaries
|
| 103 |
+
|
| 104 |
+
def new_aggregation_data(self, measure=None):
|
| 105 |
+
"""Get a new AggregationData for this aggregation."""
|
| 106 |
+
return aggregation_data.DistributionAggregationData(
|
| 107 |
+
0, 0, 0, None, self._boundaries)
|
| 108 |
+
|
| 109 |
+
@staticmethod
|
| 110 |
+
def get_metric_type(measure):
|
| 111 |
+
"""Get the MetricDescriptorType for the metric produced by this
|
| 112 |
+
aggregation and measure.
|
| 113 |
+
"""
|
| 114 |
+
return MetricDescriptorType.CUMULATIVE_DISTRIBUTION
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
class LastValueAggregation(object):
|
| 118 |
+
"""Describes that the data collected with this method will
|
| 119 |
+
overwrite the last recorded value
|
| 120 |
+
|
| 121 |
+
:type value: long
|
| 122 |
+
:param count: the initial value to be used in the aggregation
|
| 123 |
+
|
| 124 |
+
"""
|
| 125 |
+
def __init__(self, value=0):
|
| 126 |
+
self._initial_value = value
|
| 127 |
+
|
| 128 |
+
def new_aggregation_data(self, measure):
|
| 129 |
+
"""Get a new AggregationData for this aggregation."""
|
| 130 |
+
value_type = MetricDescriptorType.to_type_class(
|
| 131 |
+
self.get_metric_type(measure))
|
| 132 |
+
return aggregation_data.LastValueAggregationData(
|
| 133 |
+
value=self._initial_value, value_type=value_type)
|
| 134 |
+
|
| 135 |
+
@staticmethod
|
| 136 |
+
def get_metric_type(measure):
|
| 137 |
+
"""Get the MetricDescriptorType for the metric produced by this
|
| 138 |
+
aggregation and measure.
|
| 139 |
+
"""
|
| 140 |
+
if isinstance(measure, measure_module.MeasureInt):
|
| 141 |
+
return MetricDescriptorType.GAUGE_INT64
|
| 142 |
+
if isinstance(measure, measure_module.MeasureFloat):
|
| 143 |
+
return MetricDescriptorType.GAUGE_DOUBLE
|
| 144 |
+
raise ValueError
|
.venv/lib/python3.11/site-packages/opencensus/stats/aggregation_data.py
ADDED
|
@@ -0,0 +1,399 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
import copy
|
| 16 |
+
import logging
|
| 17 |
+
|
| 18 |
+
from opencensus.metrics.export import point, value
|
| 19 |
+
from opencensus.stats import bucket_boundaries
|
| 20 |
+
|
| 21 |
+
logger = logging.getLogger(__name__)
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
class SumAggregationData(object):
|
| 25 |
+
"""Sum Aggregation Data is the aggregated data for the Sum aggregation
|
| 26 |
+
|
| 27 |
+
:type value_type: class that is either
|
| 28 |
+
:class:`opencensus.metrics.export.value.ValueDouble` or
|
| 29 |
+
:class:`opencensus.metrics.export.value.ValueLong`
|
| 30 |
+
:param value_type: the type of value to be used when creating a point
|
| 31 |
+
:type sum_data: int or float
|
| 32 |
+
:param sum_data: represents the initial aggregated sum
|
| 33 |
+
|
| 34 |
+
"""
|
| 35 |
+
|
| 36 |
+
def __init__(self, value_type, sum_data):
|
| 37 |
+
self._value_type = value_type
|
| 38 |
+
self._sum_data = sum_data
|
| 39 |
+
|
| 40 |
+
def __repr__(self):
|
| 41 |
+
return ("{}({})"
|
| 42 |
+
.format(
|
| 43 |
+
type(self).__name__,
|
| 44 |
+
self.sum_data,
|
| 45 |
+
))
|
| 46 |
+
|
| 47 |
+
def add_sample(self, value, timestamp=None, attachments=None):
|
| 48 |
+
"""Allows the user to add a sample to the Sum Aggregation Data
|
| 49 |
+
The value of the sample is then added to the current sum data
|
| 50 |
+
"""
|
| 51 |
+
self._sum_data += value
|
| 52 |
+
|
| 53 |
+
@property
|
| 54 |
+
def sum_data(self):
|
| 55 |
+
"""The current sum data"""
|
| 56 |
+
return self._sum_data
|
| 57 |
+
|
| 58 |
+
@property
|
| 59 |
+
def value_type(self):
|
| 60 |
+
"""The value type to use when creating the point"""
|
| 61 |
+
return self._value_type
|
| 62 |
+
|
| 63 |
+
def to_point(self, timestamp):
|
| 64 |
+
"""Get a Point conversion of this aggregation.
|
| 65 |
+
|
| 66 |
+
:type timestamp: :class: `datetime.datetime`
|
| 67 |
+
:param timestamp: The time to report the point as having been recorded.
|
| 68 |
+
|
| 69 |
+
:rtype: :class: `opencensus.metrics.export.point.Point`
|
| 70 |
+
:return: a Point with value equal to `sum_data` and of type
|
| 71 |
+
`_value_type`.
|
| 72 |
+
"""
|
| 73 |
+
return point.Point(self._value_type(self.sum_data), timestamp)
|
| 74 |
+
|
| 75 |
+
|
| 76 |
+
class CountAggregationData(object):
|
| 77 |
+
"""Count Aggregation Data is the count value of aggregated data
|
| 78 |
+
|
| 79 |
+
:type count_data: long
|
| 80 |
+
:param count_data: represents the initial aggregated count
|
| 81 |
+
|
| 82 |
+
"""
|
| 83 |
+
|
| 84 |
+
def __init__(self, count_data):
|
| 85 |
+
self._count_data = count_data
|
| 86 |
+
|
| 87 |
+
def __repr__(self):
|
| 88 |
+
return ("{}({})"
|
| 89 |
+
.format(
|
| 90 |
+
type(self).__name__,
|
| 91 |
+
self.count_data,
|
| 92 |
+
))
|
| 93 |
+
|
| 94 |
+
def add_sample(self, value, timestamp=None, attachments=None):
|
| 95 |
+
"""Adds a sample to the current Count Aggregation Data and adds 1 to
|
| 96 |
+
the count data"""
|
| 97 |
+
self._count_data = self._count_data + 1
|
| 98 |
+
|
| 99 |
+
@property
|
| 100 |
+
def count_data(self):
|
| 101 |
+
"""The current count data"""
|
| 102 |
+
return self._count_data
|
| 103 |
+
|
| 104 |
+
def to_point(self, timestamp):
|
| 105 |
+
"""Get a Point conversion of this aggregation.
|
| 106 |
+
|
| 107 |
+
:type timestamp: :class: `datetime.datetime`
|
| 108 |
+
:param timestamp: The time to report the point as having been recorded.
|
| 109 |
+
|
| 110 |
+
:rtype: :class: `opencensus.metrics.export.point.Point`
|
| 111 |
+
:return: a :class: `opencensus.metrics.export.value.ValueLong`-valued
|
| 112 |
+
Point with value equal to `count_data`.
|
| 113 |
+
"""
|
| 114 |
+
return point.Point(value.ValueLong(self.count_data), timestamp)
|
| 115 |
+
|
| 116 |
+
|
| 117 |
+
class DistributionAggregationData(object):
|
| 118 |
+
"""Distribution Aggregation Data refers to the distribution stats of
|
| 119 |
+
aggregated data
|
| 120 |
+
|
| 121 |
+
:type mean_data: float
|
| 122 |
+
:param mean_data: the mean value of the distribution
|
| 123 |
+
|
| 124 |
+
:type count_data: int
|
| 125 |
+
:param count_data: the count value of the distribution
|
| 126 |
+
|
| 127 |
+
:type sum_of_sqd_deviations: float
|
| 128 |
+
:param sum_of_sqd_deviations: the sum of the sqd deviations from the mean
|
| 129 |
+
|
| 130 |
+
:type counts_per_bucket: list(int)
|
| 131 |
+
:param counts_per_bucket: the number of occurrences per bucket
|
| 132 |
+
|
| 133 |
+
:type exemplars: list(Exemplar)
|
| 134 |
+
:param: exemplars: the exemplars associated with histogram buckets.
|
| 135 |
+
|
| 136 |
+
:type bounds: list(float)
|
| 137 |
+
:param bounds: the histogram distribution of the values
|
| 138 |
+
|
| 139 |
+
"""
|
| 140 |
+
|
| 141 |
+
def __init__(self,
|
| 142 |
+
mean_data,
|
| 143 |
+
count_data,
|
| 144 |
+
sum_of_sqd_deviations,
|
| 145 |
+
counts_per_bucket=None,
|
| 146 |
+
bounds=None,
|
| 147 |
+
exemplars=None):
|
| 148 |
+
if bounds is None and exemplars is not None:
|
| 149 |
+
raise ValueError
|
| 150 |
+
if exemplars is not None and len(exemplars) != len(bounds) + 1:
|
| 151 |
+
raise ValueError
|
| 152 |
+
|
| 153 |
+
self._mean_data = mean_data
|
| 154 |
+
self._count_data = count_data
|
| 155 |
+
self._sum_of_sqd_deviations = sum_of_sqd_deviations
|
| 156 |
+
|
| 157 |
+
if bounds is None:
|
| 158 |
+
bounds = []
|
| 159 |
+
self._exemplars = None
|
| 160 |
+
else:
|
| 161 |
+
assert bounds == list(sorted(set(bounds)))
|
| 162 |
+
assert all(bb > 0 for bb in bounds)
|
| 163 |
+
if exemplars is None:
|
| 164 |
+
self._exemplars = {ii: None for ii in range(len(bounds) + 1)}
|
| 165 |
+
else:
|
| 166 |
+
self._exemplars = {ii: ex for ii, ex in enumerate(exemplars)}
|
| 167 |
+
self._bounds = (bucket_boundaries.BucketBoundaries(boundaries=bounds)
|
| 168 |
+
.boundaries)
|
| 169 |
+
|
| 170 |
+
if counts_per_bucket is None:
|
| 171 |
+
counts_per_bucket = [0 for ii in range(len(bounds) + 1)]
|
| 172 |
+
else:
|
| 173 |
+
assert all(cc >= 0 for cc in counts_per_bucket)
|
| 174 |
+
assert len(counts_per_bucket) == len(bounds) + 1
|
| 175 |
+
self._counts_per_bucket = counts_per_bucket
|
| 176 |
+
|
| 177 |
+
def __repr__(self):
|
| 178 |
+
return ("{}({})"
|
| 179 |
+
.format(
|
| 180 |
+
type(self).__name__,
|
| 181 |
+
self.count_data,
|
| 182 |
+
))
|
| 183 |
+
|
| 184 |
+
@property
|
| 185 |
+
def mean_data(self):
|
| 186 |
+
"""The current mean data"""
|
| 187 |
+
return self._mean_data
|
| 188 |
+
|
| 189 |
+
@property
|
| 190 |
+
def count_data(self):
|
| 191 |
+
"""The current count data"""
|
| 192 |
+
return self._count_data
|
| 193 |
+
|
| 194 |
+
@property
|
| 195 |
+
def sum_of_sqd_deviations(self):
|
| 196 |
+
"""The current sum of squared deviations from the mean"""
|
| 197 |
+
return self._sum_of_sqd_deviations
|
| 198 |
+
|
| 199 |
+
@property
|
| 200 |
+
def counts_per_bucket(self):
|
| 201 |
+
"""The current counts per bucket for the distribution"""
|
| 202 |
+
return self._counts_per_bucket
|
| 203 |
+
|
| 204 |
+
@property
|
| 205 |
+
def exemplars(self):
|
| 206 |
+
"""The current counts per bucket for the distribution"""
|
| 207 |
+
return self._exemplars
|
| 208 |
+
|
| 209 |
+
@property
|
| 210 |
+
def bounds(self):
|
| 211 |
+
"""The current bounds for the distribution"""
|
| 212 |
+
return self._bounds
|
| 213 |
+
|
| 214 |
+
@property
|
| 215 |
+
def sum(self):
|
| 216 |
+
"""The sum of the current distribution"""
|
| 217 |
+
return self._mean_data * self._count_data
|
| 218 |
+
|
| 219 |
+
@property
|
| 220 |
+
def variance(self):
|
| 221 |
+
"""The variance of the current distribution"""
|
| 222 |
+
if self._count_data <= 1:
|
| 223 |
+
return 0
|
| 224 |
+
return self.sum_of_sqd_deviations / (self._count_data - 1)
|
| 225 |
+
|
| 226 |
+
def add_sample(self, value, timestamp, attachments):
|
| 227 |
+
"""Adding a sample to Distribution Aggregation Data"""
|
| 228 |
+
self._count_data += 1
|
| 229 |
+
bucket = self.increment_bucket_count(value)
|
| 230 |
+
|
| 231 |
+
if attachments is not None and self.exemplars is not None:
|
| 232 |
+
self.exemplars[bucket] = Exemplar(value, timestamp, attachments)
|
| 233 |
+
if self.count_data == 1:
|
| 234 |
+
self._mean_data = value
|
| 235 |
+
return
|
| 236 |
+
|
| 237 |
+
old_mean = self._mean_data
|
| 238 |
+
self._mean_data = self._mean_data + (
|
| 239 |
+
(value - self._mean_data) / self._count_data)
|
| 240 |
+
self._sum_of_sqd_deviations = self._sum_of_sqd_deviations + (
|
| 241 |
+
(value - old_mean) * (value - self._mean_data))
|
| 242 |
+
|
| 243 |
+
def increment_bucket_count(self, value):
|
| 244 |
+
"""Increment the bucket count based on a given value from the user"""
|
| 245 |
+
if len(self._bounds) == 0:
|
| 246 |
+
self._counts_per_bucket[0] += 1
|
| 247 |
+
return 0
|
| 248 |
+
|
| 249 |
+
for ii, bb in enumerate(self._bounds):
|
| 250 |
+
if value < bb:
|
| 251 |
+
self._counts_per_bucket[ii] += 1
|
| 252 |
+
return ii
|
| 253 |
+
else:
|
| 254 |
+
last_bucket_index = len(self._bounds)
|
| 255 |
+
self._counts_per_bucket[last_bucket_index] += 1
|
| 256 |
+
return last_bucket_index
|
| 257 |
+
|
| 258 |
+
def to_point(self, timestamp):
|
| 259 |
+
"""Get a Point conversion of this aggregation.
|
| 260 |
+
|
| 261 |
+
This method creates a :class: `opencensus.metrics.export.point.Point`
|
| 262 |
+
with a :class: `opencensus.metrics.export.value.ValueDistribution`
|
| 263 |
+
value, and creates buckets and exemplars for that distribution from the
|
| 264 |
+
appropriate classes in the `metrics` package. If the distribution
|
| 265 |
+
doesn't have a histogram (i.e. `bounds` is empty) the converted point's
|
| 266 |
+
`buckets` attribute will be null.
|
| 267 |
+
|
| 268 |
+
:type timestamp: :class: `datetime.datetime`
|
| 269 |
+
:param timestamp: The time to report the point as having been recorded.
|
| 270 |
+
|
| 271 |
+
:rtype: :class: `opencensus.metrics.export.point.Point`
|
| 272 |
+
:return: a :class: `opencensus.metrics.export.value.ValueDistribution`
|
| 273 |
+
-valued Point.
|
| 274 |
+
"""
|
| 275 |
+
if self.bounds:
|
| 276 |
+
bucket_options = value.BucketOptions(value.Explicit(self.bounds))
|
| 277 |
+
buckets = [None] * len(self.counts_per_bucket)
|
| 278 |
+
for ii, count in enumerate(self.counts_per_bucket):
|
| 279 |
+
stat_ex = self.exemplars.get(ii) if self.exemplars else None
|
| 280 |
+
if stat_ex is not None:
|
| 281 |
+
metric_ex = value.Exemplar(stat_ex.value,
|
| 282 |
+
stat_ex.timestamp,
|
| 283 |
+
copy.copy(stat_ex.attachments))
|
| 284 |
+
buckets[ii] = value.Bucket(count, metric_ex)
|
| 285 |
+
else:
|
| 286 |
+
buckets[ii] = value.Bucket(count)
|
| 287 |
+
|
| 288 |
+
else:
|
| 289 |
+
bucket_options = value.BucketOptions()
|
| 290 |
+
buckets = None
|
| 291 |
+
return point.Point(
|
| 292 |
+
value.ValueDistribution(
|
| 293 |
+
count=self.count_data,
|
| 294 |
+
sum_=self.sum,
|
| 295 |
+
sum_of_squared_deviation=self.sum_of_sqd_deviations,
|
| 296 |
+
bucket_options=bucket_options,
|
| 297 |
+
buckets=buckets
|
| 298 |
+
),
|
| 299 |
+
timestamp
|
| 300 |
+
)
|
| 301 |
+
|
| 302 |
+
|
| 303 |
+
class LastValueAggregationData(object):
|
| 304 |
+
"""
|
| 305 |
+
LastValue Aggregation Data is the value of aggregated data
|
| 306 |
+
|
| 307 |
+
:type value_type: class that is either
|
| 308 |
+
:class:`opencensus.metrics.export.value.ValueDouble` or
|
| 309 |
+
:class:`opencensus.metrics.export.value.ValueLong`
|
| 310 |
+
:param value_type: the type of value to be used when creating a point
|
| 311 |
+
:type value: long
|
| 312 |
+
:param value: represents the initial value
|
| 313 |
+
|
| 314 |
+
"""
|
| 315 |
+
|
| 316 |
+
def __init__(self, value_type, value):
|
| 317 |
+
self._value_type = value_type
|
| 318 |
+
self._value = value
|
| 319 |
+
|
| 320 |
+
def __repr__(self):
|
| 321 |
+
return ("{}({})"
|
| 322 |
+
.format(
|
| 323 |
+
type(self).__name__,
|
| 324 |
+
self.value,
|
| 325 |
+
))
|
| 326 |
+
|
| 327 |
+
def add_sample(self, value, timestamp=None, attachments=None):
|
| 328 |
+
"""Adds a sample to the current
|
| 329 |
+
LastValue Aggregation Data and overwrite
|
| 330 |
+
the current recorded value"""
|
| 331 |
+
self._value = value
|
| 332 |
+
|
| 333 |
+
@property
|
| 334 |
+
def value(self):
|
| 335 |
+
"""The current value recorded"""
|
| 336 |
+
return self._value
|
| 337 |
+
|
| 338 |
+
@property
|
| 339 |
+
def value_type(self):
|
| 340 |
+
"""The value type to use when creating the point"""
|
| 341 |
+
return self._value_type
|
| 342 |
+
|
| 343 |
+
def to_point(self, timestamp):
|
| 344 |
+
"""Get a Point conversion of this aggregation.
|
| 345 |
+
|
| 346 |
+
:type timestamp: :class: `datetime.datetime`
|
| 347 |
+
:param timestamp: The time to report the point as having been recorded.
|
| 348 |
+
|
| 349 |
+
:rtype: :class: `opencensus.metrics.export.point.Point`
|
| 350 |
+
:return: a Point with value of type `_value_type`.
|
| 351 |
+
"""
|
| 352 |
+
return point.Point(self._value_type(self.value), timestamp)
|
| 353 |
+
|
| 354 |
+
|
| 355 |
+
class Exemplar(object):
|
| 356 |
+
""" Exemplar represents an example point that may be used to annotate
|
| 357 |
+
aggregated distribution values, associated with a histogram bucket.
|
| 358 |
+
|
| 359 |
+
:type value: double
|
| 360 |
+
:param value: value of the Exemplar point.
|
| 361 |
+
|
| 362 |
+
:type timestamp: time
|
| 363 |
+
:param timestamp: the time that this Exemplar's value was recorded.
|
| 364 |
+
|
| 365 |
+
:type attachments: dict
|
| 366 |
+
:param attachments: the contextual information about the example value.
|
| 367 |
+
"""
|
| 368 |
+
|
| 369 |
+
def __init__(self, value, timestamp, attachments):
|
| 370 |
+
self._value = value
|
| 371 |
+
|
| 372 |
+
self._timestamp = timestamp
|
| 373 |
+
|
| 374 |
+
if attachments is None:
|
| 375 |
+
raise TypeError('attachments should not be empty')
|
| 376 |
+
|
| 377 |
+
for key, value in attachments.items():
|
| 378 |
+
if key is None or not isinstance(key, str):
|
| 379 |
+
raise TypeError('attachment key should not be '
|
| 380 |
+
'empty and should be a string')
|
| 381 |
+
if value is None or not isinstance(value, str):
|
| 382 |
+
raise TypeError('attachment value should not be '
|
| 383 |
+
'empty and should be a string')
|
| 384 |
+
self._attachments = attachments
|
| 385 |
+
|
| 386 |
+
@property
|
| 387 |
+
def value(self):
|
| 388 |
+
"""The current value of the Exemplar point"""
|
| 389 |
+
return self._value
|
| 390 |
+
|
| 391 |
+
@property
|
| 392 |
+
def timestamp(self):
|
| 393 |
+
"""The time that this Exemplar's value was recorded"""
|
| 394 |
+
return self._timestamp
|
| 395 |
+
|
| 396 |
+
@property
|
| 397 |
+
def attachments(self):
|
| 398 |
+
"""The contextual information about the example value"""
|
| 399 |
+
return self._attachments
|
.venv/lib/python3.11/site-packages/opencensus/stats/base_exporter.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
"""Module containing base class for exporters."""
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class StatsExporter(object):
|
| 19 |
+
"""Base class for opencensus stats exporters.
|
| 20 |
+
|
| 21 |
+
Subclasses of :class:`Exporter` must override :meth:`export`.
|
| 22 |
+
"""
|
| 23 |
+
|
| 24 |
+
def on_register_view(self, view):
|
| 25 |
+
"""
|
| 26 |
+
:type view: object of :class:
|
| 27 |
+
`~opencensus.stats.view.View`
|
| 28 |
+
:param object of opencensus.stats.view.View view:
|
| 29 |
+
View object to register
|
| 30 |
+
"""
|
| 31 |
+
raise NotImplementedError # pragma: NO COVER
|
| 32 |
+
|
| 33 |
+
def emit(self, view_datas):
|
| 34 |
+
"""Send view and measurement to exporter record method,
|
| 35 |
+
and then it will record on its own way.
|
| 36 |
+
|
| 37 |
+
:type view_datas: object of :class:
|
| 38 |
+
`~opencensus.stats.view_data.ViewData`
|
| 39 |
+
:param list of opencensus.stats.view_data.ViewData ViewData:
|
| 40 |
+
list of ViewData object to send to Stackdriver Monitoring
|
| 41 |
+
"""
|
| 42 |
+
raise NotImplementedError # pragma: NO COVER
|
.venv/lib/python3.11/site-packages/opencensus/stats/bucket_boundaries.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
|
| 16 |
+
class BucketBoundaries(object):
|
| 17 |
+
"""The bucket boundaries for a histogram
|
| 18 |
+
|
| 19 |
+
:type boundaries: list(float)
|
| 20 |
+
:param boundaries: boundaries for the buckets in the underlying histogram
|
| 21 |
+
|
| 22 |
+
"""
|
| 23 |
+
def __init__(self, boundaries=None):
|
| 24 |
+
self._boundaries = list(boundaries or [])
|
| 25 |
+
|
| 26 |
+
@property
|
| 27 |
+
def boundaries(self):
|
| 28 |
+
"""the current boundaries"""
|
| 29 |
+
return self._boundaries
|
| 30 |
+
|
| 31 |
+
def is_valid_boundaries(self, boundaries):
|
| 32 |
+
"""checks if the boundaries are in ascending order"""
|
| 33 |
+
if boundaries is not None:
|
| 34 |
+
min_ = boundaries[0]
|
| 35 |
+
for value in boundaries:
|
| 36 |
+
if value < min_:
|
| 37 |
+
return False
|
| 38 |
+
else:
|
| 39 |
+
min_ = value
|
| 40 |
+
return True
|
| 41 |
+
return False
|
.venv/lib/python3.11/site-packages/opencensus/stats/execution_context.py
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
from opencensus.common.runtime_context import RuntimeContext
|
| 16 |
+
|
| 17 |
+
_measure_to_view_map_slot = RuntimeContext.register_slot(
|
| 18 |
+
'measure_to_view_map',
|
| 19 |
+
lambda: {})
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def get_measure_to_view_map():
|
| 23 |
+
return RuntimeContext.measure_to_view_map
|
| 24 |
+
|
| 25 |
+
|
| 26 |
+
def set_measure_to_view_map(measure_to_view_map):
|
| 27 |
+
RuntimeContext.measure_to_view_map = measure_to_view_map
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def clear():
|
| 31 |
+
"""Clear the context, used in test."""
|
| 32 |
+
_measure_to_view_map_slot.clear()
|
.venv/lib/python3.11/site-packages/opencensus/stats/measure.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
|
| 16 |
+
class BaseMeasure(object):
|
| 17 |
+
""" A measure is the type of metric that is being recorded with
|
| 18 |
+
a name, description, and unit
|
| 19 |
+
|
| 20 |
+
:type name: str
|
| 21 |
+
:param name: string representing the name of the measure
|
| 22 |
+
|
| 23 |
+
:type description: str
|
| 24 |
+
:param description: a string representing the description of the measure
|
| 25 |
+
|
| 26 |
+
:type unit: str
|
| 27 |
+
:param unit: the units in which the measure values are measured
|
| 28 |
+
|
| 29 |
+
"""
|
| 30 |
+
def __init__(self, name, description, unit=None):
|
| 31 |
+
self._name = name
|
| 32 |
+
self._description = description
|
| 33 |
+
self._unit = unit
|
| 34 |
+
|
| 35 |
+
@property
|
| 36 |
+
def name(self):
|
| 37 |
+
"""The name of the current measure"""
|
| 38 |
+
return self._name
|
| 39 |
+
|
| 40 |
+
@property
|
| 41 |
+
def description(self):
|
| 42 |
+
"""The description of the current measure"""
|
| 43 |
+
return self._description
|
| 44 |
+
|
| 45 |
+
@property
|
| 46 |
+
def unit(self):
|
| 47 |
+
"""The unit of the current measure"""
|
| 48 |
+
return self._unit
|
| 49 |
+
|
| 50 |
+
|
| 51 |
+
class MeasureInt(BaseMeasure):
|
| 52 |
+
"""Creates an Integer Measure"""
|
| 53 |
+
def __init__(self, name, description, unit=None):
|
| 54 |
+
super(MeasureInt, self).__init__(name, description, unit)
|
| 55 |
+
|
| 56 |
+
|
| 57 |
+
class MeasureFloat(BaseMeasure):
|
| 58 |
+
"""Creates a Float Measure"""
|
| 59 |
+
def __init__(self, name, description, unit=None):
|
| 60 |
+
super(MeasureFloat, self).__init__(name, description, unit)
|
.venv/lib/python3.11/site-packages/opencensus/stats/measure_to_view_map.py
ADDED
|
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
import copy
|
| 16 |
+
import logging
|
| 17 |
+
from collections import defaultdict
|
| 18 |
+
|
| 19 |
+
from opencensus.stats import metric_utils
|
| 20 |
+
from opencensus.stats import view_data as view_data_module
|
| 21 |
+
|
| 22 |
+
logger = logging.getLogger(__name__)
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
class MeasureToViewMap(object):
|
| 26 |
+
"""Measure To View Map stores a map from names of Measures to
|
| 27 |
+
specific View Datas
|
| 28 |
+
|
| 29 |
+
"""
|
| 30 |
+
|
| 31 |
+
def __init__(self):
|
| 32 |
+
# stores the one-to-many mapping from Measures to View Datas
|
| 33 |
+
self._measure_to_view_data_list_map = defaultdict(list)
|
| 34 |
+
# stores a map from the registered View names to the Views
|
| 35 |
+
self._registered_views = {}
|
| 36 |
+
# stores a map from the registered Measure names to the Measures
|
| 37 |
+
self._registered_measures = {}
|
| 38 |
+
# stores the set of the exported views
|
| 39 |
+
self._exported_views = set()
|
| 40 |
+
# Stores the registered exporters
|
| 41 |
+
self._exporters = []
|
| 42 |
+
|
| 43 |
+
@property
|
| 44 |
+
def exported_views(self):
|
| 45 |
+
"""the current exported views"""
|
| 46 |
+
return self._exported_views
|
| 47 |
+
|
| 48 |
+
@property
|
| 49 |
+
def exporters(self):
|
| 50 |
+
"""registered exporters"""
|
| 51 |
+
return self._exporters
|
| 52 |
+
|
| 53 |
+
def get_view(self, view_name, timestamp):
|
| 54 |
+
"""get the View Data from the given View name"""
|
| 55 |
+
view = self._registered_views.get(view_name)
|
| 56 |
+
if view is None:
|
| 57 |
+
return None
|
| 58 |
+
|
| 59 |
+
view_data_list = self._measure_to_view_data_list_map.get(
|
| 60 |
+
view.measure.name)
|
| 61 |
+
|
| 62 |
+
if not view_data_list:
|
| 63 |
+
return None
|
| 64 |
+
|
| 65 |
+
for view_data in view_data_list:
|
| 66 |
+
if view_data.view.name == view_name:
|
| 67 |
+
break
|
| 68 |
+
else:
|
| 69 |
+
return None
|
| 70 |
+
|
| 71 |
+
return self.copy_and_finalize_view_data(view_data)
|
| 72 |
+
|
| 73 |
+
def filter_exported_views(self, all_views):
|
| 74 |
+
"""returns the subset of the given view that should be exported"""
|
| 75 |
+
views = set(all_views)
|
| 76 |
+
return views
|
| 77 |
+
|
| 78 |
+
# TODO: deprecate
|
| 79 |
+
def register_view(self, view, timestamp):
|
| 80 |
+
"""registers the view's measure name to View Datas given a view"""
|
| 81 |
+
if len(self.exporters) > 0:
|
| 82 |
+
try:
|
| 83 |
+
for e in self.exporters:
|
| 84 |
+
e.on_register_view(view)
|
| 85 |
+
except AttributeError:
|
| 86 |
+
pass
|
| 87 |
+
|
| 88 |
+
self._exported_views = None
|
| 89 |
+
existing_view = self._registered_views.get(view.name)
|
| 90 |
+
if existing_view is not None:
|
| 91 |
+
if existing_view == view:
|
| 92 |
+
# ignore the views that are already registered
|
| 93 |
+
return
|
| 94 |
+
else:
|
| 95 |
+
logger.warning(
|
| 96 |
+
"A different view with the same name is already registered"
|
| 97 |
+
) # pragma: NO COVER
|
| 98 |
+
measure = view.measure
|
| 99 |
+
registered_measure = self._registered_measures.get(measure.name)
|
| 100 |
+
if registered_measure is not None and registered_measure != measure:
|
| 101 |
+
logger.warning(
|
| 102 |
+
"A different measure with the same name is already registered")
|
| 103 |
+
self._registered_views[view.name] = view
|
| 104 |
+
if registered_measure is None:
|
| 105 |
+
self._registered_measures[measure.name] = measure
|
| 106 |
+
self._measure_to_view_data_list_map[view.measure.name].append(
|
| 107 |
+
view_data_module.ViewData(view=view, start_time=timestamp,
|
| 108 |
+
end_time=timestamp))
|
| 109 |
+
|
| 110 |
+
def record(self, tags, measurement_map, timestamp, attachments=None):
|
| 111 |
+
"""records stats with a set of tags"""
|
| 112 |
+
assert all(vv >= 0 for vv in measurement_map.values())
|
| 113 |
+
for measure, value in measurement_map.items():
|
| 114 |
+
if measure != self._registered_measures.get(measure.name):
|
| 115 |
+
return
|
| 116 |
+
view_datas = []
|
| 117 |
+
for measure_name, view_data_list \
|
| 118 |
+
in self._measure_to_view_data_list_map.items():
|
| 119 |
+
if measure_name == measure.name:
|
| 120 |
+
view_datas.extend(view_data_list)
|
| 121 |
+
for view_data in view_datas:
|
| 122 |
+
view_data.record(
|
| 123 |
+
context=tags, value=value, timestamp=timestamp,
|
| 124 |
+
attachments=attachments)
|
| 125 |
+
self.export(view_datas)
|
| 126 |
+
|
| 127 |
+
# TODO: deprecate
|
| 128 |
+
def export(self, view_datas):
|
| 129 |
+
"""export view datas to registered exporters"""
|
| 130 |
+
view_datas_copy = \
|
| 131 |
+
[self.copy_and_finalize_view_data(vd) for vd in view_datas]
|
| 132 |
+
if len(self.exporters) > 0:
|
| 133 |
+
for e in self.exporters:
|
| 134 |
+
try:
|
| 135 |
+
e.export(view_datas_copy)
|
| 136 |
+
except AttributeError:
|
| 137 |
+
pass
|
| 138 |
+
|
| 139 |
+
def get_metrics(self, timestamp):
|
| 140 |
+
"""Get a Metric for each registered view.
|
| 141 |
+
|
| 142 |
+
Convert each registered view's associated `ViewData` into a `Metric` to
|
| 143 |
+
be exported.
|
| 144 |
+
|
| 145 |
+
:type timestamp: :class: `datetime.datetime`
|
| 146 |
+
:param timestamp: The timestamp to use for metric conversions, usually
|
| 147 |
+
the current time.
|
| 148 |
+
|
| 149 |
+
:rtype: Iterator[:class: `opencensus.metrics.export.metric.Metric`]
|
| 150 |
+
"""
|
| 151 |
+
for vdl in self._measure_to_view_data_list_map.values():
|
| 152 |
+
for vd in vdl:
|
| 153 |
+
metric = metric_utils.view_data_to_metric(vd, timestamp)
|
| 154 |
+
if metric is not None:
|
| 155 |
+
yield metric
|
| 156 |
+
|
| 157 |
+
# TODO(issue #470): remove this method once we export immutable stats.
|
| 158 |
+
def copy_and_finalize_view_data(self, view_data):
|
| 159 |
+
view_data_copy = copy.copy(view_data)
|
| 160 |
+
tvdam_copy = copy.deepcopy(view_data.tag_value_aggregation_data_map)
|
| 161 |
+
view_data_copy._tag_value_aggregation_data_map = tvdam_copy
|
| 162 |
+
view_data_copy.end()
|
| 163 |
+
return view_data_copy
|
.venv/lib/python3.11/site-packages/opencensus/stats/measurement.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
|
| 16 |
+
class Measurement(object):
|
| 17 |
+
""" A measurement is an object with a measure and a value attached to it
|
| 18 |
+
|
| 19 |
+
:type measure: :class: '~opencensus.stats.measure.Measure'
|
| 20 |
+
:param measure: A measure to pass into the measurement
|
| 21 |
+
|
| 22 |
+
:type value: int or float
|
| 23 |
+
:param value: value of the measurement
|
| 24 |
+
|
| 25 |
+
"""
|
| 26 |
+
def __init__(self, measure, value):
|
| 27 |
+
self._measure = measure
|
| 28 |
+
self._value = value
|
| 29 |
+
|
| 30 |
+
@property
|
| 31 |
+
def value(self):
|
| 32 |
+
"""The value of the current measurement"""
|
| 33 |
+
return self._value
|
| 34 |
+
|
| 35 |
+
@property
|
| 36 |
+
def measure(self):
|
| 37 |
+
"""The measure of the current measurement"""
|
| 38 |
+
return self._measure
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
class MeasurementInt(Measurement):
|
| 42 |
+
""" Creates a new Integer Measurement """
|
| 43 |
+
def __init__(self, measure, value):
|
| 44 |
+
super(MeasurementInt, self).__init__(measure, value)
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
class MeasurementFloat(Measurement):
|
| 48 |
+
""" Creates a new Float Measurement """
|
| 49 |
+
def __init__(self, measure, value):
|
| 50 |
+
super(MeasurementFloat, self).__init__(measure, value)
|
.venv/lib/python3.11/site-packages/opencensus/stats/measurement_map.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
import logging
|
| 16 |
+
|
| 17 |
+
from opencensus.common import utils
|
| 18 |
+
from opencensus.tags import TagContext
|
| 19 |
+
|
| 20 |
+
logger = logging.getLogger(__name__)
|
| 21 |
+
|
| 22 |
+
|
| 23 |
+
class MeasurementMap(object):
|
| 24 |
+
"""Measurement Map is a map from Measures to measured values
|
| 25 |
+
to be recorded at the same time
|
| 26 |
+
|
| 27 |
+
:type measure_to_view_map: :class: '~opencensus.stats.measure_to_view_map.
|
| 28 |
+
MeasureToViewMap'
|
| 29 |
+
:param measure_to_view_map: the measure to view map that will store the
|
| 30 |
+
recorded stats with tags
|
| 31 |
+
|
| 32 |
+
:type: attachments: dict
|
| 33 |
+
:param attachments: the contextual information about the attachment value.
|
| 34 |
+
|
| 35 |
+
"""
|
| 36 |
+
def __init__(self, measure_to_view_map, attachments=None):
|
| 37 |
+
self._measurement_map = {}
|
| 38 |
+
self._measure_to_view_map = measure_to_view_map
|
| 39 |
+
self._attachments = attachments
|
| 40 |
+
# If the user tries to record a negative value for any measurement,
|
| 41 |
+
# refuse to record all measurements from this map. Recording negative
|
| 42 |
+
# measurements will become an error in a later release.
|
| 43 |
+
self._invalid = False
|
| 44 |
+
|
| 45 |
+
@property
|
| 46 |
+
def measurement_map(self):
|
| 47 |
+
"""the current measurement map"""
|
| 48 |
+
return self._measurement_map
|
| 49 |
+
|
| 50 |
+
@property
|
| 51 |
+
def measure_to_view_map(self):
|
| 52 |
+
"""the current measure to view map for the measurement map"""
|
| 53 |
+
return self._measure_to_view_map
|
| 54 |
+
|
| 55 |
+
@property
|
| 56 |
+
def attachments(self):
|
| 57 |
+
"""the current contextual information about the attachment value."""
|
| 58 |
+
return self._attachments
|
| 59 |
+
|
| 60 |
+
def measure_int_put(self, measure, value):
|
| 61 |
+
"""associates the measure of type Int with the given value"""
|
| 62 |
+
if value < 0:
|
| 63 |
+
# Should be an error in a later release.
|
| 64 |
+
logger.warning("Cannot record negative values")
|
| 65 |
+
self._measurement_map[measure] = value
|
| 66 |
+
|
| 67 |
+
def measure_float_put(self, measure, value):
|
| 68 |
+
"""associates the measure of type Float with the given value"""
|
| 69 |
+
if value < 0:
|
| 70 |
+
# Should be an error in a later release.
|
| 71 |
+
logger.warning("Cannot record negative values")
|
| 72 |
+
self._measurement_map[measure] = value
|
| 73 |
+
|
| 74 |
+
def measure_put_attachment(self, key, value):
|
| 75 |
+
"""Associate the contextual information of an Exemplar to this MeasureMap
|
| 76 |
+
Contextual information is represented as key - value string pairs.
|
| 77 |
+
If this method is called multiple times with the same key,
|
| 78 |
+
only the last value will be kept.
|
| 79 |
+
"""
|
| 80 |
+
if self._attachments is None:
|
| 81 |
+
self._attachments = dict()
|
| 82 |
+
|
| 83 |
+
if key is None or not isinstance(key, str):
|
| 84 |
+
raise TypeError('attachment key should not be '
|
| 85 |
+
'empty and should be a string')
|
| 86 |
+
if value is None or not isinstance(value, str):
|
| 87 |
+
raise TypeError('attachment value should not be '
|
| 88 |
+
'empty and should be a string')
|
| 89 |
+
|
| 90 |
+
self._attachments[key] = value
|
| 91 |
+
|
| 92 |
+
def record(self, tags=None):
|
| 93 |
+
"""records all the measures at the same time with a tag_map.
|
| 94 |
+
tag_map could either be explicitly passed to the method, or implicitly
|
| 95 |
+
read from current runtime context.
|
| 96 |
+
"""
|
| 97 |
+
if tags is None:
|
| 98 |
+
tags = TagContext.get()
|
| 99 |
+
if self._invalid:
|
| 100 |
+
logger.warning("Measurement map has included negative value "
|
| 101 |
+
"measurements, refusing to record")
|
| 102 |
+
return
|
| 103 |
+
for measure, value in self.measurement_map.items():
|
| 104 |
+
if value < 0:
|
| 105 |
+
self._invalid = True
|
| 106 |
+
logger.warning("Dropping values, value to record must be "
|
| 107 |
+
"non-negative")
|
| 108 |
+
logger.info("Measure '{}' has negative value ({}), refusing "
|
| 109 |
+
"to record measurements from {}"
|
| 110 |
+
.format(measure.name, value, self))
|
| 111 |
+
return
|
| 112 |
+
|
| 113 |
+
self.measure_to_view_map.record(
|
| 114 |
+
tags=tags,
|
| 115 |
+
measurement_map=self.measurement_map,
|
| 116 |
+
timestamp=utils.to_iso_str(),
|
| 117 |
+
attachments=self.attachments
|
| 118 |
+
)
|
.venv/lib/python3.11/site-packages/opencensus/stats/metric_utils.py
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
Utilities to convert stats data models to metrics data models.
|
| 16 |
+
"""
|
| 17 |
+
|
| 18 |
+
from opencensus.metrics import label_value
|
| 19 |
+
from opencensus.metrics.export import metric, metric_descriptor, time_series
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
def is_gauge(md_type):
|
| 23 |
+
"""Whether a given MetricDescriptorType value is a gauge.
|
| 24 |
+
|
| 25 |
+
:type md_type: int
|
| 26 |
+
:param md_type: A MetricDescriptorType enum value.
|
| 27 |
+
"""
|
| 28 |
+
if md_type not in metric_descriptor.MetricDescriptorType:
|
| 29 |
+
raise ValueError # pragma: NO COVER
|
| 30 |
+
|
| 31 |
+
return md_type in {
|
| 32 |
+
metric_descriptor.MetricDescriptorType.GAUGE_INT64,
|
| 33 |
+
metric_descriptor.MetricDescriptorType.GAUGE_DOUBLE,
|
| 34 |
+
metric_descriptor.MetricDescriptorType.GAUGE_DISTRIBUTION
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def get_label_values(tag_values):
|
| 39 |
+
"""Convert an iterable of TagValues into a list of LabelValues.
|
| 40 |
+
|
| 41 |
+
:type tag_values: list(:class: `opencensus.tags.tag_value.TagValue`)
|
| 42 |
+
:param tag_values: An iterable of TagValues to convert.
|
| 43 |
+
|
| 44 |
+
:rtype: list(:class: `opencensus.metrics.label_value.LabelValue`)
|
| 45 |
+
:return: A list of LabelValues, converted from TagValues.
|
| 46 |
+
"""
|
| 47 |
+
return [label_value.LabelValue(tv) for tv in tag_values]
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def view_data_to_metric(view_data, timestamp):
|
| 51 |
+
"""Convert a ViewData to a Metric at time `timestamp`.
|
| 52 |
+
|
| 53 |
+
:type view_data: :class: `opencensus.stats.view_data.ViewData`
|
| 54 |
+
:param view_data: The ViewData to convert.
|
| 55 |
+
|
| 56 |
+
:type timestamp: :class: `datetime.datetime`
|
| 57 |
+
:param timestamp: The time to set on the metric's point's aggregation,
|
| 58 |
+
usually the current time.
|
| 59 |
+
|
| 60 |
+
:rtype: :class: `opencensus.metrics.export.metric.Metric`
|
| 61 |
+
:return: A converted Metric.
|
| 62 |
+
"""
|
| 63 |
+
if not view_data.tag_value_aggregation_data_map:
|
| 64 |
+
return None
|
| 65 |
+
|
| 66 |
+
md = view_data.view.get_metric_descriptor()
|
| 67 |
+
|
| 68 |
+
# TODO: implement gauges
|
| 69 |
+
if is_gauge(md.type):
|
| 70 |
+
ts_start = None # pragma: NO COVER
|
| 71 |
+
else:
|
| 72 |
+
ts_start = view_data.start_time
|
| 73 |
+
|
| 74 |
+
ts_list = []
|
| 75 |
+
for tag_vals, agg_data in view_data.tag_value_aggregation_data_map.items():
|
| 76 |
+
label_values = get_label_values(tag_vals)
|
| 77 |
+
point = agg_data.to_point(timestamp)
|
| 78 |
+
ts_list.append(time_series.TimeSeries(label_values, [point], ts_start))
|
| 79 |
+
return metric.Metric(md, ts_list)
|
.venv/lib/python3.11/site-packages/opencensus/stats/stats.py
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
from datetime import datetime
|
| 16 |
+
|
| 17 |
+
from opencensus.metrics.export.metric_producer import MetricProducer
|
| 18 |
+
from opencensus.stats.stats_recorder import StatsRecorder
|
| 19 |
+
from opencensus.stats.view_manager import ViewManager
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class _Stats(MetricProducer):
|
| 23 |
+
"""Stats defines a View Manager and a Stats Recorder in order for the
|
| 24 |
+
collection of Stats
|
| 25 |
+
"""
|
| 26 |
+
|
| 27 |
+
def __init__(self):
|
| 28 |
+
self.stats_recorder = StatsRecorder()
|
| 29 |
+
self.view_manager = ViewManager()
|
| 30 |
+
|
| 31 |
+
def get_metrics(self):
|
| 32 |
+
"""Get a Metric for each of the view manager's registered views.
|
| 33 |
+
|
| 34 |
+
Convert each registered view's associated `ViewData` into a `Metric` to
|
| 35 |
+
be exported, using the current time for metric conversions.
|
| 36 |
+
|
| 37 |
+
:rtype: Iterator[:class: `opencensus.metrics.export.metric.Metric`]
|
| 38 |
+
"""
|
| 39 |
+
return self.view_manager.measure_to_view_map.get_metrics(
|
| 40 |
+
datetime.utcnow())
|
| 41 |
+
|
| 42 |
+
|
| 43 |
+
stats = _Stats()
|
.venv/lib/python3.11/site-packages/opencensus/stats/stats_recorder.py
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
from opencensus.stats import execution_context
|
| 16 |
+
from opencensus.stats.measure_to_view_map import MeasureToViewMap
|
| 17 |
+
from opencensus.stats.measurement_map import MeasurementMap
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class StatsRecorder(object):
|
| 21 |
+
"""Stats Recorder provides methods to record stats against tags
|
| 22 |
+
|
| 23 |
+
"""
|
| 24 |
+
def __init__(self):
|
| 25 |
+
if execution_context.get_measure_to_view_map() == {}:
|
| 26 |
+
execution_context.set_measure_to_view_map(MeasureToViewMap())
|
| 27 |
+
|
| 28 |
+
self.measure_to_view_map = execution_context.get_measure_to_view_map()
|
| 29 |
+
|
| 30 |
+
def new_measurement_map(self):
|
| 31 |
+
"""Creates a new MeasurementMap in order to record stats
|
| 32 |
+
:returns a MeasurementMap for recording multiple measurements
|
| 33 |
+
"""
|
| 34 |
+
return MeasurementMap(self.measure_to_view_map)
|
.venv/lib/python3.11/site-packages/opencensus/stats/view.py
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
|
| 16 |
+
import threading
|
| 17 |
+
|
| 18 |
+
from opencensus.metrics import label_key
|
| 19 |
+
from opencensus.metrics.export import metric_descriptor
|
| 20 |
+
|
| 21 |
+
|
| 22 |
+
class View(object):
|
| 23 |
+
"""A view defines a specific aggregation and a set of tag keys
|
| 24 |
+
|
| 25 |
+
:type name: str
|
| 26 |
+
:param name: name of the view
|
| 27 |
+
|
| 28 |
+
:type description: str
|
| 29 |
+
:param description: description of the view
|
| 30 |
+
|
| 31 |
+
:type columns: (:class: '~opencensus.tags.tag_key.TagKey')
|
| 32 |
+
:param columns: the columns that the tag keys will aggregate on for this
|
| 33 |
+
view
|
| 34 |
+
|
| 35 |
+
:type measure: :class: '~opencensus.stats.measure.Measure'
|
| 36 |
+
:param measure: the measure to be aggregated by the view
|
| 37 |
+
|
| 38 |
+
:type aggregation: :class: '~opencensus.stats.aggregation.BaseAggregation'
|
| 39 |
+
:param aggregation: the aggregation the view will support
|
| 40 |
+
|
| 41 |
+
"""
|
| 42 |
+
|
| 43 |
+
def __init__(self, name, description, columns, measure, aggregation):
|
| 44 |
+
self._name = name
|
| 45 |
+
self._description = description
|
| 46 |
+
self._columns = columns
|
| 47 |
+
self._measure = measure
|
| 48 |
+
self._aggregation = aggregation
|
| 49 |
+
|
| 50 |
+
# Cache the converted MetricDescriptor here to avoid creating it each
|
| 51 |
+
# time we convert a ViewData that realizes this View into a Metric.
|
| 52 |
+
self._md_cache_lock = threading.Lock()
|
| 53 |
+
self._metric_descriptor = None
|
| 54 |
+
|
| 55 |
+
@property
|
| 56 |
+
def name(self):
|
| 57 |
+
"""the name of the current view"""
|
| 58 |
+
return self._name
|
| 59 |
+
|
| 60 |
+
@property
|
| 61 |
+
def description(self):
|
| 62 |
+
"""the description of the current view"""
|
| 63 |
+
return self._description
|
| 64 |
+
|
| 65 |
+
@property
|
| 66 |
+
def columns(self):
|
| 67 |
+
"""the columns of the current view"""
|
| 68 |
+
return self._columns
|
| 69 |
+
|
| 70 |
+
@property
|
| 71 |
+
def measure(self):
|
| 72 |
+
"""the measure of the current view"""
|
| 73 |
+
return self._measure
|
| 74 |
+
|
| 75 |
+
@property
|
| 76 |
+
def aggregation(self):
|
| 77 |
+
"""the aggregation of the current view"""
|
| 78 |
+
return self._aggregation
|
| 79 |
+
|
| 80 |
+
def new_aggregation_data(self):
|
| 81 |
+
"""Get a new AggregationData for this view.
|
| 82 |
+
|
| 83 |
+
:rtype: :class: `opencensus.status.aggregation_data.AggregationData`
|
| 84 |
+
:return: A new AggregationData.
|
| 85 |
+
"""
|
| 86 |
+
return self._aggregation.new_aggregation_data(self.measure)
|
| 87 |
+
|
| 88 |
+
def get_metric_descriptor(self):
|
| 89 |
+
"""Get a MetricDescriptor for this view.
|
| 90 |
+
|
| 91 |
+
Lazily creates a MetricDescriptor for metrics conversion.
|
| 92 |
+
|
| 93 |
+
:rtype: :class:
|
| 94 |
+
`opencensus.metrics.export.metric_descriptor.MetricDescriptor`
|
| 95 |
+
:return: A converted Metric.
|
| 96 |
+
""" # noqa
|
| 97 |
+
with self._md_cache_lock:
|
| 98 |
+
if self._metric_descriptor is None:
|
| 99 |
+
self._metric_descriptor = metric_descriptor.MetricDescriptor(
|
| 100 |
+
self.name,
|
| 101 |
+
self.description,
|
| 102 |
+
self.measure.unit,
|
| 103 |
+
self.aggregation.get_metric_type(self.measure),
|
| 104 |
+
# TODO: add label key description
|
| 105 |
+
[label_key.LabelKey(tk, "") for tk in self.columns])
|
| 106 |
+
return self._metric_descriptor
|
.venv/lib/python3.11/site-packages/opencensus/stats/view_data.py
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
from opencensus.common import utils
|
| 16 |
+
|
| 17 |
+
|
| 18 |
+
class ViewData(object):
|
| 19 |
+
"""View Data is the aggregated data for a particular view
|
| 20 |
+
|
| 21 |
+
:type view:
|
| 22 |
+
:param view: The view associated with this view data
|
| 23 |
+
|
| 24 |
+
:type start_time: datetime
|
| 25 |
+
:param start_time: the start time for this view data
|
| 26 |
+
|
| 27 |
+
:type end_time: datetime
|
| 28 |
+
:param end_time: the end time for this view data
|
| 29 |
+
|
| 30 |
+
"""
|
| 31 |
+
def __init__(self,
|
| 32 |
+
view,
|
| 33 |
+
start_time,
|
| 34 |
+
end_time):
|
| 35 |
+
self._view = view
|
| 36 |
+
self._start_time = start_time
|
| 37 |
+
self._end_time = end_time
|
| 38 |
+
self._tag_value_aggregation_data_map = {}
|
| 39 |
+
|
| 40 |
+
@property
|
| 41 |
+
def view(self):
|
| 42 |
+
"""the current view in the view data"""
|
| 43 |
+
return self._view
|
| 44 |
+
|
| 45 |
+
# TODO: `start_time` and `end_time` are sometimes a `datetime` object but
|
| 46 |
+
# should always be a `string`.
|
| 47 |
+
@property
|
| 48 |
+
def start_time(self):
|
| 49 |
+
"""the current start time in the view data"""
|
| 50 |
+
return self._start_time
|
| 51 |
+
|
| 52 |
+
@property
|
| 53 |
+
def end_time(self):
|
| 54 |
+
"""the current end time in the view data"""
|
| 55 |
+
return self._end_time
|
| 56 |
+
|
| 57 |
+
@property
|
| 58 |
+
def tag_value_aggregation_data_map(self):
|
| 59 |
+
"""the current tag value aggregation map in the view data"""
|
| 60 |
+
return self._tag_value_aggregation_data_map
|
| 61 |
+
|
| 62 |
+
def start(self):
|
| 63 |
+
"""sets the start time for the view data"""
|
| 64 |
+
self._start_time = utils.to_iso_str()
|
| 65 |
+
|
| 66 |
+
def end(self):
|
| 67 |
+
"""sets the end time for the view data"""
|
| 68 |
+
self._end_time = utils.to_iso_str()
|
| 69 |
+
|
| 70 |
+
def get_tag_values(self, tags, columns):
|
| 71 |
+
"""function to get the tag values from tags and columns"""
|
| 72 |
+
tag_values = []
|
| 73 |
+
i = 0
|
| 74 |
+
while i < len(columns):
|
| 75 |
+
tag_key = columns[i]
|
| 76 |
+
if tag_key in tags:
|
| 77 |
+
tag_values.append(tags.get(tag_key))
|
| 78 |
+
else:
|
| 79 |
+
tag_values.append(None)
|
| 80 |
+
i += 1
|
| 81 |
+
return tag_values
|
| 82 |
+
|
| 83 |
+
def record(self, context, value, timestamp, attachments=None):
|
| 84 |
+
"""records the view data against context"""
|
| 85 |
+
if context is None:
|
| 86 |
+
tags = dict()
|
| 87 |
+
else:
|
| 88 |
+
tags = context.map
|
| 89 |
+
tag_values = self.get_tag_values(tags=tags,
|
| 90 |
+
columns=self.view.columns)
|
| 91 |
+
tuple_vals = tuple(tag_values)
|
| 92 |
+
if tuple_vals not in self.tag_value_aggregation_data_map:
|
| 93 |
+
self.tag_value_aggregation_data_map[tuple_vals] = \
|
| 94 |
+
self.view.new_aggregation_data()
|
| 95 |
+
self.tag_value_aggregation_data_map.get(tuple_vals).\
|
| 96 |
+
add_sample(value, timestamp, attachments)
|
.venv/lib/python3.11/site-packages/opencensus/stats/view_manager.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Copyright 2018, OpenCensus 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 |
+
from opencensus.common import utils
|
| 16 |
+
from opencensus.stats import execution_context
|
| 17 |
+
from opencensus.stats.measure_to_view_map import MeasureToViewMap
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
class ViewManager(object):
|
| 21 |
+
"""View Manager allows the registering of Views for collecting stats
|
| 22 |
+
and receiving stats data as View Data"""
|
| 23 |
+
def __init__(self):
|
| 24 |
+
self.time = utils.to_iso_str()
|
| 25 |
+
if execution_context.get_measure_to_view_map() == {}:
|
| 26 |
+
execution_context.set_measure_to_view_map(MeasureToViewMap())
|
| 27 |
+
|
| 28 |
+
self._measure_view_map = execution_context.get_measure_to_view_map()
|
| 29 |
+
|
| 30 |
+
@property
|
| 31 |
+
def measure_to_view_map(self):
|
| 32 |
+
"""the current measure to view map for the View Manager"""
|
| 33 |
+
return self._measure_view_map
|
| 34 |
+
|
| 35 |
+
def register_view(self, view):
|
| 36 |
+
"""registers the given view"""
|
| 37 |
+
self.measure_to_view_map.register_view(view=view, timestamp=self.time)
|
| 38 |
+
|
| 39 |
+
def get_view(self, view_name):
|
| 40 |
+
"""gets the view given the view name """
|
| 41 |
+
return self.measure_to_view_map.get_view(view_name=view_name,
|
| 42 |
+
timestamp=self.time)
|
| 43 |
+
|
| 44 |
+
def get_all_exported_views(self):
|
| 45 |
+
"""returns all of the exported views for the current measure to view
|
| 46 |
+
map"""
|
| 47 |
+
return self.measure_to_view_map.exported_views
|
| 48 |
+
|
| 49 |
+
def register_exporter(self, exporter):
|
| 50 |
+
"""register the exporter"""
|
| 51 |
+
self.measure_to_view_map.exporters.append(exporter)
|
| 52 |
+
|
| 53 |
+
def unregister_exporter(self, exporter):
|
| 54 |
+
"""unregister the exporter"""
|
| 55 |
+
self.measure_to_view_map.exporters.remove(exporter)
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/__init__.cpython-311.pyc
ADDED
|
Binary file (207 Bytes). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/pem.cpython-311.pyc
ADDED
|
Binary file (3.27 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc1901.cpython-311.pyc
ADDED
|
Binary file (1.1 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc2876.cpython-311.pyc
ADDED
|
Binary file (1.76 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc2985.cpython-311.pyc
ADDED
|
Binary file (16.9 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3058.cpython-311.pyc
ADDED
|
Binary file (1.26 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3274.cpython-311.pyc
ADDED
|
Binary file (1.83 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3280.cpython-311.pyc
ADDED
|
Binary file (81.1 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3560.cpython-311.pyc
ADDED
|
Binary file (1.58 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3565.cpython-311.pyc
ADDED
|
Binary file (1.86 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3709.cpython-311.pyc
ADDED
|
Binary file (10.9 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3739.cpython-311.pyc
ADDED
|
Binary file (7.56 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc3852.cpython-311.pyc
ADDED
|
Binary file (36.8 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc4010.cpython-311.pyc
ADDED
|
Binary file (1.82 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc4108.cpython-311.pyc
ADDED
|
Binary file (14.8 kB). View file
|
|
|
.venv/lib/python3.11/site-packages/pyasn1_modules/__pycache__/rfc4211.cpython-311.pyc
ADDED
|
Binary file (21.7 kB). View file
|
|
|