honeycomb-beeline 0.8.0 → 1.0.0.pre.alpha
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- metadata +48 -113
- data/README.md +0 -36
- data/lib/honeycomb-beeline.rb +0 -13
- data/lib/honeycomb/beeline/version.rb +0 -6
- data/lib/honeycomb/client.rb +0 -180
- data/lib/honeycomb/instrumentations.rb +0 -25
- data/lib/honeycomb/span.rb +0 -295
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 7b8fe19de846820875150addea20fdf579e10245876d110ba705697f34247ee1
|
4
|
+
data.tar.gz: 3ba4a8a9624a211d953d5e54e68c35c961f277c8000fa93ed1d73ab8bee8153b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 76113e85b1549790e59add2780b73c7c32e1eaa542779af3886932253a32e964617053dddd6173366511b17307e55d2462b01bfc8981bd8d933da0b40aee2064
|
7
|
+
data.tar.gz: 2cc961e948616f7dbefc5a4cba143555b243c63728cf0d4297976cc812a26f352fb714a7f94ada3de3ce38bbce3dee3292ec823c2b821c233718d49a354acd2e
|
metadata
CHANGED
@@ -1,73 +1,31 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: honeycomb-beeline
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0.pre.alpha
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
-
|
7
|
+
- Martin Holman
|
8
8
|
autorequire:
|
9
|
-
bindir:
|
9
|
+
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-06-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: libhoney
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: 1.8.1
|
20
|
-
type: :runtime
|
21
|
-
prerelease: false
|
22
|
-
version_requirements: !ruby/object:Gem::Requirement
|
23
|
-
requirements:
|
24
|
-
- - ">="
|
25
|
-
- !ruby/object:Gem::Version
|
26
|
-
version: 1.8.1
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: activerecord-honeycomb
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: 0.4.0
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
17
|
+
- - "~>"
|
39
18
|
- !ruby/object:Gem::Version
|
40
|
-
version:
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: rack-honeycomb
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 0.4.0
|
19
|
+
version: '1.8'
|
48
20
|
type: :runtime
|
49
21
|
prerelease: false
|
50
22
|
version_requirements: !ruby/object:Gem::Requirement
|
51
23
|
requirements:
|
52
|
-
- - "
|
24
|
+
- - "~>"
|
53
25
|
- !ruby/object:Gem::Version
|
54
|
-
version:
|
26
|
+
version: '1.8'
|
55
27
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: 0.3.0
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: 0.3.0
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: activerecord
|
28
|
+
name: appraisal
|
71
29
|
requirement: !ruby/object:Gem::Requirement
|
72
30
|
requirements:
|
73
31
|
- - ">="
|
@@ -95,7 +53,7 @@ dependencies:
|
|
95
53
|
- !ruby/object:Gem::Version
|
96
54
|
version: '0'
|
97
55
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
56
|
+
name: bundler
|
99
57
|
requirement: !ruby/object:Gem::Requirement
|
100
58
|
requirements:
|
101
59
|
- - ">="
|
@@ -109,21 +67,21 @@ dependencies:
|
|
109
67
|
- !ruby/object:Gem::Version
|
110
68
|
version: '0'
|
111
69
|
- !ruby/object:Gem::Dependency
|
112
|
-
name:
|
70
|
+
name: overcommit
|
113
71
|
requirement: !ruby/object:Gem::Requirement
|
114
72
|
requirements:
|
115
|
-
- - "
|
73
|
+
- - "~>"
|
116
74
|
- !ruby/object:Gem::Version
|
117
|
-
version:
|
75
|
+
version: 0.46.0
|
118
76
|
type: :development
|
119
77
|
prerelease: false
|
120
78
|
version_requirements: !ruby/object:Gem::Requirement
|
121
79
|
requirements:
|
122
|
-
- - "
|
80
|
+
- - "~>"
|
123
81
|
- !ruby/object:Gem::Version
|
124
|
-
version:
|
82
|
+
version: 0.46.0
|
125
83
|
- !ruby/object:Gem::Dependency
|
126
|
-
name:
|
84
|
+
name: pry-byebug
|
127
85
|
requirement: !ruby/object:Gem::Requirement
|
128
86
|
requirements:
|
129
87
|
- - ">="
|
@@ -137,21 +95,7 @@ dependencies:
|
|
137
95
|
- !ruby/object:Gem::Version
|
138
96
|
version: '0'
|
139
97
|
- !ruby/object:Gem::Dependency
|
140
|
-
name:
|
141
|
-
requirement: !ruby/object:Gem::Requirement
|
142
|
-
requirements:
|
143
|
-
- - ">="
|
144
|
-
- !ruby/object:Gem::Version
|
145
|
-
version: '0'
|
146
|
-
type: :development
|
147
|
-
prerelease: false
|
148
|
-
version_requirements: !ruby/object:Gem::Requirement
|
149
|
-
requirements:
|
150
|
-
- - ">="
|
151
|
-
- !ruby/object:Gem::Version
|
152
|
-
version: '0'
|
153
|
-
- !ruby/object:Gem::Dependency
|
154
|
-
name: rails
|
98
|
+
name: rake
|
155
99
|
requirement: !ruby/object:Gem::Requirement
|
156
100
|
requirements:
|
157
101
|
- - ">="
|
@@ -165,49 +109,49 @@ dependencies:
|
|
165
109
|
- !ruby/object:Gem::Version
|
166
110
|
version: '0'
|
167
111
|
- !ruby/object:Gem::Dependency
|
168
|
-
name:
|
112
|
+
name: rspec
|
169
113
|
requirement: !ruby/object:Gem::Requirement
|
170
114
|
requirements:
|
171
|
-
- - "
|
115
|
+
- - "~>"
|
172
116
|
- !ruby/object:Gem::Version
|
173
|
-
version: '0'
|
117
|
+
version: '3.0'
|
174
118
|
type: :development
|
175
119
|
prerelease: false
|
176
120
|
version_requirements: !ruby/object:Gem::Requirement
|
177
121
|
requirements:
|
178
|
-
- - "
|
122
|
+
- - "~>"
|
179
123
|
- !ruby/object:Gem::Version
|
180
|
-
version: '0'
|
124
|
+
version: '3.0'
|
181
125
|
- !ruby/object:Gem::Dependency
|
182
|
-
name:
|
126
|
+
name: rubocop
|
183
127
|
requirement: !ruby/object:Gem::Requirement
|
184
128
|
requirements:
|
185
|
-
- - "
|
129
|
+
- - "<"
|
186
130
|
- !ruby/object:Gem::Version
|
187
|
-
version: '0'
|
131
|
+
version: '0.69'
|
188
132
|
type: :development
|
189
133
|
prerelease: false
|
190
134
|
version_requirements: !ruby/object:Gem::Requirement
|
191
135
|
requirements:
|
192
|
-
- - "
|
136
|
+
- - "<"
|
193
137
|
- !ruby/object:Gem::Version
|
194
|
-
version: '0'
|
138
|
+
version: '0.69'
|
195
139
|
- !ruby/object:Gem::Dependency
|
196
|
-
name:
|
140
|
+
name: rubocop-performance
|
197
141
|
requirement: !ruby/object:Gem::Requirement
|
198
142
|
requirements:
|
199
|
-
- - "
|
143
|
+
- - "<"
|
200
144
|
- !ruby/object:Gem::Version
|
201
|
-
version:
|
145
|
+
version: 1.3.0
|
202
146
|
type: :development
|
203
147
|
prerelease: false
|
204
148
|
version_requirements: !ruby/object:Gem::Requirement
|
205
149
|
requirements:
|
206
|
-
- - "
|
150
|
+
- - "<"
|
207
151
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
152
|
+
version: 1.3.0
|
209
153
|
- !ruby/object:Gem::Dependency
|
210
|
-
name:
|
154
|
+
name: simplecov
|
211
155
|
requirement: !ruby/object:Gem::Requirement
|
212
156
|
requirements:
|
213
157
|
- - ">="
|
@@ -221,21 +165,21 @@ dependencies:
|
|
221
165
|
- !ruby/object:Gem::Version
|
222
166
|
version: '0'
|
223
167
|
- !ruby/object:Gem::Dependency
|
224
|
-
name:
|
168
|
+
name: simplecov-console
|
225
169
|
requirement: !ruby/object:Gem::Requirement
|
226
170
|
requirements:
|
227
171
|
- - ">="
|
228
172
|
- !ruby/object:Gem::Version
|
229
|
-
version: 0
|
173
|
+
version: '0'
|
230
174
|
type: :development
|
231
175
|
prerelease: false
|
232
176
|
version_requirements: !ruby/object:Gem::Requirement
|
233
177
|
requirements:
|
234
178
|
- - ">="
|
235
179
|
- !ruby/object:Gem::Version
|
236
|
-
version: 0
|
180
|
+
version: '0'
|
237
181
|
- !ruby/object:Gem::Dependency
|
238
|
-
name:
|
182
|
+
name: webmock
|
239
183
|
requirement: !ruby/object:Gem::Requirement
|
240
184
|
requirements:
|
241
185
|
- - ">="
|
@@ -248,26 +192,18 @@ dependencies:
|
|
248
192
|
- - ">="
|
249
193
|
- !ruby/object:Gem::Version
|
250
194
|
version: '0'
|
251
|
-
description:
|
252
|
-
The Honeycomb Beeline for Ruby is the fastest path to observability for your
|
253
|
-
Ruby apps. It understands the common packages you use and automatically
|
254
|
-
instruments them to send useful events to Honeycomb.
|
195
|
+
description:
|
255
196
|
email:
|
256
|
-
-
|
197
|
+
- martin@honeycomb.io
|
257
198
|
executables: []
|
258
199
|
extensions: []
|
259
200
|
extra_rdoc_files: []
|
260
|
-
files:
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
- lib/honeycomb/span.rb
|
267
|
-
homepage: https://github.com/honeycombio/beeline-ruby
|
268
|
-
licenses:
|
269
|
-
- Apache-2.0
|
270
|
-
metadata: {}
|
201
|
+
files: []
|
202
|
+
homepage: https://honeycomb.io
|
203
|
+
licenses: []
|
204
|
+
metadata:
|
205
|
+
homepage_uri: https://honeycomb.io
|
206
|
+
source_code_uri: https://github.com/honeycombio/beeline-ruby
|
271
207
|
post_install_message:
|
272
208
|
rdoc_options: []
|
273
209
|
require_paths:
|
@@ -279,12 +215,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
279
215
|
version: 2.2.0
|
280
216
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
281
217
|
requirements:
|
282
|
-
- - "
|
218
|
+
- - ">"
|
283
219
|
- !ruby/object:Gem::Version
|
284
|
-
version:
|
220
|
+
version: 1.3.1
|
285
221
|
requirements: []
|
286
|
-
|
287
|
-
rubygems_version: 2.6.14.4
|
222
|
+
rubygems_version: 3.0.4
|
288
223
|
signing_key:
|
289
224
|
specification_version: 4
|
290
225
|
summary: Instrument your Ruby apps with Honeycomb
|
data/README.md
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
# Honeycomb Beeline for Ruby
|
2
|
-
|
3
|
-
[![Build Status](https://travis-ci.org/honeycombio/beeline-ruby.svg?branch=master)](https://travis-ci.org/honeycombio/beeline-ruby)
|
4
|
-
[![Gem Version](https://badge.fury.io/rb/honeycomb-beeline.svg)](https://badge.fury.io/rb/honeycomb-beeline)
|
5
|
-
|
6
|
-
This package makes it easy to instrument your Ruby web app to send useful events to [Honeycomb](https://www.honeycomb.io), a service for debugging your software in production.
|
7
|
-
- [Usage and Examples](https://docs.honeycomb.io/getting-data-in/beelines/ruby-beeline/)
|
8
|
-
|
9
|
-
Sign up for a [Honeycomb
|
10
|
-
trial](https://ui.honeycomb.io/signup) to obtain an API key before starting.
|
11
|
-
|
12
|
-
## Compatible with
|
13
|
-
|
14
|
-
Requires Ruby version 2.2 or later
|
15
|
-
|
16
|
-
Built in instrumentation for:
|
17
|
-
|
18
|
-
- Active Record 4 or later
|
19
|
-
- Rails 4 or later
|
20
|
-
- Faraday 0.8 or later
|
21
|
-
- Sequel
|
22
|
-
- Rack 1 or greater
|
23
|
-
|
24
|
-
## Get in touch
|
25
|
-
|
26
|
-
Please reach out to [support@honeycomb.io](mailto:support@honeycomb.io) or ping
|
27
|
-
us with the chat bubble on [our website](https://www.honeycomb.io) for any
|
28
|
-
assistance. We also welcome [bug reports](https://github.com/honeycombio/beeline-ruby/issues).
|
29
|
-
|
30
|
-
## Contributions
|
31
|
-
|
32
|
-
Features, bug fixes and other changes to `beeline-ruby` are gladly accepted. Please
|
33
|
-
open issues or a pull request with your change. Remember to add your name to the
|
34
|
-
CONTRIBUTORS file!
|
35
|
-
|
36
|
-
All contributions will be released under the Apache License 2.0.
|
data/lib/honeycomb-beeline.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# Main entrypoint for the 'honeycomb-beeline' gem.
|
2
|
-
|
3
|
-
require 'libhoney'
|
4
|
-
|
5
|
-
# Namespace for the Honeycomb Beeline.
|
6
|
-
#
|
7
|
-
# Call {.init} to initialize the Honeycomb Beeline at app startup.
|
8
|
-
module Honeycomb
|
9
|
-
end
|
10
|
-
|
11
|
-
require 'honeycomb/client'
|
12
|
-
require 'honeycomb/instrumentations'
|
13
|
-
require 'honeycomb/span'
|
data/lib/honeycomb/client.rb
DELETED
@@ -1,180 +0,0 @@
|
|
1
|
-
require 'honeycomb/beeline/version'
|
2
|
-
|
3
|
-
require 'libhoney'
|
4
|
-
|
5
|
-
require 'logger'
|
6
|
-
require 'socket'
|
7
|
-
|
8
|
-
module Honeycomb
|
9
|
-
USER_AGENT_SUFFIX = "#{Beeline::GEM_NAME}/#{Beeline::VERSION}"
|
10
|
-
|
11
|
-
class << self
|
12
|
-
attr_reader :client
|
13
|
-
attr_reader :logger
|
14
|
-
attr_reader :service_name
|
15
|
-
|
16
|
-
# Initialize the Honeycomb Beeline. You should call this only once, as
|
17
|
-
# early as possible in your app's startup process, to automatically
|
18
|
-
# instrument your app and prepare to send events.
|
19
|
-
#
|
20
|
-
# @example Providing config in code
|
21
|
-
# Honeycomb.init(
|
22
|
-
# writekey: '0123face4567cafe8901beef2345feed',
|
23
|
-
# dataset: 'myapp-development',
|
24
|
-
# service_name: 'myapp'
|
25
|
-
# )
|
26
|
-
# @example Providing config via environment variables
|
27
|
-
# # Assumes environment variables e.g.
|
28
|
-
# # HONEYCOMB_WRITEKEY=0123face4567cafe8901beef2345feed
|
29
|
-
# # HONEYCOMB_DATASET=myapp-development
|
30
|
-
# # HONEYCOMB_SERVICE=myapp
|
31
|
-
#
|
32
|
-
# Honeycomb.init
|
33
|
-
#
|
34
|
-
# @param writekey [String] (required) the Honeycomb API key (aka "write
|
35
|
-
# key") - get yours from your {https://ui.honeycomb.io/account Account
|
36
|
-
# Page}. Can also be specified via the HONEYCOMB_WRITEKEY environment
|
37
|
-
# variable.
|
38
|
-
# @param dataset [String] (required) the name of the Honeycomb
|
39
|
-
# {https://docs.honeycomb.io/getting-data-in/datasets/best-practices/
|
40
|
-
# dataset} your app should send events to. Can also be specified via the
|
41
|
-
# HONEYCOMB_DATASET environment variable.
|
42
|
-
# @param service_name [String] the name of your app, included in all events
|
43
|
-
# your app will send. Defaults to the dataset name if not specified. Can
|
44
|
-
# also be specified via the HONEYCOMB_SERVICE environment variable.
|
45
|
-
# @param debug [Boolean] if true, your app will not send any events to
|
46
|
-
# Honeycomb, but will instead print them to your app's standard error.
|
47
|
-
# It will also log diagnostic messages to standard error.
|
48
|
-
# @param logger [Logger] provide a logger to receive diagnostic messages,
|
49
|
-
# e.g. to override the default logging device or verbosity. By default
|
50
|
-
# warnings and above will be logged to standard error; under normal
|
51
|
-
# operation nothing will be logged.
|
52
|
-
def init(
|
53
|
-
writekey: ENV['HONEYCOMB_WRITEKEY'],
|
54
|
-
dataset: ENV['HONEYCOMB_DATASET'],
|
55
|
-
service_name: ENV['HONEYCOMB_SERVICE'] || dataset,
|
56
|
-
without: [],
|
57
|
-
debug: ENV.key?('HONEYCOMB_DEBUG'),
|
58
|
-
logger: nil,
|
59
|
-
**options
|
60
|
-
)
|
61
|
-
reset
|
62
|
-
|
63
|
-
@without = without
|
64
|
-
@service_name = service_name
|
65
|
-
@logger = logger || Logger.new($stderr).tap {|l| l.level = Logger::WARN }
|
66
|
-
@debug = debug
|
67
|
-
if debug
|
68
|
-
@logger ||= Logger.new($stderr)
|
69
|
-
end
|
70
|
-
|
71
|
-
options = options.merge(writekey: writekey, dataset: dataset)
|
72
|
-
@client = new_client(options)
|
73
|
-
|
74
|
-
after_init_hooks.each do |label, block|
|
75
|
-
debug "Running hook '#{label}' after Honeycomb.init"
|
76
|
-
run_hook(label, block)
|
77
|
-
end
|
78
|
-
|
79
|
-
@initialized = true
|
80
|
-
end
|
81
|
-
|
82
|
-
# Call at app shutdown to ensure all pending events have been sent to
|
83
|
-
# Honeycomb.
|
84
|
-
def shutdown
|
85
|
-
if defined?(@client) && @client
|
86
|
-
@client.close
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
# Reset the Beeline to a pristine state, ready to be `.init`ed again.
|
91
|
-
# Intended for testing purposes only.
|
92
|
-
#
|
93
|
-
# @api private
|
94
|
-
def reset
|
95
|
-
# TODO encapsulate all this into a Beeline object so we don't need
|
96
|
-
# explicit cleanup
|
97
|
-
|
98
|
-
shutdown
|
99
|
-
|
100
|
-
@logger = nil
|
101
|
-
@without = nil
|
102
|
-
@service_name = nil
|
103
|
-
@debug = nil
|
104
|
-
@client = nil
|
105
|
-
@initialized = false
|
106
|
-
end
|
107
|
-
|
108
|
-
private
|
109
|
-
def debug(msg)
|
110
|
-
logger.debug msg if logger
|
111
|
-
end
|
112
|
-
def info(msg)
|
113
|
-
logger.info msg if logger
|
114
|
-
end
|
115
|
-
def warn(msg)
|
116
|
-
logger.warn msg if logger
|
117
|
-
end
|
118
|
-
|
119
|
-
def after_init_hooks
|
120
|
-
@after_init_hooks ||= []
|
121
|
-
end
|
122
|
-
|
123
|
-
def new_client(options)
|
124
|
-
client = options.delete :client
|
125
|
-
|
126
|
-
options = {user_agent_addition: USER_AGENT_SUFFIX}.merge(options)
|
127
|
-
if @debug
|
128
|
-
raise ArgumentError, "can't specify both client and debug options", caller if client
|
129
|
-
info 'logging events to standard error instead of sending to Honeycomb'
|
130
|
-
client = Libhoney::LogClient.new(verbose: true, **options)
|
131
|
-
else
|
132
|
-
client ||= if options[:writekey] && options[:dataset]
|
133
|
-
Libhoney::Client.new(options)
|
134
|
-
else
|
135
|
-
warn "#{self.name}: no #{options[:writekey] ? 'dataset' : 'writekey'} configured, disabling sending events"
|
136
|
-
Libhoney::NullClient.new(options)
|
137
|
-
end
|
138
|
-
end
|
139
|
-
client.add_field 'meta.beeline_version', Beeline::VERSION
|
140
|
-
client.add_field 'meta.local_hostname', Socket.gethostname rescue nil
|
141
|
-
client.add_field 'service_name', @service_name
|
142
|
-
client
|
143
|
-
end
|
144
|
-
|
145
|
-
def after_init(label, &block)
|
146
|
-
raise ArgumentError unless block_given?
|
147
|
-
|
148
|
-
hook = if block.arity == 0
|
149
|
-
->(_, _) { block.call }
|
150
|
-
elsif block.arity == 1
|
151
|
-
->(client, _) { block.call client }
|
152
|
-
elsif block.arity > 2
|
153
|
-
raise ArgumentError, 'Honeycomb.after_init block should take 2 arguments'
|
154
|
-
else
|
155
|
-
block
|
156
|
-
end
|
157
|
-
|
158
|
-
if defined?(@initialized)
|
159
|
-
debug "Running hook '#{label}' as Honeycomb already initialized"
|
160
|
-
run_hook(label, hook)
|
161
|
-
else
|
162
|
-
after_init_hooks << [label, hook]
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def run_hook(label, block)
|
167
|
-
if @without.include?(label)
|
168
|
-
debug "Skipping hook '#{label}' due to opt-out"
|
169
|
-
else
|
170
|
-
block.call @client, @logger
|
171
|
-
end
|
172
|
-
rescue => e
|
173
|
-
warn "Honeycomb.init hook '#{label}' raised #{e.class}: #{e}"
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
after_init :log do |_, logger|
|
178
|
-
logger.info "Honeycomb inited" if logger
|
179
|
-
end
|
180
|
-
end
|
@@ -1,25 +0,0 @@
|
|
1
|
-
require 'honeycomb/client'
|
2
|
-
|
3
|
-
require 'activerecord-honeycomb/auto_install'
|
4
|
-
require 'faraday-honeycomb/auto_install'
|
5
|
-
require 'rack-honeycomb/auto_install'
|
6
|
-
|
7
|
-
module Honeycomb
|
8
|
-
INSTRUMENTATIONS = [
|
9
|
-
ActiveRecord::Honeycomb,
|
10
|
-
Faraday::Honeycomb,
|
11
|
-
Rack::Honeycomb,
|
12
|
-
].freeze
|
13
|
-
|
14
|
-
INSTRUMENTATIONS.each do |instrumentation|
|
15
|
-
auto = instrumentation::AutoInstall
|
16
|
-
hook_label = instrumentation.name.sub(/::Honeycomb$/, '').downcase.to_sym
|
17
|
-
after_init(hook_label) do |client, logger|
|
18
|
-
if auto.available?(logger: logger)
|
19
|
-
auto.auto_install!(honeycomb_client: client, logger: logger)
|
20
|
-
else
|
21
|
-
logger.debug "Not autoinitialising #{instrumentation.name}" if logger
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/honeycomb/span.rb
DELETED
@@ -1,295 +0,0 @@
|
|
1
|
-
require 'base64'
|
2
|
-
require 'json'
|
3
|
-
require 'securerandom'
|
4
|
-
|
5
|
-
module Honeycomb
|
6
|
-
class << self
|
7
|
-
# Start a new trace. Calling {.span} will automatically start a new trace if
|
8
|
-
# one is not already active, so you do not need to call this explicitly
|
9
|
-
# unless you want to specify the trace id or parent span id (e.g. to
|
10
|
-
# propagate a trace id received from upstream).
|
11
|
-
def trace(trace_id: nil, parent_span_id: nil, context: {}, **extra_context)
|
12
|
-
context = context.merge(extra_context)
|
13
|
-
|
14
|
-
with_trace trace_id: trace_id, parent_span_id: parent_span_id, context: context do
|
15
|
-
yield
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
# Continue a trace from a serialized trace context, e.g. propagated from
|
20
|
-
# another process.
|
21
|
-
def trace_from_encoded_context(encoded_context = nil, additional_context: {})
|
22
|
-
trace_context = decode_trace_context(encoded_context) || {}
|
23
|
-
trace_id = trace_context[:trace_id]
|
24
|
-
parent_span_id = trace_context[:parent_span_id]
|
25
|
-
context = trace_context[:context] || {}
|
26
|
-
|
27
|
-
trace(trace_id: trace_id, parent_span_id: parent_span_id, context: context.merge(additional_context)) do
|
28
|
-
yield
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
# Start a new span, and send it at the end of the supplied code block. This
|
33
|
-
# will start a new trace if one is not already active.
|
34
|
-
def span(name = nil, type: 'app', fields: {}, **extra_fields)
|
35
|
-
fields = fields.merge(extra_fields)
|
36
|
-
|
37
|
-
start = nil
|
38
|
-
|
39
|
-
event = client.event
|
40
|
-
span_for_existing_event(event, name: name, type: type) do |span_id, trace_id|
|
41
|
-
fields.each do |field, value|
|
42
|
-
event.add_field "app.#{field}", value
|
43
|
-
end
|
44
|
-
|
45
|
-
start = Time.now
|
46
|
-
|
47
|
-
yield span_id, trace_id, event
|
48
|
-
end
|
49
|
-
rescue Exception => e
|
50
|
-
if event
|
51
|
-
# TODO what should the prefix be?
|
52
|
-
event.add_field 'app.error', e.class.name
|
53
|
-
event.add_field 'app.error_detail', e.message
|
54
|
-
end
|
55
|
-
raise
|
56
|
-
ensure
|
57
|
-
if start && event
|
58
|
-
finish = Time.now
|
59
|
-
duration = finish - start
|
60
|
-
event.add_field 'duration_ms', duration * 1000
|
61
|
-
event.send
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
# Start a new span, and annotate an existing {Libhoney::Event} with its
|
66
|
-
# tracing fields. Most users should call {.span} instead, since it has
|
67
|
-
# simpler semantics (e.g. it will time the execution of the code block for
|
68
|
-
# you, record any exceptions that were thrown, and send the event at the end
|
69
|
-
# of the code block). This method is mainly useful if you are writing a
|
70
|
-
# library instrumentation which needs to also work independently of the
|
71
|
-
# Beeline, and which therefore needs to implement those semantics itself; or
|
72
|
-
# which needs custom error handling, e.g. adding custom fields in case of
|
73
|
-
# error.
|
74
|
-
def span_for_existing_event(event, name:, type:)
|
75
|
-
with_trace do |trace_id, context|
|
76
|
-
with_span do |parent_span_id, span_id|
|
77
|
-
event.add_field 'trace.trace_id', trace_id
|
78
|
-
event.add_field 'trace.parent_id', parent_span_id if parent_span_id
|
79
|
-
event.add_field 'trace.span_id', span_id
|
80
|
-
event.add_field 'name', name if name
|
81
|
-
event.add_field 'type', type
|
82
|
-
|
83
|
-
context.each do |field, value|
|
84
|
-
event.add_field "app.#{field}", value
|
85
|
-
end
|
86
|
-
|
87
|
-
yield span_id, trace_id
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
# Add a trace field, which will get added to all spans sent after this call.
|
93
|
-
def add_trace_field(name, value)
|
94
|
-
self.active_trace_context[name] = value
|
95
|
-
# TODO right now this will only add the field to all spans *started* after
|
96
|
-
# this call, which unfortunately excludes the actual active span when the
|
97
|
-
# call was made. One way to fix this is to change .span_for_existing_event
|
98
|
-
# to add fields from .active_trace_context _after_ the yield (in a
|
99
|
-
# begin/ensure block) instead of before.
|
100
|
-
end
|
101
|
-
|
102
|
-
def decode_trace_context(encoded_context)
|
103
|
-
return nil unless encoded_context
|
104
|
-
version, payload = encoded_context.split(';', 2)
|
105
|
-
case version
|
106
|
-
when '1'
|
107
|
-
decode_payload_v1(payload)
|
108
|
-
else
|
109
|
-
warn "#{self}.decode_trace_context: unrecognized trace context version #{version.inspect}"
|
110
|
-
nil
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def encode_trace_context_v1(trace_id, parent_span_id, context)
|
115
|
-
version = 1
|
116
|
-
|
117
|
-
encoded_payload = encode_payload_v1(
|
118
|
-
trace_id: trace_id,
|
119
|
-
parent_id: parent_span_id,
|
120
|
-
context: context,
|
121
|
-
)
|
122
|
-
|
123
|
-
"#{version};#{encoded_payload}"
|
124
|
-
end
|
125
|
-
alias encode_trace_context encode_trace_context_v1
|
126
|
-
|
127
|
-
def active_trace_id
|
128
|
-
Thread.current[:honeycomb_trace_id]
|
129
|
-
end
|
130
|
-
def active_trace_id=(trace_id)
|
131
|
-
Thread.current[:honeycomb_trace_id] = trace_id
|
132
|
-
end
|
133
|
-
|
134
|
-
def active_parent_span_id
|
135
|
-
Thread.current[:honeycomb_parent_span_id]
|
136
|
-
end
|
137
|
-
def active_parent_span_id=(parent_span_id)
|
138
|
-
Thread.current[:honeycomb_parent_span_id] = parent_span_id
|
139
|
-
end
|
140
|
-
|
141
|
-
def active_trace_context
|
142
|
-
Thread.current[:honeycomb_trace_context]
|
143
|
-
end
|
144
|
-
def active_trace_context=(trace_context)
|
145
|
-
Thread.current[:honeycomb_trace_context] = trace_context
|
146
|
-
end
|
147
|
-
|
148
|
-
private
|
149
|
-
def with_trace(trace_id: nil, parent_span_id: nil, context: nil)
|
150
|
-
if self.active_trace_id
|
151
|
-
if trace_id
|
152
|
-
warn "#{self}.with_trace called while another trace is already active; ignoring supplied trace_id and preserving existing one"
|
153
|
-
end
|
154
|
-
yield self.active_trace_id, self.active_trace_context
|
155
|
-
else
|
156
|
-
begin
|
157
|
-
trace_id, context = start_trace!(trace_id: trace_id, parent_span_id: parent_span_id, context: context)
|
158
|
-
|
159
|
-
yield trace_id, context
|
160
|
-
ensure
|
161
|
-
finish_trace!
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
|
-
def start_trace!(trace_id: nil, parent_span_id: nil, context: nil)
|
167
|
-
raise "#{self}.start_trace! called while another trace is already active" if self.active_trace_id
|
168
|
-
|
169
|
-
trace_id ||= SecureRandom.uuid
|
170
|
-
self.active_trace_id = trace_id
|
171
|
-
|
172
|
-
self.active_parent_span_id = parent_span_id if parent_span_id
|
173
|
-
|
174
|
-
context ||= {}
|
175
|
-
self.active_trace_context = context
|
176
|
-
|
177
|
-
[trace_id, context]
|
178
|
-
end
|
179
|
-
|
180
|
-
def finish_trace!
|
181
|
-
self.active_trace_id = nil
|
182
|
-
self.active_parent_span_id = nil
|
183
|
-
self.active_trace_context = nil
|
184
|
-
end
|
185
|
-
|
186
|
-
def with_span
|
187
|
-
parent_span_id, span_id = start_span!
|
188
|
-
|
189
|
-
yield parent_span_id, span_id
|
190
|
-
ensure
|
191
|
-
finish_span!(parent_span_id)
|
192
|
-
end
|
193
|
-
|
194
|
-
def start_span!
|
195
|
-
span_id = SecureRandom.uuid
|
196
|
-
|
197
|
-
parent_span_id = self.active_parent_span_id
|
198
|
-
self.active_parent_span_id = span_id
|
199
|
-
|
200
|
-
return parent_span_id, span_id
|
201
|
-
end
|
202
|
-
|
203
|
-
def finish_span!(parent_span_id)
|
204
|
-
self.active_parent_span_id = parent_span_id
|
205
|
-
end
|
206
|
-
|
207
|
-
def decode_payload_v1(encoded_payload)
|
208
|
-
trace_id, parent_span_id, context = nil
|
209
|
-
|
210
|
-
encoded_payload.split(',').each do |entry|
|
211
|
-
k, v = entry.split('=', 2)
|
212
|
-
case k
|
213
|
-
when 'trace_id'
|
214
|
-
trace_id = v
|
215
|
-
when 'parent_id'
|
216
|
-
parent_span_id = v
|
217
|
-
when 'context'
|
218
|
-
context = decode_payload_context_v1(v)
|
219
|
-
else
|
220
|
-
debug "#{self}.decode_payload_v1: unrecognized payload key #{k.inspect}"
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
if trace_id.nil?
|
225
|
-
warn "#{self}.decode_payload_v1: no trace_id in context"
|
226
|
-
return nil
|
227
|
-
elsif parent_span_id.nil?
|
228
|
-
warn "#{self}.decode_payload_v1: no parent_id in context"
|
229
|
-
return nil
|
230
|
-
end
|
231
|
-
|
232
|
-
payload = {
|
233
|
-
trace_id: trace_id,
|
234
|
-
parent_span_id: parent_span_id,
|
235
|
-
}
|
236
|
-
payload[:context] = context if context
|
237
|
-
payload
|
238
|
-
rescue StandardError => e
|
239
|
-
warn "#{self}.decode_payload_v1: encountered #{e.class} decoding payload: #{e}"
|
240
|
-
nil
|
241
|
-
end
|
242
|
-
|
243
|
-
def decode_payload_context_v1(encoded_payload_context)
|
244
|
-
return {} if encoded_payload_context.empty?
|
245
|
-
json = Base64.decode64(encoded_payload_context)
|
246
|
-
JSON.parse(json)
|
247
|
-
end
|
248
|
-
|
249
|
-
def encode_payload_v1(payload_parts)
|
250
|
-
payload_parts.map do |k, v|
|
251
|
-
encoded_part = encode_payload_part_v1(k, v)
|
252
|
-
encoded_part ? "#{k}=#{encoded_part}" : nil
|
253
|
-
end
|
254
|
-
.compact # strip out parts that failed to encode
|
255
|
-
.join(',')
|
256
|
-
end
|
257
|
-
|
258
|
-
def encode_payload_part_v1(param, value)
|
259
|
-
case param
|
260
|
-
when :trace_id, :parent_id
|
261
|
-
encode_payload_id_v1(value)
|
262
|
-
when :context
|
263
|
-
encode_payload_context_v1(value)
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def encode_payload_id_v1(id)
|
268
|
-
case id
|
269
|
-
when nil
|
270
|
-
nil
|
271
|
-
when String, Symbol
|
272
|
-
id = id.to_s
|
273
|
-
if id.include? ','
|
274
|
-
raise ArgumentError, "can't include ','"
|
275
|
-
end
|
276
|
-
id
|
277
|
-
when Numeric
|
278
|
-
id.to_s
|
279
|
-
else
|
280
|
-
raise ArgumentError, "invalid type #{id.class}"
|
281
|
-
end
|
282
|
-
end
|
283
|
-
|
284
|
-
def encode_payload_context_v1(context)
|
285
|
-
case context
|
286
|
-
when nil
|
287
|
-
nil
|
288
|
-
when Hash
|
289
|
-
Base64.urlsafe_encode64(JSON.generate(context)).strip
|
290
|
-
else
|
291
|
-
raise ArgumentError, "invalid type #{context.class}"
|
292
|
-
end
|
293
|
-
end
|
294
|
-
end
|
295
|
-
end
|