ddtelemetry 1.0.0a2 → 1.0.0a3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4fb967335678607cb86deb8c2b48446735a957230cb9349ce3858d21233d002b
4
- data.tar.gz: eadc2b1b9a1737564dbd38abc68f4a59c320d5cdbeb13ed3d0df0fe7c5c3a3f3
3
+ metadata.gz: 596a86f112eb74d0267f7a243d82a1ab9963a951999907a0c08f3a410e6b1a46
4
+ data.tar.gz: 67293156e3b3edcc33a37bda53c9bc0033c1883db5ea4b95fe05f7c0544337c7
5
5
  SHA512:
6
- metadata.gz: 1474fb4050d596b8f1fed72f80760e63e37f42a99327c9acdd57d7af5afe3139f096f8067437ca5d297c52ea3d4847117aeacb8ffc8d9b142f753f47495491e9
7
- data.tar.gz: 6ac9b71a55dd640a652a762c6974a6260a7448cfc94d1a30cd4f23a340a75237b7fba521049228a5ebc0b3287837434da604224253f6df693d8162e2bba3262f
6
+ metadata.gz: 3f57821fff43b9f69f0cef5098b7d47407a789b11647e2733e9ed37bb30378258f22eb6bef6628198ab7752d87a3b820ebcd98ef5a3483534eca9a9ea0663b5c
7
+ data.tar.gz: edb875daf44acaa9493119afe7918470c60fad95855be3154d4a05633daea0cceaf1b23b77a620f62fe1b8cf3626d6d51e0af2505a997a1f4deeb94c5f67706c
data/NEWS.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # DDTelemetry news
2
2
 
3
+ ## 1.0.0a3 (2017-12-25)
4
+
5
+ Changes:
6
+
7
+ * Made labels be a hash
8
+
3
9
  ## 1.0.0a2 (2017-12-18)
4
10
 
5
11
  Changes:
data/README.md CHANGED
@@ -44,16 +44,16 @@ class Cache
44
44
  end
45
45
 
46
46
  def []=(key, value)
47
- @counter.increment(:set)
47
+ @counter.increment(type: :set)
48
48
 
49
49
  @map[key] = value
50
50
  end
51
51
 
52
52
  def [](key)
53
53
  if @map.key?(key)
54
- @counter.increment(:get_hit)
54
+ @counter.increment(type: :get_hit)
55
55
  else
56
- @counter.increment(:get_miss)
56
+ @counter.increment(type: :get_miss)
57
57
  end
58
58
 
59
59
  @map[key]
@@ -77,9 +77,9 @@ cache['greeting']
77
77
  Finally, get the recorded telemetry values:
78
78
 
79
79
  ```ruby
80
- cache.counter.get(:set) # => 1
81
- cache.counter.get(:get_hit) # => 3
82
- cache.counter.get(:get_miss) # => 2
80
+ cache.counter.get(type: :set) # => 1
81
+ cache.counter.get(type: :get_hit) # => 3
82
+ cache.counter.get(type: :get_miss) # => 2
83
83
  ```
84
84
 
85
85
  Or even print all stats:
@@ -89,11 +89,11 @@ puts cache.counter
89
89
  ```
90
90
 
91
91
  ```
92
- │ count
93
- ─────────┼──────
94
- get_miss │ 2
95
- set │ 1
96
- get_hit │ 3
92
+ │ count
93
+ ──────────────┼──────
94
+ type=get_miss │ 2
95
+ type=set │ 1
96
+ type=get_hit │ 3
97
97
  ```
98
98
 
99
99
  ## Installation
@@ -120,15 +120,13 @@ _DDTelemetry_ provides two metric types:
120
120
 
121
121
  * A **summary** records observations, and provides functionality for describing the distribution of the observations through quantiles. Examples: outgoing request durations, size of written files, …
122
122
 
123
- Each metric is recorded with a label, which is a free-form object that is useful to further refine the kind of data that is being recorded. For example:
123
+ Each metric is recorded with a label, which is a hash that is useful to further refine the kind of data that is being recorded. For example:
124
124
 
125
125
  ```ruby
126
- cache_hits_counter.increment(:file_cache)
127
- request_durations_summary.observe(:weather_api, 1.07)
126
+ cache_hits_counter.increment(target: :file_cache)
127
+ request_durations_summary.observe(1.07, api: :weather)
128
128
  ```
129
129
 
130
- NOTE: Labels will likely change to become key-value pairs in a future version of DDTelemetry.
131
-
132
130
  ### Counters
133
131
 
134
132
  To create a counter, instantiate `DDTelemetry::Counter`:
@@ -140,13 +138,13 @@ counter = DDTelemetry::Counter.new
140
138
  To increment a counter, call `#increment` with a label:
141
139
 
142
140
  ```ruby
143
- counter.increment(:file_cache)
141
+ counter.increment(target: :file_cache)
144
142
  ```
145
143
 
146
144
  To get the value for a certain label, use `#get`:
147
145
 
148
146
  ```ruby
149
- counter.get(:file_cache)
147
+ counter.get(target: :file_cache)
150
148
  # => 1
151
149
  ```
152
150
 
@@ -158,18 +156,18 @@ To create a summary, instantiate `DDTelemetry::Summary`:
158
156
  summary = DDTelemetry::Summary.new
159
157
  ```
160
158
 
161
- To observe a value, call `#observe` with a label, along with the value to observe:
159
+ To observe a value, call `#observe` with the value to observe, along with a label:
162
160
 
163
161
  ```ruby
164
- summary.observe(:weather_api, 0.88)
165
- summary.observe(:weather_api, 1.07)
166
- summary.observe(:weather_api, 0.91)
162
+ summary.observe(0.88, api: :weather)
163
+ summary.observe(1.07, api: :weather)
164
+ summary.observe(0.91, api: :weather)
167
165
  ```
168
166
 
169
167
  To get the list of observations for a certain label, use `#get`, which will return a `DDTelemetry::Stats` instance:
170
168
 
171
169
  ```ruby
172
- summary.get(:weather_api)
170
+ summary.get(api: :weather)
173
171
  # => <DDTelemetry::Stats>
174
172
  ```
175
173
 
@@ -189,9 +187,9 @@ To print a metric, use `#to_s`. For example:
189
187
  ```ruby
190
188
  summary = DDTelemetry::Summary.new
191
189
 
192
- summary.observe(2.1, :erb)
193
- summary.observe(4.1, :erb)
194
- summary.observe(5.3, :haml)
190
+ summary.observe(2.1, filter: :erb)
191
+ summary.observe(4.1, filter: :erb)
192
+ summary.observe(5.3, filter: :haml)
195
193
 
196
194
  puts summary
197
195
  ```
@@ -199,10 +197,10 @@ puts summary
199
197
  Output:
200
198
 
201
199
  ```
202
- │ count min .50 .90 .95 max tot
203
- ─────┼────────────────────────────────────────────────
204
- erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
205
- haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
200
+ │ count min .50 .90 .95 max tot
201
+ ────────────┼────────────────────────────────────────────────
202
+ filter=erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
203
+ filter=haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
206
204
  ```
207
205
 
208
206
  ### Stopwatch
@@ -3,10 +3,12 @@
3
3
  module DDTelemetry
4
4
  class Counter < Metric
5
5
  def increment(label)
6
+ validate_label(label)
6
7
  basic_metric_for(label, BasicCounter).increment
7
8
  end
8
9
 
9
10
  def get(label)
11
+ validate_label(label)
10
12
  basic_metric_for(label, BasicCounter).value
11
13
  end
12
14
 
@@ -26,5 +26,11 @@ module DDTelemetry
26
26
  def basic_metric_for(label, basic_class)
27
27
  @basic_metrics.fetch(label) { @basic_metrics[label] = basic_class.new }
28
28
  end
29
+
30
+ # @api private
31
+ def validate_label(label)
32
+ return if label.is_a?(Hash)
33
+ raise ArgumentError, 'label argument must be a hash'
34
+ end
29
35
  end
30
36
  end
@@ -12,6 +12,10 @@ module DDTelemetry
12
12
 
13
13
  private
14
14
 
15
+ def label_to_s(label)
16
+ label.to_a.sort.map { |pair| pair.join('=') }.join(' ')
17
+ end
18
+
15
19
  def table_for_summary(summary)
16
20
  headers = ['', 'count', 'min', '.50', '.90', '.95', 'max', 'tot']
17
21
 
@@ -26,7 +30,7 @@ module DDTelemetry
26
30
  tot = stats.sum
27
31
  max = stats.max
28
32
 
29
- [label.to_s, count.to_s] + [min, p50, p90, p95, max, tot].map { |r| format('%4.2f', r) }
33
+ [label_to_s(label), count.to_s] + [min, p50, p90, p95, max, tot].map { |r| format('%4.2f', r) }
30
34
  end
31
35
 
32
36
  [headers] + rows
@@ -36,7 +40,7 @@ module DDTelemetry
36
40
  headers = ['', 'count']
37
41
 
38
42
  rows = counter.labels.map do |label|
39
- [label.to_s, counter.get(label).to_s]
43
+ [label_to_s(label), counter.get(label).to_s]
40
44
  end
41
45
 
42
46
  [headers] + rows
@@ -3,10 +3,12 @@
3
3
  module DDTelemetry
4
4
  class Summary < Metric
5
5
  def observe(value, label)
6
+ validate_label(label)
6
7
  basic_metric_for(label, BasicSummary).observe(value)
7
8
  end
8
9
 
9
10
  def get(label)
11
+ validate_label(label)
10
12
  values = basic_metric_for(label, BasicSummary).values
11
13
  DDTelemetry::Stats.new(values)
12
14
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DDTelemetry
4
- VERSION = '1.0.0a2'
4
+ VERSION = '1.0.0a3'
5
5
  end
@@ -11,16 +11,16 @@ class Cache
11
11
  end
12
12
 
13
13
  def []=(key, value)
14
- @counter.increment(:set)
14
+ @counter.increment(type: :set)
15
15
 
16
16
  @map[key] = value
17
17
  end
18
18
 
19
19
  def [](key)
20
20
  if @map.key?(key)
21
- @counter.increment(:get_hit)
21
+ @counter.increment(type: :get_hit)
22
22
  else
23
- @counter.increment(:get_miss)
23
+ @counter.increment(type: :get_miss)
24
24
  end
25
25
 
26
26
  @map[key]
@@ -36,13 +36,13 @@ cache['greeting']
36
36
  cache['greeting']
37
37
  cache['greeting']
38
38
 
39
- p cache.counter.get(:set)
39
+ p cache.counter.get(type: :set)
40
40
  # => 1
41
41
 
42
- p cache.counter.get(:get_hit)
42
+ p cache.counter.get(type: :get_hit)
43
43
  # => 3
44
44
 
45
- p cache.counter.get(:get_miss)
45
+ p cache.counter.get(type: :get_miss)
46
46
  # => 2
47
47
 
48
48
  puts cache.counter
@@ -2,38 +2,27 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require 'fileutils'
5
+ require 'json'
5
6
  require 'octokit'
7
+ require 'shellwords'
8
+ require 'uri'
6
9
 
7
10
  def run(*args)
8
- puts 'I will execute the following:'
9
- puts ' ' + args.map { |a| a =~ /\s/ ? a.inspect : a }.join(' ')
10
- print 'Is this correct? [y/N] '
11
- res = gets
12
- unless res.strip.casecmp('y').zero?
13
- warn 'Answer was not Y; release aborted.'
14
- exit 1
15
- end
16
-
17
- system('echo', *args)
11
+ puts('<exec> ' + args.map { |s| Shellwords.escape(s) }.join(' '))
18
12
  system(*args)
19
-
20
- print 'Continue? [y/N] '
21
- res = gets
22
- unless res.strip.casecmp('y').zero?
23
- warn 'Answer was not Y; release aborted.'
24
- exit 1
25
- end
26
-
27
- true
28
13
  end
29
14
 
15
+ gem_name = 'ddtelemetry'
16
+ version_constant = 'DDTelemetry::VERSION'
17
+ gem_path = 'ddtelemetry'
18
+
30
19
  puts '=== Logging in to GitHub’s API…'
31
20
  client = Octokit::Client.new(netrc: true)
32
21
  puts
33
22
 
34
23
  puts '=== Deleting old *.gem files…'
35
24
  Dir['*.gem'].each do |fn|
36
- puts " #{fn}…"
25
+ puts "deleting #{fn}…"
37
26
  FileUtils.rm_f(fn)
38
27
  end
39
28
  puts
@@ -45,13 +34,41 @@ unless File.readlines('NEWS.md').drop(2).first =~ / \(\d{4}-\d{2}-\d{2}\)$/
45
34
  end
46
35
  puts
47
36
 
37
+ puts '=== Reading version…'
38
+ require "./lib/#{gem_path}/version"
39
+ version = eval(version_constant) # rubocop:disable Security/Eval
40
+ puts "Version = #{version}"
41
+ puts
42
+
48
43
  puts '=== Building new gem…'
49
44
  run('gem', 'build', 'ddtelemetry.gemspec')
50
45
  puts
51
46
 
52
- puts '=== Reading version…'
53
- require './lib/ddtelemetry/version'
54
- puts "Version = #{DDTelemetry::VERSION}"
47
+ puts '=== Verifying that gems were built properly…'
48
+ gem_filename = "#{gem_name}-#{version}.gem"
49
+ unless File.file?(gem_filename)
50
+ warn "Error: Could not find gem: #{gem_filename}"
51
+ exit 1
52
+ end
53
+ puts
54
+
55
+ puts '=== Verifying that gem version does not yet exist…'
56
+ url = URI.parse("https://rubygems.org/api/v1/versions/#{gem_name}.json")
57
+ response = Net::HTTP.get_response(url)
58
+ existing_versions =
59
+ case response.code
60
+ when '404'
61
+ []
62
+ when '200'
63
+ JSON.parse(response.body).map { |e| e.fetch('number') }
64
+ else
65
+ warn "Error: Couldn’t fetch version information for #{gem_name} (status #{response.code})"
66
+ exit 1
67
+ end
68
+ if existing_versions.include?(version)
69
+ warn "Error: #{gem_name} v#{version} already exists"
70
+ exit 1
71
+ end
55
72
  puts
56
73
 
57
74
  puts '=== Verifying that release does not yet exist…'
@@ -5,42 +5,50 @@ describe DDTelemetry::Counter do
5
5
 
6
6
  describe 'new counter' do
7
7
  it 'starts at 0' do
8
- expect(subject.get(:erb)).to eq(0)
9
- expect(subject.get(:haml)).to eq(0)
8
+ expect(subject.get(filter: :erb)).to eq(0)
9
+ expect(subject.get(filter: :haml)).to eq(0)
10
10
  end
11
11
  end
12
12
 
13
13
  describe '#increment' do
14
- subject { counter.increment(:erb) }
14
+ subject { counter.increment(filter: :erb) }
15
15
 
16
16
  it 'increments the matching value' do
17
17
  expect { subject }
18
- .to change { counter.get(:erb) }
18
+ .to change { counter.get(filter: :erb) }
19
19
  .from(0)
20
20
  .to(1)
21
21
  end
22
22
 
23
23
  it 'does not increment any other value' do
24
- expect(counter.get(:haml)).to eq(0)
24
+ expect(counter.get(filter: :haml)).to eq(0)
25
25
  expect { subject }
26
- .not_to change { counter.get(:haml) }
26
+ .not_to change { counter.get(filter: :haml) }
27
+ end
28
+
29
+ context 'non-hash label' do
30
+ subject { counter.increment('WRONG UGH') }
31
+
32
+ it 'errors' do
33
+ expect { subject }.to raise_error(ArgumentError, 'label argument must be a hash')
34
+ end
27
35
  end
28
36
  end
29
37
 
30
38
  describe '#get' do
31
- subject { counter.get(:erb) }
39
+ subject { counter.get(filter: :erb) }
32
40
 
33
41
  context 'not incremented' do
34
42
  it { is_expected.to eq(0) }
35
43
  end
36
44
 
37
45
  context 'incremented' do
38
- before { counter.increment(:erb) }
46
+ before { counter.increment(filter: :erb) }
39
47
  it { is_expected.to eq(1) }
40
48
  end
41
49
 
42
50
  context 'other incremented' do
43
- before { counter.increment(:haml) }
51
+ before { counter.increment(filter: :haml) }
44
52
  it { is_expected.to eq(0) }
45
53
  end
46
54
  end
@@ -49,12 +57,12 @@ describe DDTelemetry::Counter do
49
57
  subject { counter.labels }
50
58
 
51
59
  before do
52
- counter.increment(:erb)
53
- counter.increment(:erb)
54
- counter.increment(:haml)
60
+ counter.increment(filter: :erb)
61
+ counter.increment(filter: :erb)
62
+ counter.increment(filter: :haml)
55
63
  end
56
64
 
57
- it { is_expected.to contain_exactly(:haml, :erb) }
65
+ it { is_expected.to match_array([{ filter: :haml }, { filter: :erb }]) }
58
66
  end
59
67
 
60
68
  describe '#each' do
@@ -65,12 +73,12 @@ describe DDTelemetry::Counter do
65
73
  end
66
74
 
67
75
  before do
68
- counter.increment(:erb)
69
- counter.increment(:erb)
70
- counter.increment(:haml)
76
+ counter.increment(filter: :erb)
77
+ counter.increment(filter: :erb)
78
+ counter.increment(filter: :haml)
71
79
  end
72
80
 
73
- it { is_expected.to eq(haml: 1, erb: 2) }
81
+ it { is_expected.to eq({ filter: :haml } => 1, { filter: :erb } => 2) }
74
82
 
75
83
  it 'is enumerable' do
76
84
  expect(counter.map { |_label, count| count }.sort)
@@ -82,17 +90,17 @@ describe DDTelemetry::Counter do
82
90
  subject { counter.to_s }
83
91
 
84
92
  before do
85
- counter.increment(:erb)
86
- counter.increment(:erb)
87
- counter.increment(:haml)
93
+ counter.increment(filter: :erb)
94
+ counter.increment(filter: :erb)
95
+ counter.increment(filter: :haml)
88
96
  end
89
97
 
90
98
  it 'returns table' do
91
99
  expected = <<~TABLE
92
- │ count
93
- ─────┼──────
94
- erb │ 2
95
- haml │ 1
100
+ │ count
101
+ ────────────┼──────
102
+ filter=erb │ 2
103
+ filter=haml │ 1
96
104
  TABLE
97
105
 
98
106
  expect(subject.strip).to eq(expected.strip)
@@ -3,13 +3,23 @@
3
3
  describe DDTelemetry::Summary do
4
4
  subject(:summary) { described_class.new }
5
5
 
6
+ describe '#observe' do
7
+ context 'non-hash label' do
8
+ subject { summary.observe(1.23, 'WRONG UGH') }
9
+
10
+ it 'errors' do
11
+ expect { subject }.to raise_error(ArgumentError, 'label argument must be a hash')
12
+ end
13
+ end
14
+ end
15
+
6
16
  describe '#get' do
7
- subject { summary.get(:erb) }
17
+ subject { summary.get(filter: :erb) }
8
18
 
9
19
  before do
10
- summary.observe(2.1, :erb)
11
- summary.observe(4.1, :erb)
12
- summary.observe(5.3, :haml)
20
+ summary.observe(2.1, filter: :erb)
21
+ summary.observe(4.1, filter: :erb)
22
+ summary.observe(5.3, filter: :haml)
13
23
  end
14
24
 
15
25
  it { is_expected.to be_a(DDTelemetry::Stats) }
@@ -22,12 +32,12 @@ describe DDTelemetry::Summary do
22
32
  subject { summary.labels }
23
33
 
24
34
  before do
25
- summary.observe(2.1, :erb)
26
- summary.observe(4.1, :erb)
27
- summary.observe(5.3, :haml)
35
+ summary.observe(2.1, filter: :erb)
36
+ summary.observe(4.1, filter: :erb)
37
+ summary.observe(5.3, filter: :haml)
28
38
  end
29
39
 
30
- it { is_expected.to contain_exactly(:haml, :erb) }
40
+ it { is_expected.to match_array([{ filter: :haml }, { filter: :erb }]) }
31
41
  end
32
42
 
33
43
  describe '#each' do
@@ -38,12 +48,12 @@ describe DDTelemetry::Summary do
38
48
  end
39
49
 
40
50
  before do
41
- summary.observe(2.1, :erb)
42
- summary.observe(4.1, :erb)
43
- summary.observe(5.3, :haml)
51
+ summary.observe(2.1, filter: :erb)
52
+ summary.observe(4.1, filter: :erb)
53
+ summary.observe(5.3, filter: :haml)
44
54
  end
45
55
 
46
- it { is_expected.to eq(haml: 5.3, erb: 3.1) }
56
+ it { is_expected.to eq({ filter: :haml } => 5.3, { filter: :erb } => 3.1) }
47
57
 
48
58
  it 'is enumerable' do
49
59
  expect(summary.map { |_label, stats| stats.sum }.sort)
@@ -55,17 +65,17 @@ describe DDTelemetry::Summary do
55
65
  subject { summary.to_s }
56
66
 
57
67
  before do
58
- summary.observe(2.1, :erb)
59
- summary.observe(4.1, :erb)
60
- summary.observe(5.3, :haml)
68
+ summary.observe(2.1, filter: :erb)
69
+ summary.observe(4.1, filter: :erb)
70
+ summary.observe(5.3, filter: :haml)
61
71
  end
62
72
 
63
73
  it 'returns table' do
64
74
  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
75
+ │ count min .50 .90 .95 max tot
76
+ ────────────┼────────────────────────────────────────────────
77
+ filter=erb │ 2 2.10 3.10 3.90 4.00 4.10 6.20
78
+ filter=haml │ 1 5.30 5.30 5.30 5.30 5.30 5.30
69
79
  TABLE
70
80
 
71
81
  expect(subject.strip).to eq(expected.strip)
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.0a2
4
+ version: 1.0.0a3
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-18 00:00:00.000000000 Z
11
+ date: 2017-12-25 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description:
14
14
  email:
@@ -71,7 +71,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
71
71
  version: 1.3.1
72
72
  requirements: []
73
73
  rubyforge_project:
74
- rubygems_version: 2.7.3
74
+ rubygems_version: 2.7.4
75
75
  signing_key:
76
76
  specification_version: 4
77
77
  summary: Non-timeseries telemetry