honeycomb-rails 0.1.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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e4126edc89b123ee4b3e97d5a11f71f7870dc780
4
+ data.tar.gz: 73d1591815b66f612c8b8ef83623b0d4285d6ba1
5
+ SHA512:
6
+ metadata.gz: 0a97d7fe16561fec60e4065aed9de06af9486581e662b3ab919cdd83748c7ff26a836c5fbcbfc66e7c6311b5eb118708811afc820570911af75638d11a4c69a8
7
+ data.tar.gz: f80b392f7e5561b075ce73824a7dbe729123af30224a5a4fc711282d5e3da8340e60142f0a81278213d9422e0af2eb1823875a6c34ceec7a73a9ff3315c5c29f
@@ -0,0 +1,39 @@
1
+ # honeycomb-rails
2
+
3
+ Easily instrument your Rails apps with [Honeycomb](https://honeycomb.io).
4
+
5
+ ## Getting started
6
+
7
+ Add the following to your Gemfile:
8
+
9
+ ```ruby
10
+ gem 'honeycomb-rails'
11
+ ```
12
+
13
+ Then create a file in your application repo called `config/initializers/honeycomb.rb` with the following contents:
14
+
15
+ ```ruby
16
+ HoneycombRails.configure do |conf|
17
+ conf.writekey = 'your honeycomb writekey here'
18
+ conf.dataset = 'your app name'
19
+ conf.db_dataset = 'your app name-activerecord'
20
+ end
21
+ ```
22
+
23
+ Now check out our [guide](https://honeycomb.io/docs/guides/rails/) to see what kind of visibility you can get from your app.
24
+
25
+ ## Configuration
26
+
27
+ See [docs](http://www.rubydoc.info/gems/honeycomb-rails/HoneycombRails/Config) for available config options.
28
+
29
+ ## Documentation
30
+
31
+ See [rubydoc](http://www.rubydoc.info/gems/honeycomb-rails/) for gem documentation.
32
+
33
+ ## Contributions
34
+
35
+ Features, bug fixes and other changes are gladly accepted. Please
36
+ open issues or a pull request with your change. Remember to add your name to the
37
+ CONTRIBUTORS file!
38
+
39
+ All contributions will be released under the Apache License 2.0.
@@ -0,0 +1,27 @@
1
+ if !defined?(Rails)
2
+ raise LoadError, 'honeycomb-rails requires Rails (maybe you meant libhoney?)'
3
+ end
4
+
5
+ require 'honeycomb-rails/config'
6
+
7
+ module HoneycombRails
8
+ class << self
9
+ # Run this at app initialization time to configure honeycomb-rails. e.g.
10
+ #
11
+ # HoneycombRails.configure do |conf|
12
+ # conf.writekey = 'abc123def'
13
+ # end
14
+ #
15
+ # See {Config} for available options.
16
+ #
17
+ # @yield [Config] the singleton config.
18
+ def configure
19
+ raise "Please pass a block to #{name}#configure" unless block_given?
20
+
21
+ yield config
22
+ config
23
+ end
24
+ end
25
+ end
26
+
27
+ require 'honeycomb-rails/railtie'
@@ -0,0 +1,53 @@
1
+ module HoneycombRails
2
+ # Configuration for the Honeycomb Rails integration.
3
+ #
4
+ # Specify this at app initialization time via {configure}.
5
+ class Config
6
+ def initialize
7
+ @dataset = 'rails'
8
+ @db_dataset = 'active_record'
9
+ @record_flash = true
10
+ @record_user = :detect
11
+ end
12
+
13
+ # Whether to record flash messages (default: true).
14
+ attr_writer :record_flash
15
+ # Whether to record flash messages (default: true).
16
+ def record_flash?
17
+ !!@record_flash
18
+ end
19
+
20
+ # If set, determines how to record the current user during request processing (default: :detect). Set to nil or false to disable.
21
+ #
22
+ # Valid values:
23
+ #
24
+ # * :devise - if your app uses Devise for authentication
25
+ # * :detect - autodetect how to determine the current user
26
+ # * nil, false - disable recording current user
27
+ #
28
+ # You can also pass a Proc, which will be called with the current controller
29
+ # instance during each request, and which should return a hash of metadata
30
+ # about the current user.
31
+ attr_accessor :record_user
32
+
33
+ # The Honeycomb dataset to send request events to (default: 'rails').
34
+ attr_accessor :dataset
35
+ # The Honeycomb dataset to send ActiveRecord query events to (default: 'active_record').
36
+ attr_accessor :db_dataset
37
+ # The Honeycomb write key for your team (must be specified).
38
+ attr_accessor :writekey
39
+ end
40
+
41
+ class << self
42
+ # @api private
43
+ def config
44
+ @config ||= Config.new
45
+ end
46
+
47
+ # For test use only
48
+ # @api private
49
+ def reset_config_to_default!
50
+ @config = Config.new
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,6 @@
1
+ module HoneycombRails
2
+ module Constants
3
+ # @api private
4
+ EVENT_METADATA_KEY = :honeycomb_metadata
5
+ end
6
+ end
@@ -0,0 +1 @@
1
+ require 'honeycomb-rails/extensions/action_controller'
@@ -0,0 +1,30 @@
1
+ module HoneycombRails
2
+ module Extensions
3
+ module ActionController
4
+ module InstanceMethods
5
+ def self.included(controller_class)
6
+ super
7
+
8
+ controller_class.before_action do
9
+ honeycomb_initialize
10
+ end
11
+ end
12
+
13
+ def honeycomb_initialize
14
+ @honeycomb_metadata = {}
15
+ end
16
+
17
+ # Hash of metadata to be added to the event we will send to Honeycomb
18
+ # for the current request.
19
+ #
20
+ # To annotate the event with custom information (e.g. from a particular
21
+ # controller action), just add data to this hash: e.g.
22
+ #
23
+ # honeycomb_metadata[:num_posts] = @posts.size
24
+ #
25
+ # @return [Hash<String=>Any>]
26
+ attr_reader :honeycomb_metadata
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1 @@
1
+ require 'honeycomb-rails/overrides/action_controller_instrumentation'
@@ -0,0 +1,69 @@
1
+ require 'honeycomb-rails/config'
2
+ require 'honeycomb-rails/constants'
3
+
4
+ module HoneycombRails
5
+ module Overrides
6
+ module ActionControllerInstrumentation
7
+ def append_info_to_payload(payload)
8
+ super
9
+
10
+ metadata = honeycomb_metadata
11
+
12
+ metadata.merge!(honeycomb_user_metadata)
13
+
14
+ if HoneycombRails.config.record_flash?
15
+ flash.each do |k, v|
16
+ metadata[:"flash_#{k}"] = v
17
+ end
18
+ end
19
+
20
+ # Attach to ActiveSupport::Instrumentation payload for consumption by
21
+ # subscribers/process_action.rb
22
+ payload[Constants::EVENT_METADATA_KEY] = metadata
23
+ end
24
+
25
+ def honeycomb_user_metadata
26
+ if defined?(@honeycomb_user_proc)
27
+ return @honeycomb_user_proc.call(self)
28
+ end
29
+
30
+ case HoneycombRails.config.record_user
31
+ when :detect
32
+ honeycomb_detect_user_methods!
33
+ honeycomb_user_metadata
34
+ when :devise
35
+ honeycomb_user_metadata_devise
36
+ when Proc
37
+ @honeycomb_user_proc = HoneycombRails.config.record_user
38
+ honeycomb_user_metadata
39
+ when nil, false
40
+ {}
41
+ else
42
+ raise "Invalid value for HoneycombRails.config.record_user: #{HoneycombRails.config.record_user.inspect}"
43
+ end
44
+ end
45
+
46
+ def honeycomb_user_metadata_devise
47
+ if current_user
48
+ {
49
+ current_user_id: current_user.id,
50
+ current_user_email: current_user.email,
51
+ current_user_admin: !!current_user.try(:admin?),
52
+ }
53
+ else
54
+ {}
55
+ end
56
+ end
57
+
58
+ def honeycomb_detect_user_methods!
59
+ if respond_to?(:current_user)
60
+ # This could be more sophisticated, but it'll do for now
61
+ HoneycombRails.config.record_user = :devise
62
+ else
63
+ logger.error "HoneycombRails.config.record_user = :detect but couldn't detect user methods; disabling user recording."
64
+ HoneycombRails.config.record_user = false
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,35 @@
1
+ require 'honeycomb-rails/extensions'
2
+ require 'honeycomb-rails/overrides'
3
+ require 'honeycomb-rails/subscribers'
4
+
5
+ require 'libhoney'
6
+
7
+ module HoneycombRails
8
+ class Railtie < ::Rails::Railtie
9
+ initializer 'honeycomb.action_controller_extensions', after: :action_controller do
10
+ ::ActionController::Base.include(Extensions::ActionController::InstanceMethods)
11
+ end
12
+
13
+ initializer 'honeycomb.action_controller_overrides', after: :action_controller do
14
+ ::ActionController::Base.include(Overrides::ActionControllerInstrumentation)
15
+ end
16
+
17
+ # set up libhoney after application initialization so that any config in
18
+ # the app's config/initializers has taken effect.
19
+ config.after_initialize do
20
+ writekey = HoneycombRails.config.writekey
21
+ dataset = HoneycombRails.config.dataset
22
+ @libhoney = Libhoney::Client.new(writekey: writekey, dataset: dataset)
23
+ end
24
+
25
+ config.after_initialize do
26
+ db_builder = @libhoney.builder
27
+ db_builder.dataset = HoneycombRails.config.db_dataset
28
+
29
+ [
30
+ Subscribers::ProcessAction.new(@libhoney),
31
+ Subscribers::ActiveRecord.new(db_builder),
32
+ ].each(&:subscribe!)
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,2 @@
1
+ require 'honeycomb-rails/subscribers/active_record'
2
+ require 'honeycomb-rails/subscribers/process_action'
@@ -0,0 +1,36 @@
1
+ require 'active_support/core_ext/hash'
2
+ require 'active_support/notifications'
3
+ require 'rails'
4
+
5
+ module HoneycombRails
6
+ module Subscribers
7
+ class ActiveRecord
8
+ def initialize(honeybuilder)
9
+ @honeybuilder = honeybuilder
10
+ end
11
+
12
+ def subscribe!
13
+ ::ActiveSupport::Notifications.subscribe(/sql.active_record/) do |*args|
14
+ call(*args)
15
+ end
16
+ end
17
+
18
+ def call(*args)
19
+ event = ActiveSupport::Notifications::Event.new(*args)
20
+ data = event.payload.slice(:name, :connection_id)
21
+ data[:sql] = event.payload[:sql].strip
22
+ event.payload[:binds].each do |b|
23
+ data["bind_#{ b.name }".to_sym] = b.value
24
+ end
25
+ data[:duration] = event.duration
26
+
27
+ # NOTE: Backtraces can be very verbose! Keep an eye on the data that gets sent
28
+ # into Honeycomb and, if needed, experiment with BacktraceCleaner's
29
+ # filters and silencers to trim down the noise.
30
+ data[:local_stack] = Rails.backtrace_cleaner.clean(caller)
31
+
32
+ @honeybuilder.send_now(data)
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,44 @@
1
+ require 'honeycomb-rails/constants'
2
+
3
+ require 'active_support/core_ext/hash'
4
+ require 'active_support/notifications'
5
+
6
+ module HoneycombRails
7
+ module Subscribers
8
+ class ProcessAction
9
+ def initialize(libhoney)
10
+ @libhoney = libhoney
11
+ end
12
+
13
+ def subscribe!
14
+ ::ActiveSupport::Notifications.subscribe(/process_action.action_controller/) do |*args|
15
+ call(*args)
16
+ end
17
+ end
18
+
19
+ def call(*args)
20
+ event = ::ActiveSupport::Notifications::Event.new(*args)
21
+
22
+ # These are the keys we're interested in! Skipping noisy keys (:headers, :params) for now.
23
+ data = event.payload.slice(:controller, :action, :method, :path, :format,
24
+ :status, :db_runtime, :view_runtime)
25
+
26
+ # Massage data to return "all" as the :format if not set
27
+ if !data[:format] || data[:format] == "format:*/*"
28
+ data[:format] = "all"
29
+ end
30
+
31
+ # Pull top-level attributes off of the ActiveSupport Event.
32
+ data[:duration_ms] = event.duration
33
+
34
+ # Add anything we added in our controller-level instrumentation (see
35
+ # overrides/action_controller_instrumentation.rb)
36
+ if event.payload.key?(Constants::EVENT_METADATA_KEY)
37
+ data.merge!(event.payload[Constants::EVENT_METADATA_KEY])
38
+ end
39
+
40
+ @libhoney.send_now(data)
41
+ end
42
+ end
43
+ end
44
+ end
metadata ADDED
@@ -0,0 +1,145 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: honeycomb-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sam Stokes
8
+ - Christine Yen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2017-11-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: libhoney
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 1.3.2
21
+ type: :runtime
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ version: 1.3.2
28
+ - !ruby/object:Gem::Dependency
29
+ name: rails
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 3.0.0
35
+ type: :runtime
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: 3.0.0
42
+ - !ruby/object:Gem::Dependency
43
+ name: rake
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: rspec
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: yard
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: libhoney
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 1.4.0
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: 1.4.0
98
+ description: |2
99
+ Get fine-grained visibility into the behavior and performance of your
100
+ Rails web app. This gem instruments your app to send events to Honeycomb
101
+ (https://honeycomb.io) each time it processes an HTTP request or makes a
102
+ database query.
103
+ email:
104
+ - sam@honeycomb.io
105
+ executables: []
106
+ extensions: []
107
+ extra_rdoc_files: []
108
+ files:
109
+ - README.md
110
+ - lib/honeycomb-rails.rb
111
+ - lib/honeycomb-rails/config.rb
112
+ - lib/honeycomb-rails/constants.rb
113
+ - lib/honeycomb-rails/extensions.rb
114
+ - lib/honeycomb-rails/extensions/action_controller.rb
115
+ - lib/honeycomb-rails/overrides.rb
116
+ - lib/honeycomb-rails/overrides/action_controller_instrumentation.rb
117
+ - lib/honeycomb-rails/railtie.rb
118
+ - lib/honeycomb-rails/subscribers.rb
119
+ - lib/honeycomb-rails/subscribers/active_record.rb
120
+ - lib/honeycomb-rails/subscribers/process_action.rb
121
+ homepage: https://github.com/honeycombio/honeycomb-rails
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: 2.0.0
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.6.11
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Easily instrument your Rails apps with Honeycomb
145
+ test_files: []