ddtelemetry 1.0.0a1 → 1.0.0a2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/NEWS.md +6 -0
- data/README.md +143 -20
- data/Rakefile +5 -1
- data/lib/ddtelemetry.rb +6 -7
- data/lib/ddtelemetry/basic_counter.rb +15 -0
- data/lib/ddtelemetry/basic_summary.rb +15 -0
- data/lib/ddtelemetry/counter.rb +8 -6
- data/lib/ddtelemetry/metric.rb +30 -0
- data/lib/ddtelemetry/printer.rb +45 -0
- data/lib/ddtelemetry/stats.rb +54 -0
- data/lib/ddtelemetry/stopwatch.rb +11 -2
- data/lib/ddtelemetry/summary.rb +8 -45
- data/lib/ddtelemetry/version.rb +1 -1
- data/roadmap.md +7 -0
- data/samples/cache.rb +48 -0
- data/spec/ddtelemetry/basic_counter_spec.rb +20 -0
- data/spec/ddtelemetry/basic_summary_spec.rb +23 -0
- data/spec/ddtelemetry/counter_spec.rb +86 -5
- data/spec/ddtelemetry/stats_spec.rb +87 -0
- data/spec/ddtelemetry/stopwatch_spec.rb +19 -4
- data/spec/ddtelemetry/summary_spec.rb +51 -45
- data/spec/ddtelemetry_spec.rb +0 -25
- data/spec/spec_helper.rb +1 -1
- metadata +12 -7
- data/lib/ddtelemetry/labelled_counter.rb +0 -35
- data/lib/ddtelemetry/labelled_summary.rb +0 -37
- data/lib/ddtelemetry/registry.rb +0 -18
- data/spec/ddtelemetry/labelled_counter_spec.rb +0 -94
- data/spec/ddtelemetry/labelled_summary_spec.rb +0 -78
@@ -3,66 +3,72 @@
|
|
3
3
|
describe DDTelemetry::Summary do
|
4
4
|
subject(:summary) { described_class.new }
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
6
|
+
describe '#get' do
|
7
|
+
subject { summary.get(:erb) }
|
8
|
+
|
9
|
+
before do
|
10
|
+
summary.observe(2.1, :erb)
|
11
|
+
summary.observe(4.1, :erb)
|
12
|
+
summary.observe(5.3, :haml)
|
10
13
|
end
|
11
14
|
|
12
|
-
it
|
13
|
-
|
14
|
-
|
15
|
+
it { is_expected.to be_a(DDTelemetry::Stats) }
|
16
|
+
|
17
|
+
its(:sum) { is_expected.to eq(2.1 + 4.1) }
|
18
|
+
its(:count) { is_expected.to eq(2) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe '#labels' do
|
22
|
+
subject { summary.labels }
|
23
|
+
|
24
|
+
before do
|
25
|
+
summary.observe(2.1, :erb)
|
26
|
+
summary.observe(4.1, :erb)
|
27
|
+
summary.observe(5.3, :haml)
|
15
28
|
end
|
16
29
|
|
17
|
-
it
|
18
|
-
|
19
|
-
|
30
|
+
it { is_expected.to contain_exactly(:haml, :erb) }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe '#each' do
|
34
|
+
subject do
|
35
|
+
{}.tap do |res|
|
36
|
+
summary.each { |label, stats| res[label] = stats.avg.round(2) }
|
37
|
+
end
|
20
38
|
end
|
21
39
|
|
22
|
-
|
23
|
-
|
24
|
-
|
40
|
+
before do
|
41
|
+
summary.observe(2.1, :erb)
|
42
|
+
summary.observe(4.1, :erb)
|
43
|
+
summary.observe(5.3, :haml)
|
25
44
|
end
|
26
45
|
|
27
|
-
|
28
|
-
end
|
46
|
+
it { is_expected.to eq(haml: 5.3, erb: 3.1) }
|
29
47
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
its(:count) { is_expected.to eq(1) }
|
34
|
-
its(:sum) { is_expected.to eq(2.1) }
|
35
|
-
its(:avg) { is_expected.to eq(2.1) }
|
36
|
-
its(:min) { is_expected.to eq(2.1) }
|
37
|
-
its(:max) { is_expected.to eq(2.1) }
|
38
|
-
|
39
|
-
it 'has proper quantiles' do
|
40
|
-
expect(subject.quantile(0.00)).to eq(2.1)
|
41
|
-
expect(subject.quantile(0.25)).to eq(2.1)
|
42
|
-
expect(subject.quantile(0.50)).to eq(2.1)
|
43
|
-
expect(subject.quantile(0.90)).to eq(2.1)
|
44
|
-
expect(subject.quantile(0.99)).to eq(2.1)
|
48
|
+
it 'is enumerable' do
|
49
|
+
expect(summary.map { |_label, stats| stats.sum }.sort)
|
50
|
+
.to eq([5.3, 2.1 + 4.1])
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
48
|
-
|
54
|
+
describe '#to_s' do
|
55
|
+
subject { summary.to_s }
|
56
|
+
|
49
57
|
before do
|
50
|
-
|
51
|
-
|
58
|
+
summary.observe(2.1, :erb)
|
59
|
+
summary.observe(4.1, :erb)
|
60
|
+
summary.observe(5.3, :haml)
|
52
61
|
end
|
53
62
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
expect(subject.
|
63
|
-
expect(subject.quantile(0.50)).to be_within(0.000001).of(3.1)
|
64
|
-
expect(subject.quantile(0.90)).to be_within(0.000001).of(3.9)
|
65
|
-
expect(subject.quantile(0.99)).to be_within(0.000001).of(4.08)
|
63
|
+
it 'returns table' do
|
64
|
+
expected = <<~TABLE
|
65
|
+
│ count min .50 .90 .95 max tot
|
66
|
+
─────┼────────────────────────────────────────────────
|
67
|
+
erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
|
68
|
+
haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
|
69
|
+
TABLE
|
70
|
+
|
71
|
+
expect(subject.strip).to eq(expected.strip)
|
66
72
|
end
|
67
73
|
end
|
68
74
|
end
|
data/spec/ddtelemetry_spec.rb
CHANGED
@@ -4,29 +4,4 @@ describe DDTelemetry do
|
|
4
4
|
it 'has a version number' do
|
5
5
|
expect(DDTelemetry::VERSION).not_to be nil
|
6
6
|
end
|
7
|
-
|
8
|
-
subject { described_class.new }
|
9
|
-
|
10
|
-
example do
|
11
|
-
expect(subject.counter(:filters).values).to eq({})
|
12
|
-
expect(subject.counter(:filters).get(:erb).value).to eq(0)
|
13
|
-
expect(subject.counter(:filters).value(:erb)).to eq(0)
|
14
|
-
|
15
|
-
subject.counter(:filters).increment(:erb)
|
16
|
-
expect(subject.counter(:filters).values).to eq(erb: 1)
|
17
|
-
expect(subject.counter(:filters).get(:erb).value).to eq(1)
|
18
|
-
expect(subject.counter(:filters).value(:erb)).to eq(1)
|
19
|
-
end
|
20
|
-
|
21
|
-
example do
|
22
|
-
subject.summary(:filters).observe(0.1, :erb)
|
23
|
-
expect(subject.summary(:filters).quantile(0.0, :erb)).to be_within(0.00001).of(0.1)
|
24
|
-
expect(subject.summary(:filters).quantile(0.5, :erb)).to be_within(0.00001).of(0.1)
|
25
|
-
expect(subject.summary(:filters).quantile(1.0, :erb)).to be_within(0.00001).of(0.1)
|
26
|
-
|
27
|
-
subject.summary(:filters).observe(1.1, :erb)
|
28
|
-
expect(subject.summary(:filters).quantile(0.0, :erb)).to be_within(0.00001).of(0.1)
|
29
|
-
expect(subject.summary(:filters).quantile(0.5, :erb)).to be_within(0.00001).of(0.6)
|
30
|
-
expect(subject.summary(:filters).quantile(1.0, :erb)).to be_within(0.00001).of(1.1)
|
31
|
-
end
|
32
7
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ddtelemetry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.0a2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Defreyne
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-12-
|
11
|
+
date: 2017-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description:
|
14
14
|
email:
|
@@ -29,18 +29,23 @@ files:
|
|
29
29
|
- Rakefile
|
30
30
|
- ddtelemetry.gemspec
|
31
31
|
- lib/ddtelemetry.rb
|
32
|
+
- lib/ddtelemetry/basic_counter.rb
|
33
|
+
- lib/ddtelemetry/basic_summary.rb
|
32
34
|
- lib/ddtelemetry/counter.rb
|
33
|
-
- lib/ddtelemetry/
|
34
|
-
- lib/ddtelemetry/
|
35
|
-
- lib/ddtelemetry/
|
35
|
+
- lib/ddtelemetry/metric.rb
|
36
|
+
- lib/ddtelemetry/printer.rb
|
37
|
+
- lib/ddtelemetry/stats.rb
|
36
38
|
- lib/ddtelemetry/stopwatch.rb
|
37
39
|
- lib/ddtelemetry/summary.rb
|
38
40
|
- lib/ddtelemetry/table.rb
|
39
41
|
- lib/ddtelemetry/version.rb
|
42
|
+
- roadmap.md
|
43
|
+
- samples/cache.rb
|
40
44
|
- scripts/release
|
45
|
+
- spec/ddtelemetry/basic_counter_spec.rb
|
46
|
+
- spec/ddtelemetry/basic_summary_spec.rb
|
41
47
|
- spec/ddtelemetry/counter_spec.rb
|
42
|
-
- spec/ddtelemetry/
|
43
|
-
- spec/ddtelemetry/labelled_summary_spec.rb
|
48
|
+
- spec/ddtelemetry/stats_spec.rb
|
44
49
|
- spec/ddtelemetry/stopwatch_spec.rb
|
45
50
|
- spec/ddtelemetry/summary_spec.rb
|
46
51
|
- spec/ddtelemetry/table_spec.rb
|
@@ -1,35 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DDTelemetry
|
4
|
-
class LabelledCounter
|
5
|
-
def initialize
|
6
|
-
@counters = {}
|
7
|
-
end
|
8
|
-
|
9
|
-
def increment(label)
|
10
|
-
get(label).increment
|
11
|
-
end
|
12
|
-
|
13
|
-
def get(label)
|
14
|
-
@counters.fetch(label) { @counters[label] = Counter.new }
|
15
|
-
end
|
16
|
-
|
17
|
-
def empty?
|
18
|
-
@counters.empty?
|
19
|
-
end
|
20
|
-
|
21
|
-
def value(label)
|
22
|
-
get(label).value
|
23
|
-
end
|
24
|
-
|
25
|
-
def values
|
26
|
-
@counters.each_with_object({}) do |(label, counter), res|
|
27
|
-
res[label] = counter.value
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def map
|
32
|
-
@counters.map { |(label, counter)| yield(label, counter) }
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DDTelemetry
|
4
|
-
class LabelledSummary
|
5
|
-
def initialize
|
6
|
-
@summaries = {}
|
7
|
-
end
|
8
|
-
|
9
|
-
def observe(value, label)
|
10
|
-
get(label).observe(value)
|
11
|
-
end
|
12
|
-
|
13
|
-
def get(label)
|
14
|
-
@summaries.fetch(label) { @summaries[label] = Summary.new }
|
15
|
-
end
|
16
|
-
|
17
|
-
def empty?
|
18
|
-
@summaries.empty?
|
19
|
-
end
|
20
|
-
|
21
|
-
def quantile(fraction, label)
|
22
|
-
get(label).quantile(fraction)
|
23
|
-
end
|
24
|
-
|
25
|
-
def map
|
26
|
-
@summaries.map { |(label, summary)| yield(label, summary) }
|
27
|
-
end
|
28
|
-
|
29
|
-
# TODO: add quantiles(fraction)
|
30
|
-
# TODO: add min(label)
|
31
|
-
# TODO: add mins
|
32
|
-
# TODO: add max(label)
|
33
|
-
# TODO: add maxs
|
34
|
-
# TODO: add sum(label)
|
35
|
-
# TODO: add sums
|
36
|
-
end
|
37
|
-
end
|
data/lib/ddtelemetry/registry.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module DDTelemetry
|
4
|
-
class Registry
|
5
|
-
def initialize
|
6
|
-
@counters = {}
|
7
|
-
@summaries = {}
|
8
|
-
end
|
9
|
-
|
10
|
-
def counter(name)
|
11
|
-
@counters.fetch(name) { @counters[name] = LabelledCounter.new }
|
12
|
-
end
|
13
|
-
|
14
|
-
def summary(name)
|
15
|
-
@summaries.fetch(name) { @summaries[name] = LabelledSummary.new }
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,94 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe DDTelemetry::LabelledCounter do
|
4
|
-
subject(:counter) { described_class.new }
|
5
|
-
|
6
|
-
describe 'new counter' do
|
7
|
-
it 'starts at 0' do
|
8
|
-
expect(subject.value(:erb)).to eq(0)
|
9
|
-
expect(subject.value(:haml)).to eq(0)
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'has no values' do
|
13
|
-
expect(subject.values).to eq({})
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe '#increment' do
|
18
|
-
subject { counter.increment(:erb) }
|
19
|
-
|
20
|
-
it 'increments the matching value' do
|
21
|
-
expect { subject }
|
22
|
-
.to change { counter.value(:erb) }
|
23
|
-
.from(0)
|
24
|
-
.to(1)
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'does not increment any other value' do
|
28
|
-
expect(counter.value(:haml)).to eq(0)
|
29
|
-
expect { subject }
|
30
|
-
.not_to change { counter.value(:haml) }
|
31
|
-
end
|
32
|
-
|
33
|
-
it 'correctly changes #values' do
|
34
|
-
expect { subject }
|
35
|
-
.to change { counter.values }
|
36
|
-
.from({})
|
37
|
-
.to(erb: 1)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
describe '#get' do
|
42
|
-
subject { counter.get(:erb) }
|
43
|
-
|
44
|
-
context 'not incremented' do
|
45
|
-
its(:value) { is_expected.to eq(0) }
|
46
|
-
end
|
47
|
-
|
48
|
-
context 'incremented' do
|
49
|
-
before { counter.increment(:erb) }
|
50
|
-
its(:value) { is_expected.to eq(1) }
|
51
|
-
end
|
52
|
-
|
53
|
-
context 'other incremented' do
|
54
|
-
before { counter.increment(:haml) }
|
55
|
-
its(:value) { is_expected.to eq(0) }
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe '#empty?' do
|
60
|
-
subject { counter.empty? }
|
61
|
-
|
62
|
-
context 'not incremented' do
|
63
|
-
it { is_expected.to be }
|
64
|
-
end
|
65
|
-
|
66
|
-
context 'incremented' do
|
67
|
-
before { counter.increment(:erb) }
|
68
|
-
it { is_expected.not_to be }
|
69
|
-
end
|
70
|
-
end
|
71
|
-
|
72
|
-
describe '#map' do
|
73
|
-
subject { counter.map { |label, counter| [label, counter.value] } }
|
74
|
-
|
75
|
-
context 'not incremented' do
|
76
|
-
it { is_expected.to be_empty }
|
77
|
-
end
|
78
|
-
|
79
|
-
context 'incremented once' do
|
80
|
-
before { counter.increment(:erb) }
|
81
|
-
it { is_expected.to eq [[:erb, 1]] }
|
82
|
-
end
|
83
|
-
|
84
|
-
context 'both incremental multiple times' do
|
85
|
-
before do
|
86
|
-
counter.increment(:erb)
|
87
|
-
counter.increment(:erb)
|
88
|
-
counter.increment(:haml)
|
89
|
-
end
|
90
|
-
|
91
|
-
it { is_expected.to eq [[:erb, 2], [:haml, 1]] }
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
@@ -1,78 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
describe DDTelemetry::LabelledSummary do
|
4
|
-
subject(:summary) { described_class.new }
|
5
|
-
|
6
|
-
describe '#empty?' do
|
7
|
-
subject { summary.empty? }
|
8
|
-
|
9
|
-
context 'empty summary' do
|
10
|
-
it { is_expected.to be }
|
11
|
-
end
|
12
|
-
|
13
|
-
context 'some observations' do
|
14
|
-
before do
|
15
|
-
summary.observe(7.2, :erb)
|
16
|
-
summary.observe(5.3, :erb)
|
17
|
-
summary.observe(3.0, :haml)
|
18
|
-
end
|
19
|
-
|
20
|
-
it { is_expected.not_to be }
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
describe '#get' do
|
25
|
-
subject { summary.get(:erb) }
|
26
|
-
|
27
|
-
context 'empty summary' do
|
28
|
-
its(:count) { is_expected.to eq(0) }
|
29
|
-
end
|
30
|
-
|
31
|
-
context 'one observation with that label' do
|
32
|
-
before { summary.observe(0.1, :erb) }
|
33
|
-
its(:count) { is_expected.to eq(1) }
|
34
|
-
end
|
35
|
-
|
36
|
-
context 'one observation with a different label' do
|
37
|
-
before { summary.observe(0.1, :haml) }
|
38
|
-
its(:count) { is_expected.to eq(0) }
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe '#map' do
|
43
|
-
before do
|
44
|
-
subject.observe(2.1, :erb)
|
45
|
-
subject.observe(4.1, :erb)
|
46
|
-
subject.observe(5.3, :haml)
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'yields label and summary' do
|
50
|
-
res = subject.map { |label, summary| [label, summary.avg.round(3)] }
|
51
|
-
expect(res).to eql([[:erb, 3.1], [:haml, 5.3]])
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
describe '#quantile' do
|
56
|
-
before do
|
57
|
-
subject.observe(2.1, :erb)
|
58
|
-
subject.observe(4.1, :erb)
|
59
|
-
subject.observe(5.3, :haml)
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'has proper quantiles for :erb' do
|
63
|
-
expect(subject.quantile(0.00, :erb)).to be_within(0.000001).of(2.1)
|
64
|
-
expect(subject.quantile(0.25, :erb)).to be_within(0.000001).of(2.6)
|
65
|
-
expect(subject.quantile(0.50, :erb)).to be_within(0.000001).of(3.1)
|
66
|
-
expect(subject.quantile(0.90, :erb)).to be_within(0.000001).of(3.9)
|
67
|
-
expect(subject.quantile(0.99, :erb)).to be_within(0.000001).of(4.08)
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'has proper quantiles for :erb' do
|
71
|
-
expect(subject.quantile(0.00, :haml)).to be_within(0.000001).of(5.3)
|
72
|
-
expect(subject.quantile(0.25, :haml)).to be_within(0.000001).of(5.3)
|
73
|
-
expect(subject.quantile(0.50, :haml)).to be_within(0.000001).of(5.3)
|
74
|
-
expect(subject.quantile(0.90, :haml)).to be_within(0.000001).of(5.3)
|
75
|
-
expect(subject.quantile(0.99, :haml)).to be_within(0.000001).of(5.3)
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|