honeycomb-beeline 0.5.0 → 0.6.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: fc4528a9aaab86b940cc602a90134618ff588f88d25d8eaa8408edcc294ea987
4
- data.tar.gz: f7fb9cafa295258ad9e96fe3116e8e81f8f4a27a3affa29db9eec63207cbf6a9
3
+ metadata.gz: 0e5338862ac2eed88b9a4c9712bf47d63652531c0a6c9c06d8e2e4f0f62c2650
4
+ data.tar.gz: 7e70234ac75d0361578905460c92625744f70fae73a050db386ab5b0614870e7
5
5
  SHA512:
6
- metadata.gz: '08e93b50154976fc28a3408df22a4b4e347d2236cf18673a4adef9092a4d739ff083772260e96a1d058efa6674b9afc24cc2b7d7c6156078dfd7d2847edec2c4'
7
- data.tar.gz: 78287f73733f6cce17d28fb5c58afdd8e99a4bcf8c56cc7af01c97b03a3e8aab7d7947e68e9ee6afef201fb38c0541e08ed34c912994907a09a6bfc3d9a1c27c
6
+ metadata.gz: 3730b7e2add547932ce15ed3ec4a18ab52a65c20c65542547fa8c8a6a15e19aa0a2aff498d85b8237a5603099cbca3824e5dc3e4a9ba9d260dc26ec0cf3f2d62
7
+ data.tar.gz: ac42934a9679810c693d673d88aa656ca36f7c17cbccc66cca1cd4cadb3ce0969f50926efdb4a4716913a728235b6368bef20264ebc9d7aa374ce55cdb618f8f
data/README.md CHANGED
@@ -6,217 +6,31 @@
6
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
7
  - [Usage and Examples](https://docs.honeycomb.io/getting-data-in/beelines/ruby-beeline/)
8
8
 
9
- Requires Ruby 2.2 or later. Sign up for a [Honeycomb
9
+ Sign up for a [Honeycomb
10
10
  trial](https://ui.honeycomb.io/signup) to obtain an API key before starting.
11
11
 
12
- ## Installation
12
+ ## Compatible with
13
13
 
14
- Add `honeycomb-beeline` to your Gemfile:
14
+ Requires Ruby version 2.2 or later
15
15
 
16
- ```ruby
17
- gem 'honeycomb-beeline'
18
- ```
19
- Now run `bundle install` to install the gem.
16
+ Built in instrumentation for:
20
17
 
21
- ## Setup
18
+ - Active Record 4 or later
19
+ - Rails 4 or later
20
+ - Faraday 0.8 or later
21
+ - Sequel
22
+ - Rack 1 or greater
22
23
 
23
- In your app's startup script - e.g. config.ru or app.rb - add the following
24
- code:
24
+ ## Get in touch
25
25
 
26
- ```ruby
27
- require 'honeycomb-beeline'
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).
28
29
 
29
- Honeycomb.init # pulls configuration from the environment - see below
30
- ```
30
+ ## Contributions
31
31
 
32
- ## Configuration
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!
33
35
 
34
- You'll need to configure your Honeycomb API key so that your app can
35
- identify itself to Honeycomb. You can find your API key on [your Account
36
- page](https://ui.honeycomb.io/account).
37
-
38
- You'll also need to configure the name of a dataset in your Honeycomb account to
39
- send events to. The name of your app is a good choice.
40
-
41
- You can specify the configuration either via environment variables, or by
42
- passing arguments to `Honeycomb.init`:
43
-
44
- ### Configuration via environment variables
45
-
46
- * `HONEYCOMB_WRITEKEY` - specifies the API key (aka "write key")
47
- * `HONEYCOMB_DATASET` - specifies the dataset
48
- * `HONEYCOMB_SERVICE` - specifies the name of your app (defaults to the dataset
49
- name)
50
-
51
- ### Configuration via code
52
-
53
- ```ruby
54
- Honeycomb.init(
55
- writekey: '<MY HONEYCOMB API KEY>',
56
- dataset: 'my-app',
57
- service_name: 'my-app'
58
- )
59
- ```
60
-
61
- Note that Honeycomb API keys have the ability to create and delete data, and
62
- should be managed in the same way as your other application secrets. For example
63
- you might prefer to configure production API keys via environment variables,
64
- rather than checking them into version control.
65
-
66
- ## Example questions
67
-
68
- Now your app is instrumented and sending events, try using Honeycomb to ask
69
- these questions:
70
-
71
- * Which of my app's routes are the slowest?
72
- ```
73
- BREAKDOWN: request.path
74
- CALCULATE: P99(duration_ms)
75
- FILTER: type == http_server
76
- ORDER BY: P99(duration_ms) DESC
77
- ```
78
- * Where's my app spending the most time?
79
- ```
80
- BREAKDOWN: type
81
- CALCULATE: SUM(duration_ms)
82
- ORDER BY: SUM(duration_ms) DESC
83
- ```
84
- * Which users are using the endpoint that I'd like to deprecate? First add a
85
- [custom field](#adding-additional-context) `user.email`, then try:
86
- ```
87
- BREAKDOWN: app.user.email
88
- CALCULATE: COUNT
89
- FILTER: request.path == /my/deprecated/endpoint
90
- ```
91
-
92
- ## Example event
93
-
94
- Here is an example of an `http_server` event (recording that your web app
95
- processed an incoming HTTP request) emitted by the Beeline:
96
-
97
- ```json
98
- {
99
- "meta.beeline_version": "0.2.0",
100
- "meta.local_hostname": "killerbee",
101
- "service_name": "my-test-app",
102
- "meta.package": "rack",
103
- "meta.package_version": "1.3",
104
- "type": "http_server",
105
- "name": "GET /dashboard",
106
- "request.method": "GET",
107
- "request.path": "/dashboard",
108
- "request.protocol": "https",
109
- "request.http_version": "HTTP/1.1",
110
- "request.host": "my-test-app.example.com",
111
- "request.remote_addr": "172.217.1.238",
112
- "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",
113
- "trace.trace_id": "b694512a-833f-4b35-be5f-6c742ba18e12",
114
- "trace.span_id": "c35cc326-ed90-4881-a4a8-68526d252f2e",
115
- "response.status_code": 200,
116
- "duration_ms": 303.057396
117
- }
118
- ```
119
-
120
- ## Adding additional context
121
-
122
- The Beeline will automatically instrument your incoming HTTP requests, database
123
- queries and outbound HTTP requests to send events to Honeycomb. However, it can
124
- be very helpful to extend these events with additional context specific to your
125
- app. You can add your own fields by calling `Rack::Honeycomb.add_field`. For
126
- example, this snippet shows how to associate the currently logged-in user with
127
- each `http_server` event:
128
-
129
- ```ruby
130
- get '/hello' do
131
- user = authenticate_user()
132
-
133
- # this will add a custom field 'app.user.email' to the http_server event
134
- Rack::Honeycomb.add_field(env, 'user.email', user.email)
135
-
136
- "Hello, #{user.name}!"
137
- end
138
- ```
139
-
140
- ## Instrumented packages
141
-
142
- The Beeline will automatically send the following events if you are using one of
143
- the listed packages:
144
-
145
- ### `http_server` (incoming HTTP requests)
146
-
147
- * [Sinatra](http://sinatrarb.com) - via [rack-honeycomb](https://github.com/honeycombio/rack-honeycomb)
148
- * Any other [Rack](https://rack.github.io)-based web app - via [rack-honeycomb](https://github.com/honeycombio/rack-honeycomb) (requires manually adding the middleware)
149
-
150
- ### `db` (database queries)
151
-
152
- * [ActiveRecord](https://rubygems.org/gems/activerecord) - via
153
- [activerecord-honeycomb](https://github.com/honeycombio/activerecord-honeycomb)
154
- * [Sequel](https://sequel.jeremyevans.net/) - via
155
- [sequel-honeycomb](https://github.com/honeycombio/sequel-honeycomb)
156
-
157
- ### `http_client` (outbound HTTP requests)
158
-
159
- * [Faraday](https://github.com/lostisland/faraday) - via
160
- [faraday-honeycomb](https://github.com/honeycombio/faraday-honeycomb)
161
-
162
- ## Known limitations
163
-
164
- * The Beeline will try to autodetect your web framework and automatically
165
- install its middleware. Currently this only works for Sinatra apps, and
166
- also fails in some more exotic configurations of Sinatra. If you find you
167
- aren't seeing any events for processing web requests, you can install the
168
- [middleware](https://www.rubydoc.info/gems/rack-honeycomb) manually: e.g.
169
- `use Rack::Honeycomb::Middleware`.
170
- * Rails apps should work after installing the middleware as above, but are
171
- currently better supported by our dedicated [Rails
172
- integration](https://github.com/honeycombio/honeycomb-rails).
173
- * Alternative concurrency models such as EventMachine or Celluloid are not
174
- currently supported.
175
-
176
- If support for one of these scenarios is important to you, please [let us
177
- know](#get-in-touch)!
178
-
179
- ## Troubleshooting
180
-
181
- If you've setup the Beeline as above but you aren't seeing data for your app in
182
- Honeycomb, or you're seeing errors on startup, here are a few things to try:
183
-
184
- ### Debug mode
185
-
186
- To verify the Beeline is working as expected, try running it in debug mode:
187
-
188
- ```ruby
189
- Honeycomb.init(debug: true)
190
- ```
191
-
192
- Alternatively, you can also enable debug mode with no code changes by setting
193
- `HONEYCOMB_DEBUG=true` in your environment.
194
-
195
- In debug mode, the Beeline will not send any events to Honeycomb, but will
196
- instead print them to your app's standard error. It will also log startup
197
- messages to standard error.
198
-
199
- ### Logging
200
-
201
- By default the Beeline will log errors but otherwise keep quiet. To see more
202
- detail about what it's doing, you can pass a logger object (compliant with the
203
- [stdlib Logger API](https://ruby-doc.org/stdlib-2.4.1/libdoc/logger/rdoc/)) to
204
- `Honeycomb.init`:
205
-
206
- ```ruby
207
- require 'logger'
208
- logger = Logger.new($stderr)
209
- logger.level = Logger::INFO # determine how much detail you want to see
210
- Honeycomb.init(logger: logger)
211
- ```
212
-
213
- A level of `Logger::DEBUG` will show you detail about each library being instrumented,
214
- whereas a level of `Logger::INFO` will just print a few progress messages.
215
-
216
- ### Get in touch
217
-
218
- This beeline is still young, so please reach out to
219
- [support@honeycomb.io](mailto:support@honeycomb.io) or ping us with the chat
220
- bubble on [our website](https://www.honeycomb.io) for assistance. We also
221
- welcome [bug reports](https://github.com/honeycombio/beeline-ruby/issues) and
222
- [contributions](https://github.com/honeycombio/beeline-ruby/blob/master/CONTRIBUTING.md).
36
+ All contributions will be released under the Apache License 2.0.
@@ -1,6 +1,6 @@
1
1
  module Honeycomb
2
2
  module Beeline
3
3
  GEM_NAME = 'honeycomb-beeline'
4
- VERSION = '0.5.0'
4
+ VERSION = '0.6.0'
5
5
  end
6
6
  end
@@ -72,7 +72,7 @@ module Honeycomb
72
72
  @client = new_client(options)
73
73
 
74
74
  after_init_hooks.each do |label, block|
75
- @logger.debug "Running hook '#{label}' after Honeycomb.init" if @logger
75
+ debug "Running hook '#{label}' after Honeycomb.init"
76
76
  run_hook(label, block)
77
77
  end
78
78
 
@@ -106,6 +106,16 @@ module Honeycomb
106
106
  end
107
107
 
108
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
+
109
119
  def after_init_hooks
110
120
  @after_init_hooks ||= []
111
121
  end
@@ -116,13 +126,13 @@ module Honeycomb
116
126
  options = {user_agent_addition: USER_AGENT_SUFFIX}.merge(options)
117
127
  if @debug
118
128
  raise ArgumentError, "can't specify both client and debug options", caller if client
119
- @logger.info 'logging events to standard error instead of sending to Honeycomb' if @logger
129
+ info 'logging events to standard error instead of sending to Honeycomb'
120
130
  client = Libhoney::LogClient.new(verbose: true, **options)
121
131
  else
122
132
  client ||= if options[:writekey] && options[:dataset]
123
133
  Libhoney::Client.new(options)
124
134
  else
125
- @logger.warn "#{self.name}: no #{options[:writekey] ? 'dataset' : 'writekey'} configured, disabling sending events" if @logger
135
+ warn "#{self.name}: no #{options[:writekey] ? 'dataset' : 'writekey'} configured, disabling sending events"
126
136
  Libhoney::NullClient.new(options)
127
137
  end
128
138
  end
@@ -146,7 +156,7 @@ module Honeycomb
146
156
  end
147
157
 
148
158
  if defined?(@initialized)
149
- @logger.debug "Running hook '#{label}' as Honeycomb already initialized" if @logger
159
+ debug "Running hook '#{label}' as Honeycomb already initialized"
150
160
  run_hook(label, hook)
151
161
  else
152
162
  after_init_hooks << [label, hook]
@@ -155,12 +165,12 @@ module Honeycomb
155
165
 
156
166
  def run_hook(label, block)
157
167
  if @without.include?(label)
158
- @logger.debug "Skipping hook '#{label}' due to opt-out" if @logger
168
+ debug "Skipping hook '#{label}' due to opt-out"
159
169
  else
160
170
  block.call @client, @logger
161
171
  end
162
172
  rescue => e
163
- @logger.warn "Honeycomb.init hook '#{label}' raised #{e.class}: #{e}" if @logger
173
+ warn "Honeycomb.init hook '#{label}' raised #{e.class}: #{e}"
164
174
  end
165
175
  end
166
176
 
@@ -1,42 +1,50 @@
1
+ require 'base64'
2
+ require 'json'
1
3
  require 'securerandom'
2
4
 
3
5
  module Honeycomb
4
6
  class << self
5
- # @api private
6
- def with_trace_id(trace_id = SecureRandom.uuid)
7
- Thread.current[:honeycomb_trace_id] = trace_id
8
- yield trace_id
9
- ensure
10
- Thread.current[:honeycomb_trace_id] = nil
11
- end
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)
12
13
 
13
- # @api private
14
- def trace_id
15
- Thread.current[:honeycomb_trace_id]
14
+ with_trace trace_id: trace_id, parent_span_id: parent_span_id, context: context do
15
+ yield
16
+ end
16
17
  end
17
18
 
18
- # @api private
19
- def with_span_id(span_id)
20
- parent_span_id = Thread.current[:honeycomb_span_id]
21
- Thread.current[:honeycomb_span_id] = span_id
22
- yield parent_span_id
23
- ensure
24
- Thread.current[:honeycomb_span_id] = parent_span_id
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
25
30
  end
26
31
 
27
- # @api private
28
- def span(service_name:, name:, span_id: SecureRandom.uuid)
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
+
29
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
30
44
 
31
- event.add_field 'trace.trace_id', trace_id if trace_id
32
- event.add_field 'service_name', service_name
33
- event.add_field 'name', name
34
- event.add_field 'trace.span_id', span_id
45
+ start = Time.now
35
46
 
36
- start = Time.now
37
- with_span_id(span_id) do |parent_span_id|
38
- event.add_field 'trace.parent_id', parent_span_id if parent_span_id
39
- yield
47
+ yield span_id, trace_id
40
48
  end
41
49
  rescue Exception => e
42
50
  if event
@@ -53,5 +61,235 @@ module Honeycomb
53
61
  event.send
54
62
  end
55
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
56
294
  end
57
295
  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.5.0
4
+ version: 0.6.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-19 00:00:00.000000000 Z
11
+ date: 2018-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libhoney
@@ -30,56 +30,56 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.3.0
33
+ version: 0.4.0
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.3.0
40
+ version: 0.4.0
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rack-honeycomb
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
46
46
  - !ruby/object:Gem::Version
47
- version: 0.3.0
47
+ version: 0.4.0
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
- version: 0.3.0
54
+ version: 0.4.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: faraday-honeycomb
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: 0.2.1
61
+ version: 0.3.0
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 0.2.1
68
+ version: 0.3.0
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: sequel-honeycomb
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: 0.2.1
75
+ version: 0.4.0
76
76
  type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: 0.2.1
82
+ version: 0.4.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: activerecord
85
85
  requirement: !ruby/object:Gem::Requirement