honeycomb-beeline 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
  SHA256:
3
- metadata.gz: d8226a2444f449e489670d844e544ec8986ff40b32016ae9199031ae2fef1df8
4
- data.tar.gz: 11e5d5f9dc8dcc000e6a4cdb5dbebd35f0fe332c9ff5ab0a85f4b084f428f7bd
3
+ metadata.gz: 32263488f94bb0aa40611cb4706d001d62885b4de58f86ecd3ce8ccc0416cbc3
4
+ data.tar.gz: 53b773d27af7256c876009a824b8855418d80faa460815a5a3c54febe8ac6514
5
5
  SHA512:
6
- metadata.gz: 5370b82bf792605cf79bcf67a5930a0430f498e84f0472e5046b3a027d52761d0fbc3410b21374a2fc32c61beb20738defa47db30a80a650b9ede888b09bc13a
7
- data.tar.gz: c70d4cd7b0ea59c6642286db68b38bd0c637715e5468bfa096c8684486d93bcbebb0b7b037be01bb440f10c645199465a6500dfd54ab62fb602e467dea017a46
6
+ metadata.gz: 2bbb53742e2b9ccd2392893a260ce17d74e27eb46d9e20a9f56e60a0fca910cd5007734880a36d825f33ad188917a02dbb3d7dbf754e9950abfa04fb6a07b67e
7
+ data.tar.gz: 635c9e858d1393f4cd61ecbe375faeb60fc5b6bcdf8727fea662b10562371334a607e2ec757bc96cc9ec157c2f73bf828a586547de7091c0f5c47a8f0d685c4d
data/README.md CHANGED
@@ -4,15 +4,21 @@ The Honeycomb Beeline for Ruby is the fastest path to observability for your
4
4
  Ruby apps. It understands the common packages you use and automatically
5
5
  instruments them to send useful events to Honeycomb.
6
6
 
7
- ## Setup
7
+ Sign up for a [Honeycomb trial](https://ui.honeycomb.io/signup) to obtain a
8
+ writekey before starting.
9
+
10
+ ## Installation
8
11
 
9
- Setup requires minimal changes to your app. First add this line to your Gemfile:
12
+ Add `honeycomb-beeline` to your Gemfile:
10
13
 
11
14
  ```ruby
12
15
  gem 'honeycomb-beeline'
13
16
  ```
17
+ Now run `bundle install` to install the gem.
14
18
 
15
- Then in your app's startup script - e.g. for a Rack app "config.ru" is a good
19
+ ## Setup
20
+
21
+ In your app's startup script - e.g. for a Rack app "config.ru" is a good
16
22
  place - add the following code:
17
23
 
18
24
  ```ruby
@@ -21,8 +27,6 @@ require 'honeycomb-beeline'
21
27
  Honeycomb.init
22
28
  ```
23
29
 
24
- Now run `bundle install` to install the gem.
25
-
26
30
  ## Configuration
27
31
 
28
32
  You'll need to configure your Honeycomb writekey so that your app can
@@ -51,13 +55,160 @@ Honeycomb.init(writekey: '<MY HONEYCOMB WRITEKEY>', dataset: 'my-app')
51
55
  Note that you should not check your Honeycomb writekey into version control, as
52
56
  it is sensitive and allows sending data to your Honeycomb account.
53
57
 
54
- ## Development
58
+ ## Example questions
59
+
60
+ Now your app is instrumented and sending events, try using Honeycomb to ask
61
+ these questions:
62
+
63
+ * Which of my app's routes are the slowest?
64
+ ```
65
+ BREAKDOWN: request.path
66
+ CALCULATE: P99(duration_ms)
67
+ FILTER: type == http_server
68
+ ORDER BY: P99(duration_ms) DESC
69
+ ```
70
+ * Where's my app spending the most time?
71
+ ```
72
+ BREAKDOWN: type
73
+ CALCULATE: SUM(duration_ms)
74
+ ORDER BY: SUM(duration_ms) DESC
75
+ ```
76
+ * Which users are using the endpoint that I'd like to deprecate? First add a
77
+ [custom field](#adding-additional-context) `user.email`, then try:
78
+ ```
79
+ BREAKDOWN: app.user.email
80
+ CALCULATE: COUNT
81
+ FILTER: request.path == /my/deprecated/endpoint
82
+ ```
83
+
84
+ ## Example event
85
+
86
+ Here is an example of an `http_server` event (recording that your web app
87
+ processed an incoming HTTP request) emitted by the Beeline:
88
+
89
+ ```json
90
+ {
91
+ "meta.beeline_version": "0.2.0",
92
+ "meta.local_hostname": "killerbee",
93
+ "service_name": "my-test-app",
94
+ "meta.package": "rack",
95
+ "meta.package_version": "1.3",
96
+ "type": "http_server",
97
+ "name": "GET /dashboard",
98
+ "request.method": "GET",
99
+ "request.path": "/dashboard",
100
+ "request.protocol": "https",
101
+ "request.http_version": "HTTP/1.1",
102
+ "request.host": "my-test-app.example.com",
103
+ "request.remote_addr": "172.217.1.238",
104
+ "request.header.user_agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
105
+ "trace.trace_id": "b694512a-833f-4b35-be5f-6c742ba18e12",
106
+ "trace.span_id": "c35cc326-ed90-4881-a4a8-68526d252f2e",
107
+ "response.status_code": 200,
108
+ "duration_ms": 303.057396
109
+ }
110
+ ```
111
+
112
+ ## Adding additional context
113
+
114
+ The Beeline will automatically instrument your incoming HTTP requests, database
115
+ queries and outbound HTTP requests to send events to Honeycomb. However, it can
116
+ be very helpful to extend these events with additional context specific to your
117
+ app. You can add your own fields by calling `Rack::Honeycomb.add_field`. For
118
+ example, this snippet shows how to associate the currently logged-in user with
119
+ each `http_server` event:
120
+
121
+ ```ruby
122
+ get '/hello' do
123
+ user = authenticate_user()
124
+
125
+ # this will add a custom field 'app.user.email' to the http_server event
126
+ Rack::Honeycomb.add_field(env, 'user.email', user.email)
127
+
128
+ "Hello, #{user.name}!"
129
+ end
130
+ ```
131
+
132
+ ## Instrumented packages
133
+
134
+ The Beeline will automatically send the following events if you are using one of
135
+ the listed packages:
136
+
137
+ ### `http_server` (incoming HTTP requests)
138
+
139
+ * [Sinatra](http://sinatrarb.com) - via [rack-honeycomb](https://github.com/honeycombio/rack-honeycomb)
140
+ * Any other [Rack](https://rack.github.io)-based web app - via [rack-honeycomb](https://github.com/honeycombio/rack-honeycomb) (requires manually adding the middleware)
141
+
142
+ ### `db` (database queries)
143
+
144
+ * [ActiveRecord](https://rubygems.org/gems/activerecord) - via
145
+ [activerecord-honeycomb](https://github.com/honeycombio/activerecord-honeycomb)
146
+ * [Sequel](https://sequel.jeremyevans.net/) - via
147
+ [sequel-honeycomb](https://github.com/honeycombio/sequel-honeycomb)
148
+
149
+ ### `http_client` (outbound HTTP requests)
150
+
151
+ * [Faraday](https://github.com/lostisland/faraday) - via
152
+ [faraday-honeycomb](https://github.com/honeycombio/faraday-honeycomb)
153
+
154
+ ## Known limitations
155
+
156
+ * The Beeline will try to autodetect your web framework and automatically
157
+ install its middleware. Currently this only works for Sinatra apps, and
158
+ also fails in some more exotic configurations of Sinatra. If you find you
159
+ aren't seeing any events for processing web requests, you can install the
160
+ [middleware](https://www.rubydoc.info/gems/rack-honeycomb) manually: e.g.
161
+ `use Rack::Honeycomb::Middleware`.
162
+ * Rails apps are not supported currently; instead, use our [Rails
163
+ integration](https://github.com/honeycombio/honeycomb-rails).
164
+ * Alternative concurrency models such as EventMachine or Celluloid are not
165
+ currently supported.
166
+
167
+ If support for one of these scenarios is important to you, please [let us
168
+ know](#get-in-touch)!
169
+
170
+ ## Troubleshooting
55
171
 
56
- ### Releasing a new version
172
+ If you've setup the Beeline as above but you aren't seeing data for your app in
173
+ Honeycomb, or you're seeing errors on startup, here are a few things to try:
57
174
 
58
- Travis will automatically upload tagged releases to Rubygems. To release a new
59
- version, run
175
+ ### Debug mode
176
+
177
+ To verify the Beeline is working as expected, try running it in debug mode:
178
+
179
+ ```ruby
180
+ Honeycomb.init(debug: true)
60
181
  ```
61
- bump patch --tag # Or bump minor --tag, etc.
62
- git push --follow-tags
182
+
183
+ Alternatively, you can also enable debug mode with no code changes by setting
184
+ `HONEYCOMB_DEBUG=true` in your environment.
185
+
186
+ In debug mode, the Beeline will not send any events to Honeycomb, but will
187
+ instead print them to your app's standard error. It will also log startup
188
+ messages to standard error.
189
+
190
+ ### Logging
191
+
192
+ By default the Beeline will log errors but otherwise keep quiet. To see more
193
+ detail about what it's doing, you can pass a logger object (compliant with the
194
+ [stdlib Logger API](https://ruby-doc.org/stdlib-2.4.1/libdoc/logger/rdoc/)) to
195
+ `Honeycomb.init`:
196
+
197
+ ```ruby
198
+ require 'logger'
199
+ logger = Logger.new($stderr)
200
+ logger.level = :info # determine how much detail you want to see
201
+ Honeycomb.init(logger: logger)
63
202
  ```
203
+
204
+ A level of `:debug` will show you detail about each library being instrumented,
205
+ whereas a level of `:info` will just print a few progress messages.
206
+
207
+ ### Get in touch
208
+
209
+ This beeline is still young, so please reach out to
210
+ [support@honeycomb.io](mailto:support@honeycomb.io) or ping us with the chat
211
+ bubble on [our website](https://www.honeycomb.io){target=_blank} for assistance.
212
+ We also welcome [bug
213
+ reports](https://github.com/honeycombio/beeline-ruby/issues) and
214
+ [contributions](https://github.com/honeycombio/beeline-ruby/blob/master/CONTRIBUTING.md).
@@ -1,6 +1,6 @@
1
1
  module Honeycomb
2
2
  module Beeline
3
3
  GEM_NAME = 'honeycomb-beeline'
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
6
6
  end
@@ -2,6 +2,7 @@ require 'honeycomb/beeline/version'
2
2
 
3
3
  require 'libhoney'
4
4
 
5
+ require 'logger'
5
6
  require 'socket'
6
7
 
7
8
  module Honeycomb
@@ -16,14 +17,19 @@ module Honeycomb
16
17
  dataset: ENV['HONEYCOMB_DATASET'],
17
18
  service_name: ENV['HONEYCOMB_SERVICE'] || dataset,
18
19
  without: [],
20
+ debug: ENV.key?('HONEYCOMB_DEBUG'),
19
21
  logger: nil,
20
22
  **options
21
23
  )
22
24
  reset
23
25
 
24
- @logger = logger
25
26
  @without = without
26
27
  @service_name = service_name
28
+ @logger = logger || Logger.new($stderr).tap {|l| l.level = Logger::WARN }
29
+ @debug = debug
30
+ if debug
31
+ @logger ||= Logger.new($stderr)
32
+ end
27
33
 
28
34
  options = options.merge(writekey: writekey, dataset: dataset)
29
35
  @client = new_client(options)
@@ -40,11 +46,17 @@ module Honeycomb
40
46
  client = options.delete :client
41
47
 
42
48
  options = {user_agent_addition: USER_AGENT_SUFFIX}.merge(options)
43
- client ||= begin
44
- unless options[:writekey] && options[:dataset]
45
- raise ArgumentError, "must specify writekey and dataset"
49
+ if @debug
50
+ raise ArgumentError, "can't specify both client and debug options", caller if client
51
+ @logger.info 'logging events to standard error instead of sending to Honeycomb' if @logger
52
+ client = Libhoney::LogClient.new(verbose: true, **options)
53
+ else
54
+ client ||= if options[:writekey] && options[:dataset]
55
+ Libhoney::Client.new(options)
56
+ else
57
+ @logger.warn "#{self.name}: no #{options[:writekey] ? 'dataset' : 'writekey'} configured, disabling sending events" if @logger
58
+ Libhoney::NullClient.new(options)
46
59
  end
47
- Libhoney::Client.new(options)
48
60
  end
49
61
  client.add_field 'meta.beeline_version', Beeline::VERSION
50
62
  client.add_field 'meta.local_hostname', Socket.gethostname rescue nil
@@ -56,9 +68,11 @@ module Honeycomb
56
68
  raise ArgumentError unless block_given?
57
69
 
58
70
  hook = if block.arity == 0
59
- ->(_) { block.call }
60
- elsif block.arity > 1
61
- raise ArgumentError, 'Honeycomb.after_init block should take 1 argument'
71
+ ->(_, _) { block.call }
72
+ elsif block.arity == 1
73
+ ->(client, _) { block.call client }
74
+ elsif block.arity > 2
75
+ raise ArgumentError, 'Honeycomb.after_init block should take 2 arguments'
62
76
  else
63
77
  block
64
78
  end
@@ -87,6 +101,7 @@ module Honeycomb
87
101
  @logger = nil
88
102
  @without = nil
89
103
  @service_name = nil
104
+ @debug = nil
90
105
  @client = nil
91
106
  @initialized = false
92
107
  end
@@ -100,14 +115,14 @@ module Honeycomb
100
115
  if @without.include?(label)
101
116
  @logger.debug "Skipping hook '#{label}' due to opt-out" if @logger
102
117
  else
103
- block.call @client
118
+ block.call @client, @logger
104
119
  end
105
120
  rescue => e
106
- warn "Honeycomb.init hook '#{label}' raised #{e.class}: #{e}"
121
+ @logger.warn "Honeycomb.init hook '#{label}' raised #{e.class}: #{e}" if @logger
107
122
  end
108
123
  end
109
124
 
110
- after_init :log do
111
- @logger.info "Honeycomb inited" if @logger
125
+ after_init :log do |_, logger|
126
+ logger.info "Honeycomb inited" if logger
112
127
  end
113
128
  end
@@ -15,10 +15,12 @@ module Honeycomb
15
15
 
16
16
  INSTRUMENTATIONS.each do |instrumentation|
17
17
  auto = instrumentation::AutoInstall
18
- if auto.available?
19
- hook_label = instrumentation.name.sub(/::Honeycomb$/, '').downcase.to_sym
20
- after_init(hook_label) do |client|
21
- auto.auto_install!(honeycomb_client: client, logger: @logger)
18
+ hook_label = instrumentation.name.sub(/::Honeycomb$/, '').downcase.to_sym
19
+ after_init(hook_label) do |client, logger|
20
+ if auto.available?(logger: logger)
21
+ auto.auto_install!(honeycomb_client: client, logger: logger)
22
+ else
23
+ logger.debug "Not autoinitialising #{instrumentation.name}" if logger
22
24
  end
23
25
  end
24
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeycomb-beeline
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
  - Sam Stokes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-05-30 00:00:00.000000000 Z
11
+ date: 2018-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libhoney
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 1.6.0
19
+ version: 1.8.1
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 1.6.0
26
+ version: 1.8.1
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: activerecord-honeycomb
29
29
  requirement: !ruby/object:Gem::Requirement