ddtelemetry 1.0.0a1 → 1.0.0a2

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,66 +3,72 @@
3
3
  describe DDTelemetry::Summary do
4
4
  subject(:summary) { described_class.new }
5
5
 
6
- context 'no observations' do
7
- it 'errors on #min' do
8
- expect { subject.min }
9
- .to raise_error(DDTelemetry::Summary::EmptySummaryError)
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 'errors on #max' do
13
- expect { subject.max }
14
- .to raise_error(DDTelemetry::Summary::EmptySummaryError)
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 'errors on #avg' do
18
- expect { subject.avg }
19
- .to raise_error(DDTelemetry::Summary::EmptySummaryError)
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
- it 'errors on #sum' do
23
- expect { subject.sum }
24
- .to raise_error(DDTelemetry::Summary::EmptySummaryError)
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
- its(:count) { is_expected.to eq(0) }
28
- end
46
+ it { is_expected.to eq(haml: 5.3, erb: 3.1) }
29
47
 
30
- context 'one observation' do
31
- before { subject.observe(2.1) }
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
- context 'two observations' do
54
+ describe '#to_s' do
55
+ subject { summary.to_s }
56
+
49
57
  before do
50
- subject.observe(2.1)
51
- subject.observe(4.1)
58
+ summary.observe(2.1, :erb)
59
+ summary.observe(4.1, :erb)
60
+ summary.observe(5.3, :haml)
52
61
  end
53
62
 
54
- its(:count) { is_expected.to be_within(0.000001).of(2) }
55
- its(:sum) { is_expected.to be_within(0.000001).of(6.2) }
56
- its(:avg) { is_expected.to be_within(0.000001).of(3.1) }
57
- its(:min) { is_expected.to be_within(0.000001).of(2.1) }
58
- its(:max) { is_expected.to be_within(0.000001).of(4.1) }
59
-
60
- it 'has proper quantiles' do
61
- expect(subject.quantile(0.00)).to be_within(0.000001).of(2.1)
62
- expect(subject.quantile(0.25)).to be_within(0.000001).of(2.6)
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
@@ -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
@@ -14,6 +14,6 @@ require 'timecop'
14
14
 
15
15
  RSpec.configure do |c|
16
16
  c.fuubar_progress_bar_options = {
17
- format: '%c/%C |<%b>%i| %p%%',
17
+ format: '%c/%C |<%b>%i| %p%%', # rubocop:disable Style/FormatStringToken
18
18
  }
19
19
  end
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.0a1
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-02 00:00:00.000000000 Z
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/labelled_counter.rb
34
- - lib/ddtelemetry/labelled_summary.rb
35
- - lib/ddtelemetry/registry.rb
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/labelled_counter_spec.rb
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
@@ -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