This is an automated email from the ASF dual-hosted git repository.
kezhenxu94 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-python.git
The following commit(s) were added to refs/heads/master by this push:
new 71df914 refactor: hide some functions related to meter from users
(#236)
71df914 is described below
commit 71df9145f080c37d8de4f5129bca4a97e5683951
Author: jiang1997 <[email protected]>
AuthorDate: Thu Sep 15 18:54:52 2022 +0800
refactor: hide some functions related to meter from users (#236)
---
docs/en/setup/advanced/MeterReporter.md | 45 +++++++++++++++------------------
skywalking/meter/counter.py | 12 ++++++---
skywalking/meter/gauge.py | 4 +++
skywalking/meter/histogram.py | 8 +++++-
skywalking/meter/meter.py | 32 ++++++++++++++---------
tests/unit/test_meter.py | 33 ++++++++++++------------
6 files changed, 77 insertions(+), 57 deletions(-)
diff --git a/docs/en/setup/advanced/MeterReporter.md
b/docs/en/setup/advanced/MeterReporter.md
index f9cceb2..6286a99 100644
--- a/docs/en/setup/advanced/MeterReporter.md
+++ b/docs/en/setup/advanced/MeterReporter.md
@@ -23,17 +23,16 @@ export SW_AGENT_METER_REPORTER_ACTIVE=False
## Counter
* `Counter` API represents a single monotonically increasing counter,
automatic collect data and report to backend.
```python
-tg_ls = [MeterTag("key", "value")]
-c = Counter('c2', CounterMode.INCREMENT, tg_ls)
-# or with more compact way
-# Counter('c2', CounterMode.INCREMENT).tag('key1', 'value1').tag('key2',
'value2')
-c.build()
+builder = Counter.Builder('c2', CounterMode.INCREMENT, (("k1", "v1"), ("k2",
"v2")))
+# or this way
+# builder = Counter.Builder('c2', CounterMode.INCREMENT).tag('key1',
'value1').tag('key2', 'value2')
+c = builder.build()
c.increment(2)
```
### Syntactic sugars
```python
-c = Counter('c2', CounterMode.INCREMENT)
-c.build()
+builder = Counter.Builder('c2', CounterMode.INCREMENT)
+c = builder.build()
# increase Counter c by the time the with-wrapped codes consumed
with c.create_timer():
@@ -41,8 +40,8 @@ with c.create_timer():
```
```python
-c = Counter('c3', CounterMode.INCREMENT)
-c.build()
+builder = Counter.Builder('c3', CounterMode.INCREMENT)
+c = builder.build()
# increase Counter c by num once counter_decorator_test gets called
@Counter.increase(name='c3', num=2)
@@ -51,8 +50,8 @@ def counter_decorator_test():
```
```python
-c = Counter('c4', CounterMode.INCREMENT)
-c.build()
+builder = Counter.Builder('c4', CounterMode.INCREMENT)
+c = builder.build()
# increase Counter c by the time counter_decorator_test consumed
@Counter.timer(name='c4')
@@ -60,7 +59,7 @@ def counter_decorator_test(s):
# some codes may consume a certain time
```
-1. `Counter(name, tags)` Create a new counter with the meter name and optional
tags.
+1. `Counter.Builder(name, tags)` Create a new counter builder with the meter
name and optional tags.
1. `Counter.tag(key: str, value)` Mark a tag key/value pair.
1. `Counter.mode(mode: CounterMode)` Change the counter mode, RATE mode means
reporting rate to the backend.
1. `Counter.increment(count)` Increment count to the `Counter`, It could be a
positive value.
@@ -68,26 +67,24 @@ def counter_decorator_test(s):
## Gauge
* `Gauge` API represents a single numerical value.
```python
-tg_ls = [MeterTag("key", "value")]
# producer: iterable object
-g = Gauge('g1', producer, tg_ls)
-g.build()
+builder = Gauge.Builder('g1', producer, (("key", "value")))
+g = Builder.build()
```
-1. `Gauge(name, tags)` Create a new gauge with the meter name and iterable
object, this iterable object need to produce numeric value.
+1. `Gauge.Builder(name, tags)` Create a new gauge builder with the meter name
and iterable object, this iterable object need to produce numeric value.
1. `Gauge.tag(key: str, value)` Mark a tag key/value pair.
1. `Gauge.build()` Build a new `Gauge` which is collected and reported to the
backend.
## Histogram
* `Histogram` API represents a summary sample observations with customize
buckets.
```python
-tg_ls = [MeterTag("key", "value")]
-h = Histogram('h2', [i / 10 for i in range(10)], tg_ls)
-h.build()
+builder = Histogram.Builder('h2', [i / 10 for i in range(10)], ("key",
"value"))
+h = builder.build()
```
### Syntactic sugars
```python
-h = Histogram('h3', [i / 10 for i in range(10)])
-h.build()
+builder = Histogram.Builder('h3', [i / 10 for i in range(10)])
+h = builder.build()
# Histogram h will record the time the with-wrapped codes consumed
with h.create_timer():
@@ -95,15 +92,15 @@ with h.create_timer():
```
```python
-h = Histogram('h2', [i / 10 for i in range(10)])
-h.build()
+builder = Histogram.Builder('h2', [i / 10 for i in range(10)])
+h = builder.build()
# Histogram h will record the time histogram_decorator_test consumed
@Histogram.timer(name='h2')
def histogram_decorator_test(s):
time.sleep(s)
```
-1. `Histogram(name, tags)` Create a new histogram with the meter name and
optional tags.
+1. `Histogram.Builder(name, tags)` Create a new histogram builder with the
meter name and optional tags.
1. `Histogram.tag(key: str, value)` Mark a tag key/value pair.
1. `Histogram.minValue(value)` Set up the minimal value of this histogram,
default is `0`.
1. `Histogram.build()` Build a new `Histogram` which is collected and reported
to the backend.
diff --git a/skywalking/meter/counter.py b/skywalking/meter/counter.py
index 123b9d2..1a1edec 100644
--- a/skywalking/meter/counter.py
+++ b/skywalking/meter/counter.py
@@ -50,10 +50,6 @@ class Counter(BaseMeter):
meterdata =
MeterData(singleValue=MeterSingleValue(name=self.get_name(),
labels=self.transform_tags(), value=count))
return meterdata
- def mode(self, mode):
- self.mode = mode
- return self
-
def get_type(self):
return MeterType.COUNTER
@@ -98,3 +94,11 @@ class Counter(BaseMeter):
return wrapper
return inner
+
+ class Builder(BaseMeter.Builder):
+ def __init__(self, name: str, mode: CounterMode, tags=None):
+ self.meter = Counter(name, mode, tags)
+
+ def mode(self, mode: CounterMode):
+ self.meter.mode = mode
+ return self
diff --git a/skywalking/meter/gauge.py b/skywalking/meter/gauge.py
index b004fed..a74e957 100644
--- a/skywalking/meter/gauge.py
+++ b/skywalking/meter/gauge.py
@@ -35,3 +35,7 @@ class Gauge(BaseMeter):
def get_type(self):
return MeterType.GAUGE
+
+ class Builder(BaseMeter.Builder):
+ def __init__(self, name: str, generator, tags=None):
+ self.meter = Gauge(name, generator, tags)
diff --git a/skywalking/meter/histogram.py b/skywalking/meter/histogram.py
index 3a81cf2..5c5e5df 100644
--- a/skywalking/meter/histogram.py
+++ b/skywalking/meter/histogram.py
@@ -25,10 +25,12 @@ class Histogram(BaseMeter):
super().__init__(name, tags)
self.min_value = min_value
+ # check if a list is empty?
# https://stackoverflow.com/a/53522/9845190
if not steps:
raise Exception('steps must not be empty')
+ # sort and deduplicate
# https://stackoverflow.com/a/2931683/9845190
steps = sorted(set(steps))
@@ -50,7 +52,7 @@ class Histogram(BaseMeter):
left = 0
right = len(self.buckets)
- # find the first bucket greater than or equal the value
+ # find the first bucket greater than or equal to the value
while left < right:
mid = (left + right) // 2
if self.buckets[mid].bucket < value:
@@ -118,3 +120,7 @@ class Histogram(BaseMeter):
return wrapper
return inner
+
+ class Builder(BaseMeter.Builder):
+ def __init__(self, name: str, steps, min_value=0, tags=None):
+ self.meter = Histogram(name, steps, min_value, tags)
diff --git a/skywalking/meter/meter.py b/skywalking/meter/meter.py
index 5eba338..f8eacd1 100644
--- a/skywalking/meter/meter.py
+++ b/skywalking/meter/meter.py
@@ -49,20 +49,20 @@ class MeterTag():
class MeterId():
- def __init__(self, name: str, type, tags: list) -> None:
+ def __init__(self, name: str, type, tags: tuple) -> None:
if tags is None:
- tags = []
+ tags = ()
self.name = name
self.type = type
- self.tags = tags
+ self.tags = [MeterTag(key, value) for (key, value) in tags]
self.labels = None
def transform_tags(self):
if self.labels is not None:
return self.labels
- self.labels = [Label(tag.key, tag.value) for tag in self.tags]
+ self.labels = [Label(name=tag.key, value=tag.value) for tag in
self.tags]
return self.labels
def get_name(self):
@@ -101,14 +101,22 @@ class BaseMeter(ABC):
def transform_tags(self):
return self.get_id().transform_tags()
- def tag(self, name: str, value):
- self.meterId.get_tags().append(MeterTag(name, value))
- return self
-
- def build(self):
- self.meterId.get_tags().sort()
- BaseMeter.meter_service.register(self)
-
@abstractmethod
def get_type(self):
pass
+
+ class Builder(ABC):
+ @abstractmethod
+ def __init__(self, name: str, tags=None):
+ # Derived Builder should instantiate its corresponding meter here.
+ # self.meter = BaseMeter(name, tags)
+ pass
+
+ def tag(self, name: str, value):
+ self.meter.meterId.get_tags().append(MeterTag(name, value))
+ return self
+
+ def build(self):
+ self.meter.meterId.get_tags().sort()
+ BaseMeter.meter_service.register(self.meter)
+ return self.meter
diff --git a/tests/unit/test_meter.py b/tests/unit/test_meter.py
index 1569fbf..4447abc 100644
--- a/tests/unit/test_meter.py
+++ b/tests/unit/test_meter.py
@@ -52,8 +52,9 @@ tolerance = 5e-2
class TestMeter(unittest.TestCase):
def test_counter(self):
- c = Counter('c1', CounterMode.INCREMENT)
- c.build()
+ builder = Counter.Builder('c1', CounterMode.INCREMENT, (('k1', 'v1'),
('k2', 'v2')))
+ builder.tag('k3', 'v3')
+ c = builder.build()
@Counter.increase(name='c1')
def increase_by_one():
@@ -68,8 +69,8 @@ class TestMeter(unittest.TestCase):
self.assertEqual(i, meterdata.singleValue.value)
def test_counter_with_satement(self):
- c = Counter('c2', CounterMode.INCREMENT)
- c.build()
+ builder = Counter.Builder('c2', CounterMode.INCREMENT)
+ c = builder.build()
ls = [i / 10 for i in range(10)]
random.shuffle(ls)
@@ -86,8 +87,8 @@ class TestMeter(unittest.TestCase):
def test_counter_increase_decarator(self):
- c = Counter('c3', CounterMode.INCREMENT)
- c.build()
+ builder = Counter.Builder('c3', CounterMode.INCREMENT)
+ c = builder.build()
@Counter.increase(name='c3', num=2)
def counter_decorator_test():
@@ -101,8 +102,8 @@ class TestMeter(unittest.TestCase):
self.assertEqual(i * 2, meterdata.singleValue.value)
def test_counter_timer_decarator(self):
- c = Counter('c4', CounterMode.INCREMENT)
- c.build()
+ builder = Counter.Builder('c4', CounterMode.INCREMENT)
+ c = builder.build()
ls = [i / 10 for i in range(10)]
@@ -121,8 +122,8 @@ class TestMeter(unittest.TestCase):
self.assertLessEqual(abs(total - meterdata.singleValue.value),
tolerance)
def test_histogram(self):
- h = Histogram('h1', list(range(0, 10)))
- h.build()
+ builder = Histogram.Builder('h1', list(range(0, 10)))
+ h = builder.build()
for repeat in range(1, 10):
ls = list(range(1, 10))
@@ -135,8 +136,8 @@ class TestMeter(unittest.TestCase):
self.assertEqual(repeat, meterdata.histogram.values[i -
1].count)
def test_histogram_timer_decarator(self):
- h = Histogram('h2', [i / 10 for i in range(10)])
- h.build()
+ builder = Histogram.Builder('h2', [i / 10 for i in range(10)])
+ h = builder.build()
ls = [i / 10 for i in range(10)]
@@ -153,8 +154,8 @@ class TestMeter(unittest.TestCase):
self.assertEqual(repeat, meterdata.histogram.values[idx].count)
def test_histogram_with_satement(self):
- h = Histogram('h3', [i / 10 for i in range(10)])
- h.build()
+ builder = Histogram.Builder('h3', [i / 10 for i in range(10)])
+ h = builder.build()
ls = [i / 10 for i in range(10)]
@@ -171,8 +172,8 @@ class TestMeter(unittest.TestCase):
def test_gauge(self):
ls = list(range(1, 10))
random.shuffle(ls)
- g = Gauge('g1', iter(ls))
- g.build()
+ builder = Gauge.Builder('g1', iter(ls))
+ g = builder.build()
for i in ls:
meterdata = meter_service.transform(g)