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.
@@ -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