nightwing 0.2.0 → 0.3.0

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
  SHA1:
3
- metadata.gz: d1a31b84aa7f3d919e2afa26971a8ed1936efa9c
4
- data.tar.gz: d4bd99cef7cb8449ed7e05d5f189053c21fdd695
3
+ metadata.gz: 1830dcc5ef65dd81a3991d08edb121cdd5e7dc35
4
+ data.tar.gz: 8fd3c1a4a52736adb30b92bec706960e068e8453
5
5
  SHA512:
6
- metadata.gz: 2babddd5a3b8c38132211c41fe33c5ceef7d850e4a8a83c32a7267fac271944d1badc830f62e4c676795685b748522b7f724c86c0e710adbf21ed130dfe1d046
7
- data.tar.gz: e42a3b39948aaee75c2a9b5450dc421ffda4c5ef74065ea3250a05ef1b85aca3b7c3fdbf73875942ff3abde2ed4806208af74f4290f1a75d6f0db47088dce024
6
+ metadata.gz: cafce097fd7a8470aa4b5316767d0dce065859c0f7de51a80b003696ce68db9773e11c9b30152092fd160dbcc8e81b4a8f90efc31071b88d40f6a1e28b1e2dc7
7
+ data.tar.gz: 0fe35c47611d301c4dfbffe431041ec9a6eea96c60af51d076ce6c3093f0ed1ff8f454f548e0b433795cfa8e61c41355c13257f37cd5969f174f346323948b4d
data/.rubocop.yml CHANGED
@@ -10,10 +10,14 @@ Metrics/LineLength:
10
10
  Max: 120
11
11
  StringLiterals:
12
12
  EnforcedStyle: double_quotes
13
+ Style/Alias:
14
+ Enabled: false
13
15
  Style/FrozenStringLiteralComment:
14
16
  Enabled: false
15
17
  Style/IfUnlessModifier:
16
18
  Enabled: false
19
+ Style/ModuleFunction:
20
+ Enabled: false
17
21
  Style/PerlBackrefs:
18
22
  Enabled: false
19
23
  Style/SignalException:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,28 @@
1
+ ## Unreleased
2
+
3
+ ## 0.3.0
4
+
5
+ - New profiling extension for Redis
6
+ - New profiling extension for Memcache (via Dalli)
7
+ - Added new `Nightwing.client` to global statds client configuration
8
+ - Internal setup refactor
9
+ - Metric changes are listed below
10
+
11
+ **Renamed Metrics**
12
+
13
+ - `instrumentation.sql.<table>.<action>.time` to `sql.<table>.<action>.time`
14
+
15
+ **New Metrics**
16
+
17
+ - `memcache.command.time`
18
+ - `memcache.command.<command>.time`
19
+ - `memcache.command.processed`
20
+ - `memcache.command.<command>.processed`
21
+ - `redis.command.time`
22
+ - `redis.command.<command>.time`
23
+ - `redis.command.processed`
24
+ - `redis.command.<command>.processed`
25
+
1
26
  ## 0.2.0
2
27
 
3
28
  - Renamed memory_used metric so that we can utilize the memory namespace for additional metrics
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- nightwing (0.2.0)
4
+ nightwing (0.3.0)
5
5
  activesupport (>= 4.1.0)
6
6
  oink (= 0.10.1)
7
7
  sidekiq (>= 2.6)
@@ -9,14 +9,14 @@ PATH
9
9
  GEM
10
10
  remote: https://rubygems.org/
11
11
  specs:
12
- activemodel (4.2.5)
13
- activesupport (= 4.2.5)
12
+ activemodel (4.2.5.1)
13
+ activesupport (= 4.2.5.1)
14
14
  builder (~> 3.1)
15
- activerecord (4.2.5)
16
- activemodel (= 4.2.5)
17
- activesupport (= 4.2.5)
15
+ activerecord (4.2.5.1)
16
+ activemodel (= 4.2.5.1)
17
+ activesupport (= 4.2.5.1)
18
18
  arel (~> 6.0)
19
- activesupport (4.2.5)
19
+ activesupport (4.2.5.1)
20
20
  i18n (~> 0.7)
21
21
  json (~> 1.7, >= 1.7.7)
22
22
  minitest (~> 5.1)
File without changes
data/README.md CHANGED
@@ -28,14 +28,26 @@ Sidekiq.configure_server do |config|
28
28
  end
29
29
  ```
30
30
 
31
+ To gather database metrics:
32
+
31
33
  ```ruby
32
34
  # config/initializers/instrumentation.rb
33
- ActiveSupport::Notifications.subscribe(
34
- 'sql.active_record',
35
- Nightwing::Instrumentation::ActiveRecord.new(client: Librato),
36
- )
35
+ Nightwing.client = Librato
36
+
37
+ ActiveSupport::Notifications.subscribe('sql.active_record', Nightwing::Instrumentation::ActiveRecord.new)
37
38
  ```
38
39
 
40
+ To gather Redis and memcache metrics:
41
+
42
+ ```ruby
43
+ # config/initializers/instrumentation.rb
44
+ Nightwing.client = Librato
45
+
46
+ require 'nightwing/extensions/dalli' # dalli gem required
47
+ require 'nightwing/extensions/redis' # redis gem required
48
+ ```
49
+
50
+
39
51
  ### Available options
40
52
 
41
53
  | Name | Description | Required? | Default |
@@ -51,7 +63,20 @@ When debug mode is turned on, Nightwing will output the metrics into a parsable
51
63
 
52
64
  Below are the metrics reported to Librato from instrumentation classes
53
65
 
54
- - `instrumentation.sql.<table>.<action>.time`: how long the database query took to complete
66
+ - `sql.<table>.<action>.time`: how long the database query took to complete
67
+
68
+ ## Extensions Metrics
69
+
70
+ Below are the metrics reported to Librato from instrumentation classes
71
+
72
+ - `redis.command.processed`: number of times overall command was called
73
+ - `redis.command.time`: response time (in ms) for all commands
74
+ - `redis.command.<command>.processed`: number of times the command was called
75
+ - `redis.command.<command>.time`: response time (in ms) for command
76
+ - `memcache.command.processed`: number of times overall command was called
77
+ - `memcache.command.time`: response time (in ms) for all commands
78
+ - `memcache.command.<command>.processed`: number of times the command was called
79
+ - `memcache.command.<command>.time`: response time (in ms) for command
55
80
 
56
81
  ## Sidekiq Metrics
57
82
 
data/circle.yml CHANGED
@@ -1,5 +1,14 @@
1
+ dependencies:
2
+ override:
3
+ - 'rvm-exec 2.1.7 bundle install'
4
+ - 'rvm-exec 2.2.3 bundle install'
5
+ - 'rvm-exec 2.3.0 bundle install'
6
+
1
7
  test:
2
- pre:
3
- - bundle exec rubocop
4
8
  override:
5
- - bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml
9
+ - 'rvm-exec 2.1.7 bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
10
+ - 'rvm-exec 2.1.7 bundle exec rubocop'
11
+ - 'rvm-exec 2.2.3 bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
12
+ - 'rvm-exec 2.2.3 bundle exec rubocop'
13
+ - 'rvm-exec 2.3.0 bundle exec rspec -r rspec_junit_formatter --format RspecJunitFormatter -o $CIRCLE_TEST_REPORTS/rspec/junit.xml'
14
+ - 'rvm-exec 2.3.0 bundle exec rubocop'
data/lib/nightwing.rb CHANGED
@@ -1,6 +1,26 @@
1
1
  require "nightwing/version"
2
+ require "nightwing/debug_client"
2
3
  require "nightwing/instrumentation/active_record"
4
+ require "nightwing/sidekiq/base"
3
5
  require "nightwing/sidekiq/stats"
4
6
  require "nightwing/sidekiq/queue_stats"
5
7
  require "nightwing/sidekiq/worker_stats"
6
8
  require "nightwing/sidekiq/profiler"
9
+
10
+ module Nightwing
11
+ extend self
12
+
13
+ def client
14
+ @client || internal_client
15
+ end
16
+
17
+ def client=(c)
18
+ @client = c
19
+ end
20
+
21
+ private
22
+
23
+ def internal_client
24
+ @internal_client ||= Nightwing::DebugClient.new
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ Dalli::Client.class_eval do
2
+ def perform_with_profiling(*args)
3
+ begin
4
+ start_time = Time.now
5
+ result = perform_without_profiling(*args)
6
+ ensure
7
+ time_ellasped = (Time.now - start_time) * 1_000
8
+ command = args.first.is_a?(Array) ? args[0][0] : args.first
9
+
10
+ Nightwing.client.timing "memcache.command.time", time_ellasped
11
+ Nightwing.client.timing "memcache.command.#{command}.time", time_ellasped
12
+
13
+ Nightwing.client.increment "memcache.command.processed"
14
+ Nightwing.client.increment "memcache.command.#{command}.processed"
15
+ end
16
+
17
+ result
18
+ end
19
+ alias perform_without_profiling perform
20
+ alias perform perform_with_profiling
21
+ end if defined?(Dalli::Client)
@@ -0,0 +1,21 @@
1
+ Redis::Client.class_eval do
2
+ def call_with_profiling(*args, &blk)
3
+ begin
4
+ start_time = Time.now
5
+ result = call_without_profiling(*args, &blk)
6
+ ensure
7
+ time_ellasped = (Time.now - start_time) * 1_000
8
+ command = args.first.is_a?(Array) ? args[0][0] : args.first
9
+
10
+ Nightwing.client.timing "redis.command.time", time_ellasped
11
+ Nightwing.client.timing "redis.command.#{command}.time", time_ellasped
12
+
13
+ Nightwing.client.increment "redis.command.processed"
14
+ Nightwing.client.increment "redis.command.#{command}.processed"
15
+ end
16
+
17
+ result
18
+ end
19
+ alias call_without_profiling call
20
+ alias call call_with_profiling
21
+ end if defined?(Redis::Client)
@@ -1,10 +1,8 @@
1
- require "nightwing/instrumentation/base"
2
-
3
1
  module Nightwing
4
2
  module Instrumentation
5
3
  # This code was influenced by Matt Aimonetti's awesome blog post: "Practical Guide to StatsD/Graphite Monitoring"
6
4
  # Check it out: https://matt.aimonetti.net/posts/2013/06/26/practical-guide-to-graphite-monitoring
7
- class ActiveRecord < Base
5
+ class ActiveRecord
8
6
  SQL_INSERT_DELETE_PARSER_REGEXP = /^(\w+)\s(\w+)\s\W*(\w+)/
9
7
  SQL_SELECT_REGEXP = /select .*? FROM \W*(\w+)/i
10
8
  SQL_UPDATE_REGEXP = /update \W*(\w+)/i
@@ -15,8 +13,15 @@ module Nightwing
15
13
  end
16
14
 
17
15
  if table
16
+ action.downcase!
17
+ table.downcase!
18
18
  query_time = (finished - started) * 1_000
19
- client.timing("#{namespace}.sql.#{table.downcase}.#{action.downcase}.time", query_time.round)
19
+
20
+ Nightwing.client.timing "sql.#{action}.time", query_time.round
21
+ Nightwing.client.timing "sql.#{action}.#{table}.time", query_time.round
22
+
23
+ Nightwing.client.increment "sql.#{action}.processed"
24
+ Nightwing.client.increment "sql.#{action}.#{table}.processed"
20
25
  end
21
26
  end
22
27
 
@@ -1,11 +1,28 @@
1
1
  require "sidekiq/api"
2
- require "nightwing/base"
2
+ require "nightwing/metric"
3
+ require "nightwing/logger"
4
+ require "nightwing/client_logger"
3
5
 
4
6
  module Nightwing
5
7
  module Sidekiq
6
- class Base < Nightwing::Base
8
+ class Base
9
+ attr_reader :namespace, :logger
10
+
7
11
  def initialize(options = {})
8
- super options.merge(namespace: "sidekiq")
12
+ @namespace = options.fetch(:namespace, "sidekiq")
13
+ @client = options.fetch(:client, Nightwing.client)
14
+ @logger = options.fetch(:logger, Nightwing::Logger.new)
15
+ @debug = options.fetch(:debug, false)
16
+ end
17
+
18
+ def client
19
+ @client_proxy ||= begin
20
+ if @debug
21
+ Nightwing::ClientLogger.new(client: @client, logger: @logger)
22
+ else
23
+ @client
24
+ end
25
+ end
9
26
  end
10
27
 
11
28
  private
@@ -1,3 +1,3 @@
1
1
  module Nightwing
2
- VERSION = "0.2.0".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ class Dalli
4
+ class Client
5
+ def perform(*_)
6
+ @performed = true
7
+ end
8
+
9
+ def called?
10
+ @performed
11
+ end
12
+ end
13
+ end
14
+
15
+ describe "Dalli extensions" do
16
+ subject { Dalli::Client.new }
17
+
18
+ before do
19
+ require "nightwing/extensions/dalli"
20
+ end
21
+
22
+ describe "#peform" do
23
+ it "measures time" do
24
+ expect(Nightwing.client).to receive(:timing) do |*args|
25
+ expect(args.first).to eq("memcache.command.time")
26
+ expect(args.last > 0).to be(true)
27
+ end
28
+
29
+ expect(Nightwing.client).to receive(:timing) do |*args|
30
+ expect(args.first).to eq("memcache.command.foo.time")
31
+ expect(args.last > 0).to be(true)
32
+ end
33
+
34
+ expect(Nightwing.client).to receive(:increment).with("memcache.command.processed")
35
+ expect(Nightwing.client).to receive(:increment).with("memcache.command.foo.processed")
36
+
37
+ subject.perform :foo
38
+ end
39
+
40
+ it "actually calls perform" do
41
+ subject.perform :foo
42
+ expect(subject).to be_called
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ require "spec_helper"
2
+
3
+ class Redis
4
+ class Client
5
+ def call(*_)
6
+ @performed = true
7
+ end
8
+
9
+ def called?
10
+ @performed
11
+ end
12
+ end
13
+ end
14
+
15
+ describe "Redis extensions" do
16
+ subject { Redis::Client.new }
17
+
18
+ before do
19
+ require "nightwing/extensions/redis"
20
+ end
21
+
22
+ describe "#peform" do
23
+ it "measures time" do
24
+ expect(Nightwing.client).to receive(:timing) do |*args|
25
+ expect(args.first).to eq("redis.command.time")
26
+ expect(args.last > 0).to be(true)
27
+ end
28
+
29
+ expect(Nightwing.client).to receive(:timing) do |*args|
30
+ expect(args.first).to eq("redis.command.foo.time")
31
+ expect(args.last > 0).to be(true)
32
+ end
33
+
34
+ expect(Nightwing.client).to receive(:increment).with("redis.command.processed")
35
+ expect(Nightwing.client).to receive(:increment).with("redis.command.foo.processed")
36
+
37
+ subject.call :foo
38
+ end
39
+
40
+ it "actually calls perform" do
41
+ subject.call :foo
42
+ expect(subject).to be_called
43
+ end
44
+ end
45
+ end
@@ -2,12 +2,16 @@ require "spec_helper"
2
2
  require "active_support/all"
3
3
 
4
4
  describe Nightwing::Instrumentation::ActiveRecord do
5
- subject { described_class.new(namespace: "instr") }
5
+ subject { described_class.new }
6
6
 
7
7
  describe "#call" do
8
8
  context "when given select SQL query" do
9
9
  it "measures time" do
10
- expect(subject.client).to receive(:timing).with("instr.sql.users.select.time", 2_000)
10
+ expect(Nightwing.client).to receive(:timing).with("sql.select.time", 2_000)
11
+ expect(Nightwing.client).to receive(:timing).with("sql.select.users.time", 2_000)
12
+ expect(Nightwing.client).to receive(:increment).with("sql.select.processed")
13
+ expect(Nightwing.client).to receive(:increment).with("sql.select.users.processed")
14
+
11
15
  payload = { name: "SQL", sql: "select * from users;" }
12
16
  subject.call(nil, 5.seconds.ago, 3.seconds.ago, nil, payload)
13
17
  end
@@ -15,7 +19,11 @@ describe Nightwing::Instrumentation::ActiveRecord do
15
19
 
16
20
  context "when given insert SQL query" do
17
21
  it "measures time" do
18
- expect(subject.client).to receive(:timing).with("instr.sql.foo.insert.time", 1_000)
22
+ expect(Nightwing.client).to receive(:timing).with("sql.insert.time", 1_000)
23
+ expect(Nightwing.client).to receive(:timing).with("sql.insert.foo.time", 1_000)
24
+ expect(Nightwing.client).to receive(:increment).with("sql.insert.processed")
25
+ expect(Nightwing.client).to receive(:increment).with("sql.insert.foo.processed")
26
+
19
27
  payload = { name: "SQL", sql: "insert into foo values(1, 2, 3);" }
20
28
  subject.call(nil, 10.seconds.ago, 9.seconds.ago, nil, payload)
21
29
  end
@@ -0,0 +1,27 @@
1
+ require "spec_helper"
2
+
3
+ describe Nightwing do
4
+ describe "#client" do
5
+ context "when client is not set" do
6
+ class MyClient; end
7
+
8
+ before do
9
+ Nightwing.client = MyClient.new
10
+ end
11
+
12
+ it "returns client" do
13
+ expect(Nightwing.client.class).to eq(MyClient)
14
+ end
15
+ end
16
+
17
+ context "when client is not set" do
18
+ before do
19
+ Nightwing.client = nil
20
+ end
21
+
22
+ it "returns default client" do
23
+ expect(Nightwing.client.class).to eq(Nightwing::DebugClient)
24
+ end
25
+ end
26
+ end
27
+ end
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.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Ledet
@@ -119,15 +119,15 @@ files:
119
119
  - CHANGELOG.md
120
120
  - Gemfile
121
121
  - Gemfile.lock
122
- - LICENSE.txt
122
+ - LICENSE
123
123
  - README.md
124
124
  - circle.yml
125
125
  - lib/nightwing.rb
126
- - lib/nightwing/base.rb
127
126
  - lib/nightwing/client_logger.rb
128
127
  - lib/nightwing/debug_client.rb
128
+ - lib/nightwing/extensions/dalli.rb
129
+ - lib/nightwing/extensions/redis.rb
129
130
  - lib/nightwing/instrumentation/active_record.rb
130
- - lib/nightwing/instrumentation/base.rb
131
131
  - lib/nightwing/logger.rb
132
132
  - lib/nightwing/metric.rb
133
133
  - lib/nightwing/sidekiq/base.rb
@@ -137,12 +137,15 @@ files:
137
137
  - lib/nightwing/sidekiq/worker_stats.rb
138
138
  - lib/nightwing/version.rb
139
139
  - nightwing.gemspec
140
+ - spec/nightwing/extensions/dalli_spec.rb
141
+ - spec/nightwing/extensions/redis_spec.rb
140
142
  - spec/nightwing/instrumentation/active_record_spec.rb
141
143
  - spec/nightwing/metric_spec.rb
142
144
  - spec/nightwing/sidekiq/profiler_spec.rb
143
145
  - spec/nightwing/sidekiq/queue_stats_spec.rb
144
146
  - spec/nightwing/sidekiq/stats_spec.rb
145
147
  - spec/nightwing/sidekiq/worker_stats_spec.rb
148
+ - spec/nightwing_spec.rb
146
149
  - spec/spec_helper.rb
147
150
  homepage: https://github.com/teespring/nightwing
148
151
  licenses:
@@ -1,27 +0,0 @@
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
@@ -1,17 +0,0 @@
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