зеркало из https://github.com/mozilla/glean.git
[Python] Migrate labeled metrics to UniFFI
This commit is contained in:
Родитель
bbbf9a0a33
Коммит
23fb9dc6e2
|
@ -3,14 +3,13 @@
|
|||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
from typing import Any, Callable, List, Optional, Set, Type
|
||||
from typing import Any, Optional, Set, Type
|
||||
|
||||
|
||||
from .. import _ffi
|
||||
from .boolean import BooleanMetricType
|
||||
from .counter import CounterMetricType
|
||||
from .lifetime import Lifetime
|
||||
from .string import StringMetricType
|
||||
from .._uniffi import CommonMetricData
|
||||
from .._uniffi import LabeledBoolean
|
||||
from .._uniffi import LabeledCounter
|
||||
from .._uniffi import LabeledString
|
||||
from ..testing import ErrorType
|
||||
|
||||
|
||||
|
@ -30,50 +29,18 @@ class LabeledMetricBase:
|
|||
metric storage and rearrange them correctly in the ping.
|
||||
"""
|
||||
|
||||
# The following 4 class attributes must be overridden by classes
|
||||
# The following class attribute must be overridden by classes
|
||||
# inheriting from LabeledMetricBase:
|
||||
|
||||
# The class of the concrete metric type
|
||||
_submetric_type: Type
|
||||
|
||||
# The FFI function to instantiate the labeled metric type
|
||||
_metric_type_instantiator: Callable
|
||||
|
||||
# The FFI function to get a concrete metric type from the labeled metric type
|
||||
_submetric_type_instantiator: Callable
|
||||
|
||||
# The FFI function for test_get_num_recorded_errors
|
||||
_test_get_num_recorded_errors_ffi: Callable
|
||||
_ctor: Type
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
disabled: bool,
|
||||
category: str,
|
||||
lifetime: Lifetime,
|
||||
name: str,
|
||||
send_in_pings: List[str],
|
||||
common_metric_data: CommonMetricData,
|
||||
labels: Optional[Set[str]] = None,
|
||||
):
|
||||
self._disabled = disabled
|
||||
self._send_in_pings = send_in_pings
|
||||
|
||||
if labels is not None:
|
||||
label_list = _ffi.ffi_encode_vec_string(list(labels))
|
||||
label_len = len(labels)
|
||||
else:
|
||||
label_list = _ffi.ffi.NULL
|
||||
label_len = 0
|
||||
|
||||
self._handle = self._metric_type_instantiator(
|
||||
_ffi.ffi_encode_string(category),
|
||||
_ffi.ffi_encode_string(name),
|
||||
_ffi.ffi_encode_vec_string(send_in_pings),
|
||||
len(send_in_pings),
|
||||
lifetime.value,
|
||||
disabled,
|
||||
label_list,
|
||||
label_len,
|
||||
)
|
||||
self._inner = self._ctor(common_metric_data, labels)
|
||||
|
||||
def __getitem__(self, item: str) -> Any:
|
||||
"""
|
||||
|
@ -91,14 +58,7 @@ class LabeledMetricBase:
|
|||
label is used, the metric will be recorded in the special `__other__`
|
||||
label.
|
||||
"""
|
||||
handle = self._submetric_type_instantiator(
|
||||
self._handle, _ffi.ffi_encode_string(item)
|
||||
)
|
||||
metric = self._submetric_type.__new__(self._submetric_type) # type: ignore
|
||||
metric._handle = handle
|
||||
metric._disabled = self._disabled
|
||||
metric._send_in_pings = self._send_in_pings
|
||||
return metric
|
||||
return self._inner.get(item)
|
||||
|
||||
def test_get_num_recorded_errors(
|
||||
self, error_type: ErrorType, ping_name: Optional[str] = None
|
||||
|
@ -115,41 +75,19 @@ class LabeledMetricBase:
|
|||
num_errors (int): The number of errors recorded for the metric for
|
||||
the given error type.
|
||||
"""
|
||||
if ping_name is None:
|
||||
ping_name = self._send_in_pings[0]
|
||||
|
||||
return self._test_get_num_recorded_errors_ffi(
|
||||
self._handle,
|
||||
error_type.value,
|
||||
_ffi.ffi_encode_string(ping_name),
|
||||
)
|
||||
return self._inner.test_get_num_recorded_errors(error_type, ping_name)
|
||||
|
||||
|
||||
class LabeledBooleanMetricType(LabeledMetricBase):
|
||||
_submetric_type = BooleanMetricType
|
||||
_metric_type_instantiator = _ffi.lib.glean_new_labeled_boolean_metric
|
||||
_submetric_type_instantiator = _ffi.lib.glean_labeled_boolean_metric_get
|
||||
_test_get_num_recorded_errors_ffi = (
|
||||
_ffi.lib.glean_labeled_boolean_test_get_num_recorded_errors
|
||||
)
|
||||
_ctor = LabeledBoolean
|
||||
|
||||
|
||||
class LabeledCounterMetricType(LabeledMetricBase):
|
||||
_submetric_type = CounterMetricType
|
||||
_metric_type_instantiator = _ffi.lib.glean_new_labeled_counter_metric
|
||||
_submetric_type_instantiator = _ffi.lib.glean_labeled_counter_metric_get
|
||||
_test_get_num_recorded_errors_ffi = (
|
||||
_ffi.lib.glean_labeled_counter_test_get_num_recorded_errors
|
||||
)
|
||||
_ctor = LabeledCounter
|
||||
|
||||
|
||||
class LabeledStringMetricType(LabeledMetricBase):
|
||||
_submetric_type = StringMetricType
|
||||
_metric_type_instantiator = _ffi.lib.glean_new_labeled_string_metric
|
||||
_submetric_type_instantiator = _ffi.lib.glean_labeled_string_metric_get
|
||||
_test_get_num_recorded_errors_ffi = (
|
||||
_ffi.lib.glean_labeled_string_test_get_num_recorded_errors
|
||||
)
|
||||
_ctor = LabeledString
|
||||
|
||||
|
||||
__all__ = [
|
||||
|
|
|
@ -2,145 +2,83 @@
|
|||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
|
||||
import io
|
||||
import json
|
||||
import sys
|
||||
|
||||
|
||||
from glean_parser import validate_ping
|
||||
|
||||
|
||||
from glean import Glean
|
||||
from glean import __version__ as glean_version
|
||||
from glean import _builtins
|
||||
from glean import metrics
|
||||
from glean._dispatcher import Dispatcher
|
||||
from glean.metrics import Lifetime
|
||||
from glean.metrics import Lifetime, CommonMetricData
|
||||
from glean.testing import ErrorType
|
||||
|
||||
|
||||
def test_labeled_counter_type(ping_schema_url):
|
||||
labeled_counter_metric = metrics.LabeledCounterMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
)
|
||||
)
|
||||
|
||||
labeled_counter_metric["label1"].add(1)
|
||||
labeled_counter_metric["label2"].add(2)
|
||||
|
||||
assert labeled_counter_metric["label1"].test_has_value()
|
||||
assert 1 == labeled_counter_metric["label1"].test_get_value()
|
||||
|
||||
assert labeled_counter_metric["label2"].test_has_value()
|
||||
assert 2 == labeled_counter_metric["label2"].test_get_value()
|
||||
|
||||
json_content = Glean.test_collect(_builtins.pings.metrics)
|
||||
|
||||
assert 0 == validate_ping.validate_ping(
|
||||
io.StringIO(json_content), sys.stdout, schema_url=ping_schema_url
|
||||
)
|
||||
|
||||
tree = json.loads(json_content)
|
||||
|
||||
assert (
|
||||
1
|
||||
== tree["metrics"]["labeled_counter"]["telemetry.labeled_counter_metric"][
|
||||
"label1"
|
||||
]
|
||||
)
|
||||
assert (
|
||||
2
|
||||
== tree["metrics"]["labeled_counter"]["telemetry.labeled_counter_metric"][
|
||||
"label2"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def test_labeled_boolean_type(ping_schema_url):
|
||||
labeled_boolean_metric = metrics.LabeledBooleanMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_boolean_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_boolean_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
)
|
||||
)
|
||||
|
||||
labeled_boolean_metric["label1"].set(True)
|
||||
labeled_boolean_metric["label2"].set(False)
|
||||
|
||||
assert labeled_boolean_metric["label1"].test_has_value()
|
||||
assert labeled_boolean_metric["label1"].test_get_value()
|
||||
|
||||
assert labeled_boolean_metric["label2"].test_has_value()
|
||||
assert not labeled_boolean_metric["label2"].test_get_value()
|
||||
|
||||
json_content = Glean.test_collect(_builtins.pings.metrics)
|
||||
|
||||
assert 0 == validate_ping.validate_ping(
|
||||
io.StringIO(json_content), sys.stdout, schema_url=ping_schema_url
|
||||
)
|
||||
|
||||
tree = json.loads(json_content)
|
||||
|
||||
assert tree["metrics"]["labeled_boolean"]["telemetry.labeled_boolean_metric"][
|
||||
"label1"
|
||||
]
|
||||
assert not tree["metrics"]["labeled_boolean"]["telemetry.labeled_boolean_metric"][
|
||||
"label2"
|
||||
]
|
||||
|
||||
|
||||
def test_labeled_string_type(ping_schema_url):
|
||||
labeled_string_metric = metrics.LabeledStringMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_string_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_string_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
)
|
||||
)
|
||||
|
||||
labeled_string_metric["label1"].set("foo")
|
||||
labeled_string_metric["label2"].set("bar")
|
||||
|
||||
assert labeled_string_metric["label1"].test_has_value()
|
||||
assert "foo" == labeled_string_metric["label1"].test_get_value()
|
||||
|
||||
assert labeled_string_metric["label2"].test_has_value()
|
||||
assert "bar" == labeled_string_metric["label2"].test_get_value()
|
||||
|
||||
json_content = Glean.test_collect(_builtins.pings.metrics)
|
||||
|
||||
assert 0 == validate_ping.validate_ping(
|
||||
io.StringIO(json_content), sys.stdout, schema_url=ping_schema_url
|
||||
)
|
||||
|
||||
tree = json.loads(json_content)
|
||||
|
||||
assert (
|
||||
"foo"
|
||||
== tree["metrics"]["labeled_string"]["telemetry.labeled_string_metric"][
|
||||
"label1"
|
||||
]
|
||||
)
|
||||
assert (
|
||||
"bar"
|
||||
== tree["metrics"]["labeled_string"]["telemetry.labeled_string_metric"][
|
||||
"label2"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def test_other_label_with_predefined_labels(ping_schema_url):
|
||||
labeled_counter_metric = metrics.LabeledCounterMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
),
|
||||
labels=["foo", "bar", "baz"],
|
||||
)
|
||||
|
||||
|
@ -153,40 +91,20 @@ def test_other_label_with_predefined_labels(ping_schema_url):
|
|||
|
||||
assert 3 == labeled_counter_metric["foo"].test_get_value()
|
||||
assert 1 == labeled_counter_metric["bar"].test_get_value()
|
||||
assert not labeled_counter_metric["baz"].test_has_value()
|
||||
assert not labeled_counter_metric["baz"].test_get_value()
|
||||
assert 3 == labeled_counter_metric["not_there"].test_get_value()
|
||||
|
||||
json_content = Glean.test_collect(_builtins.pings.metrics)
|
||||
|
||||
assert 0 == validate_ping.validate_ping(
|
||||
io.StringIO(json_content), sys.stdout, schema_url=ping_schema_url
|
||||
)
|
||||
|
||||
tree = json.loads(json_content)
|
||||
|
||||
assert (
|
||||
3
|
||||
== tree["metrics"]["labeled_counter"]["telemetry.labeled_counter_metric"]["foo"]
|
||||
)
|
||||
assert (
|
||||
1
|
||||
== tree["metrics"]["labeled_counter"]["telemetry.labeled_counter_metric"]["bar"]
|
||||
)
|
||||
assert (
|
||||
3
|
||||
== tree["metrics"]["labeled_counter"]["telemetry.labeled_counter_metric"][
|
||||
"__other__"
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
def test_other_label_without_predefined_labels(ping_schema_url):
|
||||
labeled_counter_metric = metrics.LabeledCounterMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
)
|
||||
)
|
||||
|
||||
for i in range(21):
|
||||
|
@ -199,24 +117,20 @@ def test_other_label_without_predefined_labels(ping_schema_url):
|
|||
assert 1 == labeled_counter_metric[f"label_{i}"].test_get_value()
|
||||
assert 5 == labeled_counter_metric["__other__"].test_get_value()
|
||||
|
||||
json_content = Glean.test_collect(_builtins.pings.metrics)
|
||||
|
||||
assert 0 == validate_ping.validate_ping(
|
||||
io.StringIO(json_content), sys.stdout, schema_url=ping_schema_url
|
||||
)
|
||||
|
||||
|
||||
def test_other_label_without_predefined_labels_before_glean_init():
|
||||
labeled_counter_metric = metrics.LabeledCounterMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
)
|
||||
)
|
||||
|
||||
Glean._reset()
|
||||
Dispatcher.set_task_queueing(True)
|
||||
|
||||
for i in range(21):
|
||||
labeled_counter_metric[f"label_{i}"].add(1)
|
||||
|
@ -236,11 +150,14 @@ def test_other_label_without_predefined_labels_before_glean_init():
|
|||
|
||||
def test_invalid_labels_go_to_other():
|
||||
labeled_counter_metric = metrics.LabeledCounterMetricType(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
CommonMetricData(
|
||||
disabled=False,
|
||||
category="telemetry",
|
||||
lifetime=Lifetime.APPLICATION,
|
||||
name="labeled_counter_metric",
|
||||
send_in_pings=["metrics"],
|
||||
dynamic_label=None,
|
||||
)
|
||||
)
|
||||
|
||||
labeled_counter_metric["notSnakeCase"].add(1)
|
||||
|
|
Загрузка…
Ссылка в новой задаче