gremlin 0.0.1 → 0.0.2

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: f7287de278b662763ddc2ca3cca5d38c41bdd190
4
- data.tar.gz: 823ee29d0d1dac97672d32d3649c502699271f0a
3
+ metadata.gz: 9f3277bdf017d08b45ad5deb0313a9aa4fe713dd
4
+ data.tar.gz: 359c2c16c2438cd7366911abf975c3b802776b87
5
5
  SHA512:
6
- metadata.gz: d40b078ddda9c56352cb260a493002bc9e13fa695cb781b5065fedd08c99a0c78205c8161c02953ce0004eaaf1f72473d3971744bc2d33faf5108623dee2b741
7
- data.tar.gz: 6ba936ae95928ad71d409f3213921ced78bca12e71f189b38c8da808fe158bbd9e33930a7b67d2c1a3857afbb9f845a9d83b95b4343498502e5088ab7238a6dd
6
+ metadata.gz: ecc158ed3ff1540d04d163e4ffc5dd2d5d1a02b5cb396133e221d3d41ef521e918612c55a7db11bce2095a72b2d001e6cf820ab03898ab6d5cd1539e9b31e3e4
7
+ data.tar.gz: a3477c8661b90c1a227f5870dcccddc0f75b4a171ea372fe766fa552abd1324536621f1d4dd4dcadacce6afe0839d32cf702e1f11fc9de764d7d9f77da14a5b7
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  *.sw*
2
2
  spec/examples.txt
3
+ *.gem
4
+ *.rdb
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- gremlin (0.0.1)
4
+ gremlin (0.0.2)
5
5
  quantile
6
6
  rails
7
7
  redis (~> 3.2)
@@ -54,7 +54,7 @@ GEM
54
54
  erubis (2.7.0)
55
55
  globalid (0.3.7)
56
56
  activesupport (>= 4.1.0)
57
- i18n (0.7.0)
57
+ i18n (0.8.1)
58
58
  loofah (2.0.3)
59
59
  nokogiri (>= 1.5.9)
60
60
  mail (2.6.4)
@@ -97,7 +97,7 @@ GEM
97
97
  thor (>= 0.18.1, < 2.0)
98
98
  rake (10.5.0)
99
99
  rdoc (5.0.0)
100
- redis (3.3.2)
100
+ redis (3.3.3)
101
101
  redis-native_hash (0.2.1)
102
102
  redis (>= 2.0.0)
103
103
  rspec (3.5.0)
@@ -121,10 +121,10 @@ GEM
121
121
  activesupport (>= 4.0)
122
122
  sprockets (>= 3.0.0)
123
123
  thor (0.19.4)
124
- thread_safe (0.3.5)
124
+ thread_safe (0.3.6)
125
125
  tzinfo (1.2.2)
126
126
  thread_safe (~> 0.1)
127
- websocket-driver (0.6.4)
127
+ websocket-driver (0.6.5)
128
128
  websocket-extensions (>= 0.1.0)
129
129
  websocket-extensions (0.1.2)
130
130
 
@@ -139,4 +139,4 @@ DEPENDENCIES
139
139
  rspec (~> 3.3, >= 3.3.0)
140
140
 
141
141
  BUNDLED WITH
142
- 1.11.2
142
+ 1.12.4
@@ -0,0 +1,143 @@
1
+ require 'benchmark'
2
+ require 'gremlin'
3
+
4
+
5
+ include Benchmark
6
+
7
+ print "Starting benchmarks..."
8
+
9
+ orig_std_out = STDOUT.clone
10
+ STDOUT.reopen(File::open('/dev/null', 'w'))
11
+
12
+ counter_init_benchmarks = (1..100).map do |n|
13
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
14
+ counter_name = "test_#{SecureRandom.hex(5)}_counter".to_sym
15
+ x.report("Counter initialize") { Gremlin::Instruments::Counter.new counter_name, "placeholder", {} }
16
+ end
17
+ end
18
+
19
+ counter_init_and_fetch_benchmarks = (1..100).map do |n|
20
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
21
+ counter_name = "test_#{SecureRandom.hex(5)}_counter".to_sym
22
+ x.report("Counter initialize then fetch") do
23
+ Gremlin::Instruments::Counter.new counter_name, "placeholder", {}
24
+ Gremlin.registry.get counter_name
25
+ end
26
+ end
27
+ end
28
+
29
+ counter_init_and_incr_benchmarks = (1..100).map do |n|
30
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
31
+ counter_name = "test_#{SecureRandom.hex(5)}_counter".to_sym
32
+ x.report("Counter increment") do
33
+ counter = Gremlin::Instruments::Counter.new counter_name, "placeholder", {}
34
+ counter.increment
35
+ end
36
+ end
37
+ end
38
+
39
+ gauge_init_benchmarks = (1..100).map do |n|
40
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
41
+ gauge_name = "test_#{SecureRandom.hex(5)}_gauge".to_sym
42
+ gauge_set_val = rand(1..25000000)
43
+ x.report("Gauge initialize") { Gremlin::Instruments::Gauge.new gauge_name, "placeholder", {} }
44
+ end
45
+ end
46
+
47
+ gauge_init_and_fetch_benchmarks = (1..100).map do |n|
48
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
49
+ gauge_name = "test_#{SecureRandom.hex(5)}_gauge".to_sym
50
+ gauge_set_val = rand(1..25000000)
51
+ x.report("Gauge fetch") do
52
+ Gremlin::Instruments::Gauge.new gauge_name, "placeholder", {}
53
+ Gremlin.registry.get gauge_name
54
+ end
55
+ end
56
+ end
57
+
58
+ gauge_init_and_set_benchmarks = (1..100).map do |n|
59
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
60
+ gauge_name = "test_#{SecureRandom.hex(5)}_gauge".to_sym
61
+ gauge_set_val = rand(1..25000000)
62
+ x.report("Gauge set") do
63
+ gauge = Gremlin::Instruments::Gauge.new gauge_name, "placeholder", {}
64
+ gauge.set({ :foo => "baz" }, gauge_set_val)
65
+ end
66
+ end
67
+ end
68
+
69
+ summary_init_benchmarks = (1..100).map do |n|
70
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
71
+ summary_name = "test_#{SecureRandom.hex(5)}_summary".to_sym
72
+ summary_observe_val = rand(1..25000000)
73
+ x.report("Summary initialize") { Gremlin::Instruments::Summary.new summary_name.to_sym, "placeholder", {} }
74
+ end
75
+ end
76
+
77
+ summary_init_and_fetch_benchmarks = (1..100).map do |n|
78
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
79
+ summary_name = "test_#{SecureRandom.hex(5)}_summary".to_sym
80
+ summary_observe_val = rand(1..25000000)
81
+ x.report("Summary fetch") do
82
+ Gremlin::Instruments::Summary.new summary_name.to_sym, "placeholder", {}
83
+ Gremlin.registry.get summary_name
84
+ end
85
+ end
86
+ end
87
+
88
+ summary_init_and_observe_benchmarks = (1..100).map do |n|
89
+ Benchmark.benchmark(CAPTION, 35, FORMAT) do |x|
90
+ summary_name = "test_#{SecureRandom.hex(5)}_summary".to_sym
91
+ summary_observe_val = rand(1..25000000)
92
+ x.report("Summary observe") do
93
+ summary = Gremlin::Instruments::Summary.new summary_name.to_sym, "placeholder", {}
94
+ summary.observe({ :bar => "foo" }, summary_observe_val)
95
+ end
96
+ end
97
+ end
98
+
99
+ STDOUT.reopen(orig_std_out)
100
+ print "Done!\n"
101
+
102
+ counter_init_agg = counter_init_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
103
+ counter_init_and_incr_agg = counter_init_and_incr_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
104
+ counter_init_and_fetch_agg = counter_init_and_fetch_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
105
+
106
+ puts "--------------------------------------------------------"
107
+ puts ""
108
+ puts "Counter Initialize Total: #{counter_init_agg*1000} ms"
109
+ puts "Counter Initialize Avg: #{counter_init_agg/100*1000} ms over 100 iterations"
110
+ puts "Counter Initialize and Fetch Total: #{counter_init_and_fetch_agg*1000} ms"
111
+ puts "Counter Initialize and Fetch Avg: #{counter_init_and_fetch_agg/100*1000} ms over 100 iterations"
112
+ puts "Counter Initialize and Fetch Total: #{counter_init_and_incr_agg*1000} ms"
113
+ puts "Counter Initialize and Fetch Avg: #{counter_init_and_incr_agg/100*1000} ms over 100 iterations"
114
+ puts ""
115
+
116
+ gauge_init_agg = gauge_init_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
117
+ gauge_init_and_fetch_agg = gauge_init_and_fetch_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
118
+ gauge_init_and_set_agg = gauge_init_and_set_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
119
+
120
+ puts "--------------------------------------------------------"
121
+ puts ""
122
+ puts "Gauge Initialize Total: #{gauge_init_agg*1000} ms"
123
+ puts "Gauge Initialize Avg: #{gauge_init_agg/100*1000} ms over 100 iterations"
124
+ puts "Gauge Initialize and Fetch Total: #{gauge_init_and_fetch_agg*1000} ms"
125
+ puts "Gauge Initialize and Fetch Avg: #{gauge_init_and_fetch_agg/100*1000} ms over 100 iterations"
126
+ puts "Gauge Initialize and Set Total: #{gauge_init_and_set_agg*1000} ms"
127
+ puts "Gauge Initialize and Set Avg: #{gauge_init_and_set_agg/100*1000} ms over 100 iterations"
128
+ puts ""
129
+ puts "--------------------------------------------------------"
130
+
131
+ summary_init_agg = summary_init_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
132
+ summary_init_and_fetch_agg = summary_init_and_fetch_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
133
+ summary_init_and_observe_agg = summary_init_and_observe_benchmarks.flatten.inject(0) { |sum, x| sum + x.real }
134
+
135
+ puts ""
136
+ puts "Summary Initialize Total: #{summary_init_agg*1000} ms"
137
+ puts "Summary Initialize Avg: #{summary_init_agg/100*1000} ms over 100 iterations"
138
+ puts "Summary Initialize and Fetch Total: #{summary_init_and_fetch_agg*1000} ms"
139
+ puts "Summary Initialize and Fetch Avg: #{summary_init_and_fetch_agg/100*1000} ms over 100 iterations"
140
+ puts "Summary Initialize and Observe Total: #{summary_init_and_observe_agg*1000} ms"
141
+ puts "Summary Initialize and Observe Avg: #{summary_init_and_observe_agg/100*1000} ms over 100 iterations"
142
+ puts ""
143
+ puts "--------------------------------------------------------"
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
 
12
12
  spec.summary = %q{Gem to sanely emit metrics from Omadahealth rails applications}
13
13
  spec.description = %q{A modular metrics harness for Omadahealth rails applications}
14
- spec.homepage = "https://github.com/omadahealth/omada-metrics"
14
+ spec.homepage = "https://github.com/omadahealth/gremlin"
15
15
  spec.license = "MIT"
16
16
 
17
17
  # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
@@ -1,9 +1,11 @@
1
1
  # Supporting librarires
2
2
  require "active_support/cache"
3
3
  require "active_support/notifications" if defined?(::Rails)
4
- require "quantile"
4
+ require "erb"
5
5
  require "json"
6
+ require "quantile"
6
7
  require "redis_hash"
8
+ require "yaml"
7
9
 
8
10
  # Gem internals
9
11
  require "gremlin/version"
@@ -13,6 +15,7 @@ require "gremlin/instruments/counter"
13
15
  require "gremlin/instruments/gauge"
14
16
  require "gremlin/instruments/summary"
15
17
  require "gremlin/quantile"
18
+ require "gremlin/notification_observer"
16
19
 
17
20
  # Rails support
18
21
  require "gremlin/engine" if defined?(::Rails::Engine)
@@ -20,8 +23,37 @@ require "gremlin/railtie" if defined?(::Rails)
20
23
 
21
24
  module Gremlin
22
25
  class << self
26
+ attr_reader :configuration
27
+
23
28
  def registry
24
29
  @registry ||= Gremlin::Registry.new
25
30
  end
31
+
32
+ def configuration
33
+ unless @configuration
34
+ @configuration = configure do |c|
35
+ c.redis = { :host => "localhost", :port => 6379, :db => 15 }
36
+ c.enabled = true
37
+ end
38
+ end
39
+ @configuration
40
+ end
41
+
42
+ def configure
43
+ config = Config.new
44
+ yield config
45
+ @configuration = config
46
+ end
47
+
48
+ def enabled?
49
+ @configuration.enabled
50
+ end
51
+
52
+ def disabled?
53
+ not enabled?
54
+ end
55
+ end
56
+
57
+ class Config < Struct.new(:redis, :enabled)
26
58
  end
27
59
  end
@@ -9,7 +9,10 @@ module Gremlin
9
9
  @base_labels = base_labels
10
10
  @mutex = Mutex.new
11
11
 
12
+ Redis::Client.default = Redis.new(**Gremlin.configuration.redis)
13
+ @r = Redis.new(**Gremlin.configuration.redis)
12
14
  @values = Redis::NativeHash.find(retention_key) || Redis::NativeHash.new
15
+ @values.redis = Redis.new(**Gremlin.configuration.redis)
13
16
  @values.key = retention_key
14
17
  @values.save
15
18
  end
@@ -65,18 +68,6 @@ module Gremlin
65
68
  end
66
69
  end
67
70
  end
68
-
69
- def get(labels={})
70
- v = @values[labels.to_json]
71
- case type
72
- when :counter
73
- v.to_i
74
- when :gauge
75
- v.to_f
76
- else
77
- v
78
- end
79
- end
80
71
  end
81
72
  end
82
73
  end
@@ -5,10 +5,7 @@ module Gremlin
5
5
  class Counter < Base
6
6
  def increment(labels={}, by=1)
7
7
  @mutex.synchronize do
8
- prev_val = get(labels.to_json) || default
9
- @values[labels.to_json] = prev_val + by
10
- @values.save
11
- @values[labels.to_json]
8
+ @r.hincrby retention_key, labels.to_json, by
12
9
  end
13
10
  end
14
11
 
@@ -23,6 +20,12 @@ module Gremlin
23
20
  def retention_key
24
21
  "gremlin_prometheus_#{node}_metrics_counter_#{name}"
25
22
  end
23
+
24
+ def get(labels={})
25
+ @values.reload!
26
+ v = @values[labels.to_json]
27
+ v.to_i
28
+ end
26
29
  end
27
30
  end
28
31
  end
@@ -5,9 +5,8 @@ module Gremlin
5
5
  class Gauge < Base
6
6
  def set(labels={}, value)
7
7
  @mutex.synchronize do
8
- @values[labels.to_json] = value
9
- @values.save
10
- @values[labels.to_json]
8
+ @r.hset retention_key, labels.to_json, value
9
+ get(labels)
11
10
  end
12
11
  end
13
12
 
@@ -18,6 +17,12 @@ module Gremlin
18
17
  def retention_key
19
18
  "gremlin_prometheus_#{node}_metrics_gauge_#{name}"
20
19
  end
20
+
21
+ def get(labels={})
22
+ @values.reload!
23
+ v = @values[labels.to_json]
24
+ v.to_f
25
+ end
21
26
  end
22
27
  end
23
28
  end
@@ -0,0 +1,38 @@
1
+ module Gremlin
2
+ module NotificationObserver
3
+ class CounterReceiver
4
+ def initialize(name, docstring, labels)
5
+ @instrument = Gremlin::Instruments::Counter.new(name, docstring, labels)
6
+ begin
7
+ Gremlin.registry.register @instrument
8
+ rescue Gremlin::Registry::AlreadyRegisteredError; end
9
+ end
10
+
11
+ def call(name, start, finish, id, payload)
12
+ instrument.increment({})
13
+ end
14
+
15
+ def instrument
16
+ Gremlin.registry.get(@instrument.name)
17
+ end
18
+ end
19
+
20
+ class SummaryReceiver
21
+ def initialize(name, docstring, labels, payload_field)
22
+ @instrument = Gremlin::Instruments::Summary.new(name, docstring, labels)
23
+ begin
24
+ Gremlin.registry.register @instrument
25
+ rescue Gremlin::Registry::AlreadyRegisteredError; end
26
+ @field_to_observe = payload_field
27
+ end
28
+
29
+ def call(name, start, finish, id, payload)
30
+ instrument.observe({}, payload[@field_to_observe.to_sym])
31
+ end
32
+
33
+ def instrument
34
+ Gremlin.registry.get(@instrument.name)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -1,130 +1,93 @@
1
1
  module Gremlin
2
- class Railtie < ::Rails::Railtie
3
- config.before_initialize do
4
- # XXX is there anything to configure? redis?
5
- end
6
-
7
- initializer "gremlin.base_instrumentation" do |app|
8
- environment = ::Rails.env.to_s
9
- application_name = ::Rails.application.class.parent_name.downcase
10
- node = `hostname`.strip
11
-
12
- #
13
- # ActionController
14
- #
15
-
16
- ActiveSupport::Notifications.subscribe "start_processing.action_controller" do |name, start, finish, id, payload|
17
- # Payload contains:
18
- # :controller --- The controller name
19
- # :action --- The action
20
- # :params --- Hash of request parameters without any filtered parameter
21
- # :headers --- Request headers
22
- # :format --- html/js/json/xml etc
23
- # :method --- HTTP request verb
24
- # :path --- Request path
25
-
26
- # Counter to track event occurances
2
+ module ActionController
3
+ class StartProcessingCounterReceiver < Gremlin::NotificationObserver::CounterReceiver
4
+ def call(name, start, finish, id, payload)
27
5
  begin
28
- occurance_counter = Gremlin::Instruments::Counter.new("action_controller_start_processing_events".to_sym,
29
- "ActionController start processing occurance counter.",
30
- application: application_name, environment: environment, node: node)
31
- Gremlin.registry.register occurance_counter
32
- rescue Gremlin::Registry::AlreadyRegisteredError
33
- occurance_counter = Gremlin.registry.get "action_controller_start_processing_events".to_sym
34
- end
35
-
36
- occurance_counter.increment({ controller: payload[:controller].to_s, format: payload[:format].to_s, action: payload[:action] })
6
+ instrument.increment({ controller: payload[:controller].to_s,
7
+ format: payload[:format].to_s,
8
+ action: payload[:action] })
9
+ rescue; end
37
10
  end
11
+ end
38
12
 
39
- ActiveSupport::Notifications.subscribe "process_action.action_controller" do |name, start, finish, id, payload|
40
- # Payload contains:
41
- # :controller --- The controller name
42
- # :action --- The action
43
- # :params --- Hash of request parameters *without any filtered parameter*
44
- # :headers --- Request headers
45
- # :format --- html/js/json/xml etc
46
- # :method --- HTTP request verb
47
- # :path --- Request path
48
- # :status --- HTTP status code
49
- # :view_runtime --- Amount spent in view in ms
50
- # :db_runtime --- Amount spent executing database queries in ms
51
-
52
- # Counter to track event occurances
53
- begin
54
- occurance_counter = Gremlin::Instruments::Counter.new("action_controller_process_action_events".to_sym,
55
- "ActionController process action occurance counter.",
56
- application: application_name, environment: environment, node: node)
57
- Gremlin.registry.register occurance_counter
58
- rescue Gremlin::Registry::AlreadyRegisteredError
59
- occurance_counter = Gremlin.registry.get "action_controller_process_action_events".to_sym
60
- end
61
-
62
- occurance_counter.increment({ controller: payload[:controller].to_s, format: payload[:format].to_s, action: payload[:action], status: payload[:status] })
63
-
13
+ class ProcessActionCounterReceiver < Gremlin::NotificationObserver::CounterReceiver
14
+ def call(name, start, finish, id, payload)
64
15
  begin
65
- db_summary = Gremlin::Instruments::Summary.new("action_controller_process_action_db_runtime_ms".to_sym,
66
- "ActionController process action DB runtime in milliseconds.",
67
- application: application_name, environment: environment, node: node)
68
- Gremlin.registry.register db_summary
69
- rescue Gremlin::Registry::AlreadyRegisteredError
70
- db_summary = Gremlin.registry.get "action_controller_process_action_db_runtime_ms".to_sym
71
- end
72
-
73
- db_summary.observe({ controller: payload[:controller], method: payload[:method], status: payload[:status], action: payload[:action] }, payload[:db_runtime])
16
+ instrument.increment({ controller: payload[:controller].to_s,
17
+ format: payload[:format].to_s,
18
+ action: payload[:action],
19
+ status: payload[:status] })
20
+ rescue; end
21
+ end
22
+ end
74
23
 
24
+ class ProcessActionSummaryReceiver < Gremlin::NotificationObserver::SummaryReceiver
25
+ def call(name, start, finish, id, payload)
75
26
  begin
76
- view_summary = Gremlin::Instruments::Summary.new("action_controller_process_action_view_runtime_ms".to_sym,
77
- "ActionController process action view runtime in milliseconds.",
78
- application: application_name, environment: environment, node: node)
79
- Gremlin.registry.register view_summary
80
- rescue Gremlin::Registry::AlreadyRegisteredError
81
- view_summary = Gremlin.registry.get "action_controller_process_action_view_runtime_ms".to_sym
82
- end
83
-
84
- view_summary.observe({ controller: payload[:controller], method: payload[:method], status: payload[:status], action: payload[:action] }, payload[:view_runtime])
27
+ instrument.observe({ controller: payload[:controller],
28
+ method: payload[:method],
29
+ status: payload[:status],
30
+ action: payload[:action] },
31
+ payload[@field_to_observe.to_sym])
32
+ rescue; end
33
+ end
34
+ end
35
+ end
36
+
37
+ class Railtie < ::Rails::Railtie
38
+ config.before_initialize do
39
+ Gremlin.configure do |c|
40
+ c.redis = { url: "localhost", port: 6379, db: 15 }
41
+ c.enabled = true
85
42
  end
86
43
 
87
- ActiveSupport::Notifications.subscribe "redirect_to.action_controller" do |name, start, finish, id, payload|
88
- # Payload contains:
89
- # :status --- HTTP response code
90
- # :location --- URL to redirect to
91
-
92
- # Counter to track event occurances
93
- begin
94
- occurance_counter = Gremlin::Instruments::Counter.new("action_controller_redirect_to_events".to_sym,
95
- "ActionController redirect to occurance counter.",
96
- application: application_name, environment: environment, node: node)
97
- Gremlin.registry.register occurance_counter
98
- rescue Gremlin::Registry::AlreadyRegisteredError
99
- occurance_counter = Gremlin.registry.get "action_controller_redirect_to_events".to_sym
44
+ conf_file = ::Rails.root.join("config", "gremlin.yml")
45
+ config = YAML.load(ERB.new(File.read(conf_file)).result) if File.exists?(conf_file)
46
+ if config
47
+ Gremlin.configure do |c|
48
+ c.redis = config[::Rails.env] ? config[::Rails.env]["redis"] : config["redis"]
49
+ c.enabled = config[::Rails.env] ? config[::Rails.env]["enabled"] : config["enabled"]
100
50
  end
101
-
102
- occurance_counter.increment({ status: payload[:status] })
103
51
  end
52
+ end
104
53
 
105
- ##
106
- ## ActiveRecord
107
- ##
54
+ initializer "gremlin.base_instrumentation" do |app|
55
+ environment = ::Rails.env.to_s
56
+ application_name = ::Rails.application.class.parent_name.downcase
57
+ node = `hostname`.strip
58
+ basic_labels = { node: node, app: application_name, env: environment }
108
59
 
109
- ActiveSupport::Notifications.subscribe "sql.active_record" do |name, start, finish, id, payload|
110
- # Payload contains:
111
- # :sql --- SQL statement
112
- # :name --- Name of the operation
113
- # :connection_id --- self.object_id
114
- # :binds --- Bind parameters
60
+ next if Gremlin.disabled?
115
61
 
116
- # Counter to track event occurances
117
- begin
118
- occurance_counter = Gremlin::Instruments::Counter.new("active_record_sql_events".to_sym,
119
- "ActiveRecord SQL occurance counter.",
120
- application: application_name, environment: environment, node: node)
121
- Gremlin.registry.register occurance_counter
122
- rescue Gremlin::Registry::AlreadyRegisteredError
123
- occurance_counter = Gremlin.registry.get "active_record_sql_events".to_sym
124
- end
62
+ #
63
+ # ActionController instrumentation
64
+ #
125
65
 
126
- occurance_counter.increment
127
- end
66
+ # Generic instrumentation for /(start_processing|process_action|redirect_to)\.action_controller/
67
+ occurance_counter = Gremlin::NotificationObserver::CounterReceiver.new("notification_count",
68
+ "Count of notifications handled by Gremlin.",
69
+ basic_labels)
70
+ ActiveSupport::Notifications.subscribe /(start_processing|process_action|redirect_to)\.action_controller/, occurance_counter
71
+
72
+ # Instrumentation for start_processing.action_controller
73
+ start_processing_occurance_counter = Gremlin::ActionController::StartProcessingCounterReceiver.new("action_controller_start_processing_count",
74
+ "Count of start_processing.action_controller notifications handled by Gremlin.",
75
+ basic_labels)
76
+ ActiveSupport::Notifications.subscribe "start_processing.action_controller", start_processing_occurance_counter
77
+
78
+ # Instrumentation for process_action.action_controller
79
+ view_summary = Gremlin::ActionController::ProcessActionSummaryReceiver.new("action_controller_process_action_view_runtime_ms",
80
+ "ActionController process action view runtime in milliseconds.",
81
+ basic_labels, "view_runtime")
82
+ db_summary = Gremlin::ActionController::ProcessActionSummaryReceiver.new("action_controller_process_action_db_runtime_ms",
83
+ "ActionController process action db runtime in milliseconds.",
84
+ basic_labels, "db_runtime")
85
+ process_action_occurance_counter = Gremlin::ActionController::ProcessActionCounterReceiver.new("action_controller_process_action_count",
86
+ "Count of process_action.action_controller notifications handled by Gremlin.",
87
+ basic_labels)
88
+ ActiveSupport::Notifications.subscribe "process_action.action_controller", process_action_occurance_counter
89
+ ActiveSupport::Notifications.subscribe "process_action.action_controller", view_summary
90
+ ActiveSupport::Notifications.subscribe "process_action.action_controller", db_summary
128
91
  end
129
92
  end
130
93
  end
@@ -5,7 +5,9 @@ module Gremlin
5
5
  NotAMetricError = Class.new StandardError
6
6
 
7
7
  def initialize
8
+ Redis::Client.default = Redis.new(**Gremlin.configuration.redis)
8
9
  @metrics = Redis::NativeHash.find(retention_key) || Redis::NativeHash.new()
10
+ @metrics.redis = Redis.new(**Gremlin.configuration.redis)
9
11
  @metrics.key = retention_key
10
12
  @metrics.save
11
13
 
@@ -26,6 +28,10 @@ module Gremlin
26
28
  end
27
29
  end
28
30
 
31
+ def dump_metrics
32
+ @metrics
33
+ end
34
+
29
35
  def get(name)
30
36
  m = @metrics[name.to_sym]
31
37
  deserialize(m) unless m.nil?
@@ -1,3 +1,3 @@
1
1
  module Gremlin
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gremlin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kevin G. Phillips
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2017-01-17 00:00:00.000000000 Z
11
+ date: 2017-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -139,6 +139,7 @@ files:
139
139
  - Gemfile
140
140
  - Gemfile.lock
141
141
  - app/controllers/gremlin/metrics_controller.rb
142
+ - benchmark.rb
142
143
  - config/routes.rb
143
144
  - gremlin.gemspec
144
145
  - lib/gremlin.rb
@@ -147,13 +148,14 @@ files:
147
148
  - lib/gremlin/instruments/counter.rb
148
149
  - lib/gremlin/instruments/gauge.rb
149
150
  - lib/gremlin/instruments/summary.rb
151
+ - lib/gremlin/notification_observer.rb
150
152
  - lib/gremlin/quantile.rb
151
153
  - lib/gremlin/quantile/estimator.rb
152
154
  - lib/gremlin/quantile/quantile.rb
153
155
  - lib/gremlin/railtie.rb
154
156
  - lib/gremlin/registry.rb
155
157
  - lib/gremlin/version.rb
156
- homepage: https://github.com/omadahealth/omada-metrics
158
+ homepage: https://github.com/omadahealth/gremlin
157
159
  licenses:
158
160
  - MIT
159
161
  metadata: