nightwing 0.1.0 → 0.2.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: 918b61571eb184206d03a99f762982658944339c
4
- data.tar.gz: 1e3741e8078e80f055354d80de4fee4a311d72e0
3
+ metadata.gz: d1a31b84aa7f3d919e2afa26971a8ed1936efa9c
4
+ data.tar.gz: d4bd99cef7cb8449ed7e05d5f189053c21fdd695
5
5
  SHA512:
6
- metadata.gz: 06dbfca4a437ba0df72dee941eb0847e5831629b1ca98270712a7bda6d4426c1c65ae3db7359171d2e8d0908687f2494ceb5b016e0ade49c5a4d888b5eda5452
7
- data.tar.gz: 1dabeed4b2bfc8f07d514520acb3f50b39a61fae193c0950b8f3b141a475e501324e124a22cd36228397d9a6c77937f3b152350369e9d9bf71998bb7194ed9cf
6
+ metadata.gz: 2babddd5a3b8c38132211c41fe33c5ceef7d850e4a8a83c32a7267fac271944d1badc830f62e4c676795685b748522b7f724c86c0e710adbf21ed130dfe1d046
7
+ data.tar.gz: e42a3b39948aaee75c2a9b5450dc421ffda4c5ef74065ea3250a05ef1b85aca3b7c3fdbf73875942ff3abde2ed4806208af74f4290f1a75d6f0db47088dce024
data/.rubocop.yml CHANGED
@@ -14,6 +14,8 @@ Style/FrozenStringLiteralComment:
14
14
  Enabled: false
15
15
  Style/IfUnlessModifier:
16
16
  Enabled: false
17
+ Style/PerlBackrefs:
18
+ Enabled: false
17
19
  Style/SignalException:
18
20
  Enabled: false
19
21
  Style/GuardClause:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,15 @@
1
+ ## 0.2.0
2
+
3
+ - Renamed memory_used metric so that we can utilize the memory namespace for additional metrics
4
+
5
+ **Renamed Metrics**
6
+
7
+ - `sidekiq.<queue>.<worker>.memory_used` to `sidekiq.<queue>.<worker>.memory.delta`
8
+
9
+ **New Metrics**
10
+
11
+ - `instrumentation.sql.<table>.<action>.time`
12
+
1
13
  ## 0.1.0
2
14
 
3
15
  - Add new Profiler middleware
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nightwing (0.1.0)
4
+ nightwing (0.2.0)
5
5
  activesupport (>= 4.1.0)
6
6
  oink (= 0.10.1)
7
7
  sidekiq (>= 2.6)
data/README.md CHANGED
@@ -28,6 +28,14 @@ Sidekiq.configure_server do |config|
28
28
  end
29
29
  ```
30
30
 
31
+ ```ruby
32
+ # config/initializers/instrumentation.rb
33
+ ActiveSupport::Notifications.subscribe(
34
+ 'sql.active_record',
35
+ Nightwing::Instrumentation::ActiveRecord.new(client: Librato),
36
+ )
37
+ ```
38
+
31
39
  ### Available options
32
40
 
33
41
  | Name | Description | Required? | Default |
@@ -39,7 +47,13 @@ end
39
47
 
40
48
  When debug mode is turned on, Nightwing will output the metrics into a parsable format. The output destination is determined by the logger. If no logger is given then we send the debugging output to STDOUT.
41
49
 
42
- ## Metrics
50
+ ## Instrumentation Metrics
51
+
52
+ Below are the metrics reported to Librato from instrumentation classes
53
+
54
+ - `instrumentation.sql.<table>.<action>.time`: how long the database query took to complete
55
+
56
+ ## Sidekiq Metrics
43
57
 
44
58
  Below are the metrics reported to Librato from the Sidekiq middleware
45
59
 
@@ -56,7 +70,7 @@ Below are the metrics reported to Librato from the Sidekiq middleware
56
70
  - `sidekiq.<queue>.failed`: number of jobs in given queue that raised an error
57
71
  - `sidekiq.<queue>.time`: how long jobs took to process (in milliseconds)
58
72
  - `sidekiq.<queue>.gc.count`: number of times the Ruby GC kicked off
59
- - `sidekiq.<queue>.memory_used`: the different in the process memory after jobs were processed (in bytes)
73
+ - `sidekiq.<queue>.memory.delta`: the different in the process memory after jobs were processed (in bytes)
60
74
 
61
75
  ¹: the difference between now and when the oldest job was enqueued (given in seconds)
62
76
 
@@ -68,4 +82,4 @@ Below are the metrics reported to Librato from the Sidekiq middleware
68
82
  - `sidekiq.<queue>.<worker>.time`: how long given worker took to process (in milliseconds)
69
83
  - `sidekiq.<queue>.<worker>.retried`: number of times a given worker retried
70
84
  - `sidekiq.<queue>.<worker>.gc.count`: number of times the Ruby GC kicked off
71
- - `sidekiq.<queue>.<worker>.memory_used`: the different in the process memory after jobs were processed (in bytes)
85
+ - `sidekiq.<queue>.<worker>.memory.delta`: the different in the process memory after jobs were processed (in bytes)
data/lib/nightwing.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  require "nightwing/version"
2
+ require "nightwing/instrumentation/active_record"
2
3
  require "nightwing/sidekiq/stats"
3
4
  require "nightwing/sidekiq/queue_stats"
4
5
  require "nightwing/sidekiq/worker_stats"
@@ -0,0 +1,27 @@
1
+ require "nightwing/metric"
2
+ require "nightwing/debug_client"
3
+ require "nightwing/logger"
4
+ require "nightwing/client_logger"
5
+
6
+ module Nightwing
7
+ class Base
8
+ attr_reader :namespace, :logger
9
+
10
+ def initialize(options = {})
11
+ @namespace = options.fetch(:namespace)
12
+ @client = options.fetch(:client, Nightwing::DebugClient.new)
13
+ @logger = options.fetch(:logger, Nightwing::Logger.new)
14
+ @debug = options.fetch(:debug, false)
15
+ end
16
+
17
+ def client
18
+ @client_proxy ||= begin
19
+ if @debug
20
+ Nightwing::ClientLogger.new(client: @client, logger: @logger)
21
+ else
22
+ @client
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,37 @@
1
+ require "nightwing/instrumentation/base"
2
+
3
+ module Nightwing
4
+ module Instrumentation
5
+ # This code was influenced by Matt Aimonetti's awesome blog post: "Practical Guide to StatsD/Graphite Monitoring"
6
+ # Check it out: https://matt.aimonetti.net/posts/2013/06/26/practical-guide-to-graphite-monitoring
7
+ class ActiveRecord < Base
8
+ SQL_INSERT_DELETE_PARSER_REGEXP = /^(\w+)\s(\w+)\s\W*(\w+)/
9
+ SQL_SELECT_REGEXP = /select .*? FROM \W*(\w+)/i
10
+ SQL_UPDATE_REGEXP = /update \W*(\w+)/i
11
+
12
+ def call(_name, started, finished, _unique_id, payload)
13
+ if payload[:name] == "SQL" || payload[:name] =~ /.* Load$/ || payload[:name].nil?
14
+ table, action = query_info(payload[:sql])
15
+ end
16
+
17
+ if table
18
+ query_time = (finished - started) * 1_000
19
+ client.timing("#{namespace}.sql.#{table.downcase}.#{action.downcase}.time", query_time.round)
20
+ end
21
+ end
22
+
23
+ private
24
+
25
+ def query_info(query)
26
+ case query
27
+ when SQL_INSERT_DELETE_PARSER_REGEXP
28
+ [$3, $1]
29
+ when SQL_UPDATE_REGEXP
30
+ [$1, "update"]
31
+ when SQL_SELECT_REGEXP
32
+ [$1, "select"]
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ require "nightwing/base"
2
+
3
+ module Nightwing
4
+ module Instrumentation
5
+ class Base < Nightwing::Base
6
+ def initialize(options = {})
7
+ super default_options.merge(options)
8
+ end
9
+
10
+ private
11
+
12
+ def default_options
13
+ { namespace: "instrumentation" }
14
+ end
15
+ end
16
+ end
17
+ end
@@ -1,29 +1,11 @@
1
1
  require "sidekiq/api"
2
- require "nightwing/metric"
3
- require "nightwing/debug_client"
4
- require "nightwing/logger"
5
- require "nightwing/client_logger"
2
+ require "nightwing/base"
6
3
 
7
4
  module Nightwing
8
5
  module Sidekiq
9
- class Base
10
- attr_reader :namespace, :logger
11
-
6
+ class Base < Nightwing::Base
12
7
  def initialize(options = {})
13
- @namespace = options.fetch(:namespace, "sidekiq")
14
- @client = options.fetch(:client, Nightwing::DebugClient.new)
15
- @logger = options.fetch(:logger, Nightwing::Logger.new)
16
- @debug = options.fetch(:debug, false)
17
- end
18
-
19
- def client
20
- @client_proxy ||= begin
21
- if @debug
22
- Nightwing::ClientLogger.new(client: @client, logger: @logger)
23
- else
24
- @client
25
- end
26
- end
8
+ super options.merge(namespace: "sidekiq")
27
9
  end
28
10
 
29
11
  private
@@ -1,4 +1,3 @@
1
- require "nightwing/sidekiq/profiler"
2
1
  require "oink"
3
2
 
4
3
  module Nightwing
@@ -15,16 +14,17 @@ module Nightwing
15
14
 
16
15
  yield
17
16
  ensure
18
- memory_delta_in_bytes = memory_snapshot - initial_snapshot
17
+ finish_snapshot = memory_snapshot
18
+ memory_delta_in_bytes = finish_snapshot - initial_snapshot
19
19
  total_time = ((Time.now - started_at) * 1_000).round
20
20
  total_gc_count = ::GC.count - initial_gc_count
21
21
 
22
22
  client.timing "#{worker_namespace}.time", total_time
23
- client.measure "#{worker_namespace}.memory_used", memory_delta_in_bytes
23
+ client.measure "#{worker_namespace}.memory.delta", memory_delta_in_bytes
24
24
  client.measure "#{worker_namespace}.gc.count", total_gc_count
25
25
 
26
26
  client.timing "#{queue_namespace}.time", total_time
27
- client.measure "#{queue_namespace}.memory_used", memory_delta_in_bytes
27
+ client.measure "#{queue_namespace}.memory.delta", memory_delta_in_bytes
28
28
  client.measure "#{queue_namespace}.gc.count", total_gc_count
29
29
  end
30
30
  end
@@ -1,3 +1,3 @@
1
1
  module Nightwing
2
- VERSION = "0.1.0".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
@@ -0,0 +1,24 @@
1
+ require "spec_helper"
2
+ require "active_support/all"
3
+
4
+ describe Nightwing::Instrumentation::ActiveRecord do
5
+ subject { described_class.new(namespace: "instr") }
6
+
7
+ describe "#call" do
8
+ context "when given select SQL query" do
9
+ it "measures time" do
10
+ expect(subject.client).to receive(:timing).with("instr.sql.users.select.time", 2_000)
11
+ payload = { name: "SQL", sql: "select * from users;" }
12
+ subject.call(nil, 5.seconds.ago, 3.seconds.ago, nil, payload)
13
+ end
14
+ end
15
+
16
+ context "when given insert SQL query" do
17
+ it "measures time" do
18
+ expect(subject.client).to receive(:timing).with("instr.sql.foo.insert.time", 1_000)
19
+ payload = { name: "SQL", sql: "insert into foo values(1, 2, 3);" }
20
+ subject.call(nil, 10.seconds.ago, 9.seconds.ago, nil, payload)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -24,9 +24,9 @@ describe Nightwing::Sidekiq::Profiler do
24
24
  end
25
25
 
26
26
  it "records memory" do
27
- expect(subject.client).to receive(:measure).with("sidekiq.default.my_worker.memory_used", 0).and_call_original
27
+ expect(subject.client).to receive(:measure).with("sidekiq.default.my_worker.memory.delta", 0).and_call_original
28
28
  expect(subject.client).to receive(:measure).with("sidekiq.default.my_worker.gc.count", 0).and_call_original
29
- expect(subject.client).to receive(:measure).with("sidekiq.default.memory_used", 0).and_call_original
29
+ expect(subject.client).to receive(:measure).with("sidekiq.default.memory.delta", 0).and_call_original
30
30
  expect(subject.client).to receive(:measure).with("sidekiq.default.gc.count", 0).and_call_original
31
31
 
32
32
  subject.call(MyWorker.new, nil, "default") do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nightwing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Ledet
@@ -123,8 +123,11 @@ files:
123
123
  - README.md
124
124
  - circle.yml
125
125
  - lib/nightwing.rb
126
+ - lib/nightwing/base.rb
126
127
  - lib/nightwing/client_logger.rb
127
128
  - lib/nightwing/debug_client.rb
129
+ - lib/nightwing/instrumentation/active_record.rb
130
+ - lib/nightwing/instrumentation/base.rb
128
131
  - lib/nightwing/logger.rb
129
132
  - lib/nightwing/metric.rb
130
133
  - lib/nightwing/sidekiq/base.rb
@@ -134,6 +137,7 @@ files:
134
137
  - lib/nightwing/sidekiq/worker_stats.rb
135
138
  - lib/nightwing/version.rb
136
139
  - nightwing.gemspec
140
+ - spec/nightwing/instrumentation/active_record_spec.rb
137
141
  - spec/nightwing/metric_spec.rb
138
142
  - spec/nightwing/sidekiq/profiler_spec.rb
139
143
  - spec/nightwing/sidekiq/queue_stats_spec.rb