honeycomb-beeline 0.2.0 → 0.3.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 +4 -4
- data/README.md +162 -11
- data/lib/honeycomb/beeline/version.rb +1 -1
- data/lib/honeycomb/client.rb +27 -12
- data/lib/honeycomb/instrumentations.rb +6 -4
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 32263488f94bb0aa40611cb4706d001d62885b4de58f86ecd3ce8ccc0416cbc3
|
4
|
+
data.tar.gz: 53b773d27af7256c876009a824b8855418d80faa460815a5a3c54febe8ac6514
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
##
|
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
|
-
|
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
|
-
|
59
|
-
|
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
|
-
|
62
|
-
|
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).
|
data/lib/honeycomb/client.rb
CHANGED
@@ -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
|
-
|
44
|
-
|
45
|
-
|
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
|
61
|
-
|
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
|
-
|
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
|
-
|
19
|
-
|
20
|
-
|
21
|
-
auto.auto_install!(honeycomb_client: client, 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.
|
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-
|
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.
|
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.
|
26
|
+
version: 1.8.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: activerecord-honeycomb
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|