ddtelemetry 1.0.0a2 → 1.0.0a3

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