vitals 0.3.0 → 0.4.0

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
  SHA1:
3
- metadata.gz: 144354fc633911fa91781b4ceefc10e9e8b0f7f7
4
- data.tar.gz: 72b1133aa8c4ac7aa9bdcc59d69781f946ef9551
3
+ metadata.gz: 18d3c258a6d33421ef4c97c17a3a3fab5446e687
4
+ data.tar.gz: a901838061bdc54a96e47777a54fb659db3adb20
5
5
  SHA512:
6
- metadata.gz: 037a86c00abc7b8e1206f3ce651538a93d177b26853c57dda4f0d1511f57555b293bb72da24f9e930c8bfa1099686d92face5faf397b5de925e4877f34432e71
7
- data.tar.gz: 0abeedcabd6f8a33403b5c894555b5729bb3b2fd1d960eaa01d22469217837d98ba6c3a976a0373bc9b5e39fe772a9839953cb6e82dec4002b079e1cf37dacc2
6
+ metadata.gz: 5d9e8a208a0f930db9ede6a3db245bc793ba45dec41aadabaa039588e4cd96b24333fde8c5b85d2355691c3081e73837e4f19b85f971e0b65a745de5282cab8c
7
+ data.tar.gz: 7043d594b8c34a347792c89b4b072c8852d2612353d4d16b9274e679bc45eed6e7cc6bbe81c10764c8c0b24d0467c4c08e1e4d2fe4a45a51a5157076ba6ebf4c
data/.gitignore CHANGED
@@ -5,3 +5,4 @@ test/dummy/db/*.sqlite3
5
5
  test/dummy/log/*.log
6
6
  test/dummy/tmp/coverage/
7
7
  coverage/
8
+ .byebug_history
data/Gemfile.lock CHANGED
@@ -20,6 +20,7 @@ GEM
20
20
  thread_safe (~> 0.3, >= 0.3.1)
21
21
  benchmark-ips (2.5.0)
22
22
  builder (3.2.2)
23
+ byebug (8.2.2)
23
24
  coderay (1.1.1)
24
25
  coercible (1.0.0)
25
26
  descendants_tracker (~> 0.0.1)
@@ -141,6 +142,7 @@ DEPENDENCIES
141
142
  activesupport (~> 4.2.6)
142
143
  benchmark-ips (~> 2.5.0)
143
144
  bundler (~> 1.11)
145
+ byebug (~> 8.2.2)
144
146
  coveralls (~> 0.8.13)
145
147
  grape (~> 0.15.0)
146
148
  guard-minitest (~> 2.4.4)
@@ -10,3 +10,6 @@ Vitals::Integrations::Notifications::ActionController.subscribe!
10
10
  require 'vitals/integrations/notifications/active_job'
11
11
  Vitals::Integrations::Notifications::ActiveJob.subscribe!
12
12
 
13
+ require 'vitals/integrations/rack/requests'
14
+ Rails.application.config.middleware.insert_before "Rails::Rack::Logger", Vitals::Integrations::Rack::Requests
15
+
@@ -29,6 +29,21 @@ class VitalsFlowTest < ActionDispatch::IntegrationTest
29
29
  TestLogSubscriber.attach_to :action_controller
30
30
  end
31
31
 
32
+ test "get posts with rack middleware" do
33
+ get '/posts'
34
+ metrics = %w{
35
+ controllers.posts_index_get.200.all
36
+ controllers.posts_index_get.200.db
37
+ controllers.posts_index_get.200.view
38
+ requests.posts_index_get.200
39
+ }
40
+
41
+ assert_timings Vitals.reporter.reports,
42
+ metrics,
43
+ TestLogSubscriber.controller_times+[-1],
44
+ 60
45
+ end
46
+
32
47
  test "get new which also triggers a job" do
33
48
  get '/posts/new'
34
49
 
@@ -37,11 +52,12 @@ class VitalsFlowTest < ActionDispatch::IntegrationTest
37
52
  controllers.posts_new_get.200.all
38
53
  controllers.posts_new_get.200.db
39
54
  controllers.posts_new_get.200.view
55
+ requests.posts_new_get.200
40
56
  }
41
57
 
42
58
  assert_timings Vitals.reporter.reports,
43
59
  metrics,
44
- [3]+TestLogSubscriber.controller_times,
60
+ [-1]+TestLogSubscriber.controller_times+[-1],
45
61
  60
46
62
 
47
63
  end
@@ -53,11 +69,12 @@ class VitalsFlowTest < ActionDispatch::IntegrationTest
53
69
  controllers.posts_index_get.200.all
54
70
  controllers.posts_index_get.200.db
55
71
  controllers.posts_index_get.200.view
72
+ requests.posts_index_get.200
56
73
  }
57
74
 
58
75
  assert_timings Vitals.reporter.reports,
59
76
  metrics,
60
- TestLogSubscriber.controller_times,
77
+ TestLogSubscriber.controller_times+[-1],
61
78
  80
62
79
  end
63
80
 
@@ -67,11 +84,12 @@ class VitalsFlowTest < ActionDispatch::IntegrationTest
67
84
  metrics = %w{
68
85
  controllers.posts_create_post.302.all
69
86
  controllers.posts_create_post.302.db
87
+ requests.posts_create_post.302
70
88
  }
71
89
 
72
90
  assert_timings Vitals.reporter.reports,
73
91
  metrics,
74
- TestLogSubscriber.controller_times,
92
+ TestLogSubscriber.controller_times+[-1],
75
93
  80
76
94
  end
77
95
 
@@ -4,13 +4,13 @@ def assert_timings(reports, metrics, times, delta=30)
4
4
  expect(reports.count).to eq metrics.count
5
5
  metrics.zip(times).each_with_index do |(m,v), i|
6
6
  expect(reports[i][:timing]).to eq m
7
- expect(reports[i][:val]).to be_within(delta).of(v)
7
+ expect(reports[i][:val]).to(be_within(delta).of(v)) if v >=0
8
8
  end
9
9
  else
10
10
  assert_equal reports.count, metrics.count
11
11
  metrics.zip(times).each_with_index do |(m,v), i|
12
12
  assert_equal reports[i][:timing], m
13
- assert_in_delta reports[i][:val], v, delta
13
+ assert_in_delta(reports[i][:val], v, delta) if v >=0
14
14
  end
15
15
  end
16
16
  end
@@ -11,16 +11,12 @@ module Vitals::Integrations::Notifications
11
11
  def self.handle(name, started, finished, unique_id, payload)
12
12
  endpoint = payload[:endpoint]
13
13
  route = endpoint.route
14
- version = route.route_version
15
14
  method = route.route_method.downcase
16
15
 
17
- path = route.route_path.dup
18
- path.sub!(/\(\..*\)$/, '')
19
- path.sub!(":version", version) if version
20
- path.gsub!(/\//, ".")
16
+ path = Vitals::Utils.grape_path(route)
21
17
 
22
18
  # TODO move 'grape' to configuration opts in subscribe!(opts)
23
- m = "grape#{path}_#{method}.#{endpoint.status}.all"
19
+ m = "grape.#{path}_#{method}.#{endpoint.status}.all"
24
20
  Vitals.timing(m, duration(started, finished))
25
21
  end
26
22
 
@@ -1,23 +1,56 @@
1
-
2
1
  module Vitals::Integrations::Rack
3
2
  class Requests
4
3
  REQUEST_METHOD = 'REQUEST_METHOD'.freeze
5
- PATH_INFO = 'PATH_INFO'.freeze
4
+
5
+ RACK_PATH_INFO = 'PATH_INFO'.freeze
6
+ SINATRA_PATH_INFO = 'sinatra.route'.freeze
7
+ GRAPE_PATH_INFO = 'api.endpoint'.freeze
8
+ RAILS_PATH_INFO = 'action_controller.instance'.freeze
6
9
 
7
10
  def initialize(app, options = {})
8
11
  @app = app
12
+ @prefix = options[:prefix] ? options[:prefix] + "." : nil
9
13
  end
10
14
 
11
15
  def call(env)
12
16
  start = Time.now
13
17
  status, header, body = @app.call(env)
18
+ t = Time.now - start
19
+ path = if env[SINATRA_PATH_INFO]
20
+ Requests.sinatra_path(env)
21
+ elsif env[GRAPE_PATH_INFO]
22
+ Requests.grape_path(env)
23
+ elsif env[RAILS_PATH_INFO]
24
+ Requests.rails_path(env)
25
+ else
26
+ Requests.rack_path(env)
27
+ end
28
+ m = "requests.#{@prefix}#{path}_#{env[REQUEST_METHOD].downcase}.#{status}"
14
29
 
15
30
  # TODO add option to customize 'requests' through options
16
- m = "requests.#{env[PATH_INFO]}.#{env[REQUEST_METHOD].downcase}.#{status}"
17
- Vitals.timing(m, Vitals::Utils.sec_to_ms(Time.now - start))
31
+ Vitals.timing(m, Vitals::Utils.sec_to_ms(t))
18
32
 
19
33
  [status, header, body]
20
34
  end
35
+
36
+ private
37
+
38
+ def self.sinatra_path(env)
39
+ env[SINATRA_PATH_INFO].gsub(/^\w+\s+\//, '')
40
+ end
41
+
42
+ def self.grape_path(env)
43
+ Vitals::Utils.grape_path(env[GRAPE_PATH_INFO].route)
44
+ end
45
+
46
+ def self.rails_path(env)
47
+ ctrl = env[RAILS_PATH_INFO]
48
+ "#{ctrl.controller_name}_#{ctrl.action_name}"
49
+ end
50
+
51
+ def self.rack_path(env)
52
+ ''
53
+ end
21
54
  end
22
55
  end
23
56
 
@@ -2,21 +2,26 @@ module Vitals::Reporters
2
2
  class ConsoleReporter < BaseReporter
3
3
  attr_accessor :format
4
4
 
5
- def initialize(category:'main', format:nil)
5
+ def initialize(category:'main', output: $stdout, format:nil)
6
6
  @format = format
7
7
  @category = category
8
+ @output = output
8
9
  end
9
10
 
10
11
  def inc(m)
11
- puts "#{@category} INC #{self.format.format(m)}"
12
+ print "#{@category} INC #{self.format.format(m)}"
12
13
  end
13
14
 
14
15
  def gauge(m, v)
15
- puts "#{@category} GAUGE #{self.format.format(m)} #{v}"
16
+ print "#{@category} GAUGE #{self.format.format(m)} #{v}"
16
17
  end
17
18
 
18
19
  def timing(m, v)
19
- puts "#{@category} TIME #{self.format.format(m)} #{v}"
20
+ print "#{@category} TIME #{self.format.format(m)} #{v}"
21
+ end
22
+
23
+ def print(str)
24
+ @output.printf("#{ str }\n")
20
25
  end
21
26
  end
22
27
  end
data/lib/vitals/utils.rb CHANGED
@@ -11,5 +11,14 @@ module Vitals
11
11
  def self.sec_to_ms(sec)
12
12
  (1000.0 * sec).round
13
13
  end
14
+ # XXX grape specific, move this away some day?
15
+ def self.grape_path(route)
16
+ version = route.route_version
17
+ path = route.route_path.dup[1..-1]
18
+ path.sub!(/\(\..*\)$/, '')
19
+ path.sub!(":version", version) if version
20
+ path.gsub!(/\//, ".")
21
+ path
22
+ end
14
23
  end
15
24
  end
@@ -1,3 +1,3 @@
1
1
  module Vitals
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
data/vitals.gemspec CHANGED
@@ -43,6 +43,6 @@ Gem::Specification.new do |spec|
43
43
  spec.add_development_dependency "grape", "~> 0.15.0"
44
44
  spec.add_development_dependency "activesupport", "~> 4.2.6"
45
45
  spec.add_development_dependency "sinatra", "~> 1.4.7"
46
-
46
+ spec.add_development_dependency "byebug", "~> 8.2.2"
47
47
 
48
48
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vitals
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dotan Nahum
@@ -206,6 +206,20 @@ dependencies:
206
206
  - - "~>"
207
207
  - !ruby/object:Gem::Version
208
208
  version: 1.4.7
209
+ - !ruby/object:Gem::Dependency
210
+ name: byebug
211
+ requirement: !ruby/object:Gem::Requirement
212
+ requirements:
213
+ - - "~>"
214
+ - !ruby/object:Gem::Version
215
+ version: 8.2.2
216
+ type: :development
217
+ prerelease: false
218
+ version_requirements: !ruby/object:Gem::Requirement
219
+ requirements:
220
+ - - "~>"
221
+ - !ruby/object:Gem::Version
222
+ version: 8.2.2
209
223
  description: Flexible StatsD instrumentation for Rails, Rack, Grape and more
210
224
  email:
211
225
  - jondotan@gmail.com