honeycomb-beeline 1.0.0.pre.alpha1 → 1.0.0.pre.beta

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: 0b983a1c5b4b52a3163efeee003c8084c18a7c13c19882f295a907c2cedfca67
4
- data.tar.gz: 1f7f2bde288e4020442b60501b99f055b7d9d6eb076aa5f458e5a298f783f337
3
+ metadata.gz: 51f069ff2b73a6b141dab639c08f4ddfe5cf7fa8292fd4e6a09bc550564b6092
4
+ data.tar.gz: 458d5f1636b41b3e2aaafde0eb6067f3d7de78298772b317f818d6f305c7b7a0
5
5
  SHA512:
6
- metadata.gz: ae48345d9bc3348a91b05de67b006c2844e1a9480c32ad835eeda5afe795d873013f7212b5cfe087504e84ac91fb323bb69eaf38dfb57c77df6ad2fcbfef9769
7
- data.tar.gz: 13ad83ca06195d0699b36b0e931eb2ba1a0fbd1aa0efe7f22c303ce04cf8b414994b5db6ff852ad3d83519bf11f5aff785083bd8b8c83c8b211a7592f6019429
6
+ metadata.gz: 0267a0f92727c4ff77801ccee578f754ca00e7e0a3c7162f170adabaff53bf63de933c9dcdd714d057bb62af55f784dddd9c01c39a4f8f5a4e657e8e53e67bd3
7
+ data.tar.gz: afdcf6a30a34d1610a7c6baf5d747fb46b1deb486f86764cf413d340603a02e0e6e029f4a89548c806a29747ee53e1162b49aa5304c138d460eae1fe2e076aa8
data/.rubocop.yml CHANGED
@@ -4,6 +4,7 @@ AllCops:
4
4
  TargetRubyVersion: 2.2
5
5
  Exclude:
6
6
  - "examples/**/*"
7
+ - "vendor/**/*"
7
8
 
8
9
  Style/StringLiterals:
9
10
  EnforcedStyle: double_quotes
@@ -14,7 +15,10 @@ Metrics/BlockLength:
14
15
  - spec/**/*.rb
15
16
 
16
17
  Metrics/AbcSize:
17
- Max: 40
18
+ Max: 50
19
+
20
+ Metrics/ClassLength:
21
+ Max: 200
18
22
 
19
23
  Metrics/MethodLength:
20
24
  Max: 25
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.5.3
1
+ 2.6.3
data/.travis.yml CHANGED
@@ -5,6 +5,7 @@ rvm:
5
5
  - 2.3
6
6
  - 2.4
7
7
  - 2.5
8
+ - 2.6
8
9
  gemfile:
9
10
  - gemfiles/faraday.gemfile
10
11
  - gemfiles/sequel4.gemfile
@@ -19,6 +20,7 @@ gemfile:
19
20
  - gemfiles/rails_6rc1.gemfile
20
21
  script: bundle exec rake test
21
22
  before_install:
23
+ - gem update bundler
22
24
  - ./bundler_version.sh
23
25
  matrix:
24
26
  exclude:
@@ -26,17 +28,27 @@ matrix:
26
28
  gemfile: gemfiles/rails_41.gemfile
27
29
  - rvm: 2.5
28
30
  gemfile: gemfiles/rails_41.gemfile
31
+ - rvm: 2.6
32
+ gemfile: gemfiles/rails_41.gemfile
29
33
  - rvm: 2.2
30
34
  gemfile: gemfiles/rails_6rc1.gemfile
31
35
  - rvm: 2.3
32
36
  gemfile: gemfiles/rails_6rc1.gemfile
33
37
  - rvm: 2.4
34
38
  gemfile: gemfiles/rails_6rc1.gemfile
39
+ stages:
40
+ - lint
41
+ - test
42
+ - deploy
35
43
  jobs:
36
44
  include:
45
+ - stage: lint
46
+ script: bundle exec rake rubocop
47
+ rvm: 2.6
48
+ gemfile: Gemfile
37
49
  - stage: deploy
38
50
  script: skip
39
- rvm: 2.5
51
+ rvm: 2.6
40
52
  gemfile: Gemfile
41
53
  deploy:
42
54
  provider: rubygems
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honeycomb-beeline (1.0.0.pre.alpha1)
4
+ honeycomb-beeline (1.0.0.pre.beta)
5
5
  libhoney (~> 1.8)
6
6
 
7
7
  GEM
@@ -24,7 +24,7 @@ GEM
24
24
  safe_yaml (~> 1.0.0)
25
25
  diff-lcs (1.3)
26
26
  docile (1.3.2)
27
- domain_name (0.5.20180417)
27
+ domain_name (0.5.20190701)
28
28
  unf (>= 0.0.5, < 1.0.0)
29
29
  ffi (1.11.1)
30
30
  hashdiff (0.4.0)
data/bundler_version.sh CHANGED
@@ -1,12 +1,9 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- set -uex
3
+ set -ux
4
4
 
5
5
  if [[ "$BUNDLE_GEMFILE" =~ (rails_41.gemfile|rails_42.gemfile)$ ]]; then
6
- if [[ "$TRAVIS_RUBY_VERSION" =~ ^(2.3)$ ]]; then
7
- gem uninstall -v '>= 2' -i $(rvm gemdir) -ax bundler
8
- elif [[ "$TRAVIS_RUBY_VERSION" =~ ^(2.4|2.5)$ ]]; then
9
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler
10
- fi
6
+ gem uninstall -v '>= 2' -i $(rvm gemdir) -ax bundler
7
+ gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler
11
8
  gem install bundler -v '< 2'
12
9
  fi
@@ -13,7 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.summary = "Instrument your Ruby apps with Honeycomb"
14
14
  spec.homepage = "https://honeycomb.io"
15
15
 
16
- spec.license = 'Apache-2.0'
16
+ spec.license = "Apache-2.0"
17
17
 
18
18
  spec.required_ruby_version = ">= 2.2.0"
19
19
 
@@ -1,33 +1,40 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "forwardable"
3
4
  require "libhoney"
4
-
5
5
  require "honeycomb/beeline/version"
6
6
  require "honeycomb/client"
7
7
  require "honeycomb/trace"
8
8
 
9
9
  # main module
10
10
  module Honeycomb
11
+ INTEGRATIONS = %i[
12
+ active_support
13
+ faraday
14
+ rack
15
+ rails
16
+ rake
17
+ sequel
18
+ sinatra
19
+ ].freeze
20
+
11
21
  class << self
22
+ extend Forwardable
12
23
  attr_reader :client
13
24
 
25
+ def_delegators :@client, :start_span, :add_field, :add_field_to_trace
26
+
14
27
  def configure
15
28
  Configuration.new.tap do |config|
16
29
  yield config
17
- @client = Honeycomb::Client.new(client: config.client,
18
- service_name: config.service_name)
19
- config.after_initialize(@client)
30
+ @client = Honeycomb::Client.new(configuration: config)
20
31
  end
21
32
 
22
33
  @client
23
34
  end
24
35
 
25
- def start_span(name:, &block)
26
- client.start_span(name: name, &block)
27
- end
28
-
29
36
  def load_integrations
30
- %i[faraday rack sinatra rails sequel active_support].each do |integration|
37
+ INTEGRATIONS.each do |integration|
31
38
  begin
32
39
  require "honeycomb/integrations/#{integration}"
33
40
  rescue LoadError
@@ -35,40 +42,6 @@ module Honeycomb
35
42
  end
36
43
  end
37
44
  end
38
-
39
- # Used to configure the Honeycomb client
40
- class Configuration
41
- attr_accessor :write_key,
42
- :dataset,
43
- :api_host
44
-
45
- attr_writer :service_name, :client
46
-
47
- def initialize
48
- @write_key = ENV["HONEYCOMB_WRITEKEY"]
49
- @dataset = ENV["HONEYCOMB_DATASET"]
50
- @service_name = ENV["HONEYCOMB_SERVICE"]
51
- @client = nil
52
- end
53
-
54
- def service_name
55
- @service_name || dataset
56
- end
57
-
58
- def client
59
- options = {}.tap do |o|
60
- o[:writekey] = write_key
61
- o[:dataset] = dataset
62
- api_host && o[:api_host] = api_host
63
- end
64
-
65
- @client || Libhoney::Client.new(options)
66
- end
67
-
68
- def after_initialize(client)
69
- super(client) if defined?(super)
70
- end
71
- end
72
45
  end
73
46
 
74
47
  Honeycomb.load_integrations unless ENV["HONEYCOMB_DISABLE_AUTOCONFIGURE"]
@@ -3,7 +3,7 @@
3
3
  module Honeycomb
4
4
  module Beeline
5
5
  NAME = "honeycomb-beeline".freeze
6
- VERSION = "1.0.0-alpha1".freeze
6
+ VERSION = "1.0.0-beta".freeze
7
7
  USER_AGENT_SUFFIX = "#{NAME}/#{VERSION}".freeze
8
8
  end
9
9
  end
@@ -1,29 +1,33 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "socket"
4
- require "forwardable"
5
3
  require "honeycomb/beeline/version"
4
+ require "honeycomb/configuration"
6
5
  require "honeycomb/context"
7
6
 
8
7
  module Honeycomb
9
8
  # The Honeycomb Beeline client
10
9
  class Client
11
- extend Forwardable
12
-
13
- def initialize(client:, service_name: nil)
10
+ def initialize(configuration:)
11
+ @client = configuration.client
14
12
  # attempt to set the user_agent_addition, this will only work if the
15
13
  # client has not sent an event prior to being passed in here. This should
16
14
  # be most cases
17
- client.instance_variable_set(:@user_agent_addition,
18
- Honeycomb::Beeline::USER_AGENT_SUFFIX)
19
- client.add_field "meta.beeline_version", Honeycomb::Beeline::VERSION
20
- client.add_field "meta.local_hostname", host_name
15
+ @client.instance_variable_set(:@user_agent_addition,
16
+ Honeycomb::Beeline::USER_AGENT_SUFFIX)
17
+ @client.add_field "meta.beeline_version", Honeycomb::Beeline::VERSION
18
+ @client.add_field "meta.local_hostname", configuration.host_name
21
19
 
22
20
  # maybe make `service_name` a required parameter
23
- client.add_field "service_name", service_name
24
- @client = client
21
+ @client.add_field "service_name", configuration.service_name
25
22
  @context = Context.new
26
23
 
24
+ @additional_trace_options = {
25
+ presend_hook: configuration.presend_hook,
26
+ sample_hook: configuration.sample_hook,
27
+ }
28
+
29
+ configuration.after_initialize(self)
30
+
27
31
  at_exit do
28
32
  client.close
29
33
  end
@@ -33,7 +37,8 @@ module Honeycomb
33
37
  if context.current_trace.nil?
34
38
  Trace.new(serialized_trace: serialized_trace,
35
39
  builder: client.builder,
36
- context: context)
40
+ context: context,
41
+ **@additional_trace_options)
37
42
  else
38
43
  context.current_span.create_child
39
44
  end
@@ -70,10 +75,5 @@ module Honeycomb
70
75
  private
71
76
 
72
77
  attr_reader :client, :context
73
-
74
- def host_name
75
- # Send the heroku dyno name instead of hostname if available
76
- ENV["DYNO"] || Socket.gethostname
77
- end
78
78
  end
79
79
  end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "socket"
4
+
5
+ module Honeycomb
6
+ # Used to configure the Honeycomb client
7
+ class Configuration
8
+ attr_accessor :write_key,
9
+ :dataset,
10
+ :api_host
11
+
12
+ attr_writer :service_name, :client, :host_name
13
+
14
+ def initialize
15
+ @write_key = ENV["HONEYCOMB_WRITEKEY"]
16
+ @dataset = ENV["HONEYCOMB_DATASET"]
17
+ @service_name = ENV["HONEYCOMB_SERVICE"]
18
+ @client = nil
19
+ end
20
+
21
+ def service_name
22
+ @service_name || dataset
23
+ end
24
+
25
+ def client
26
+ options = {}.tap do |o|
27
+ o[:writekey] = write_key
28
+ o[:dataset] = dataset
29
+ api_host && o[:api_host] = api_host
30
+ end
31
+
32
+ @client || Libhoney::Client.new(options)
33
+ end
34
+
35
+ def after_initialize(client)
36
+ super(client) if defined?(super)
37
+ end
38
+
39
+ def host_name
40
+ # Send the heroku dyno name instead of hostname if available
41
+ @host_name || ENV["DYNO"] || Socket.gethostname
42
+ end
43
+
44
+ def presend_hook(&hook)
45
+ if block_given?
46
+ @presend_hook = hook
47
+ else
48
+ @presend_hook
49
+ end
50
+ end
51
+
52
+ def sample_hook(&hook)
53
+ if block_given?
54
+ @sample_hook = hook
55
+ else
56
+ @sample_hook
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "digest"
4
+
5
+ module Honeycomb
6
+ ##
7
+ # Provides a should_sample method which can be used for deterministic
8
+ # sampling
9
+ #
10
+ module DeterministicSampler
11
+ MAX_INT32 = 2**32 - 1
12
+
13
+ def should_sample(rate, value)
14
+ return true if rate == 1
15
+
16
+ upper_bound = MAX_INT32 / rate
17
+ digest = Digest::SHA1.digest(value)[0, 4]
18
+ value = digest.unpack("I!>").first
19
+ value <= upper_bound
20
+ end
21
+ end
22
+ end
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "rails"
3
+ require "rails/railtie"
4
4
  require "honeycomb/integrations/active_support"
5
5
  require "honeycomb/integrations/rack"
6
6
 
@@ -31,7 +31,8 @@ module Honeycomb
31
31
 
32
32
  # Automatically capture rack requests and create a trace
33
33
  class Railtie < ::Rails::Railtie
34
- initializer "honeycomb.install_middleware", after: :load_config_initializers do |app|
34
+ initializer("honeycomb.install_middleware",
35
+ after: :load_config_initializers) do |app|
35
36
  if Honeycomb.client
36
37
  # what location should we insert the middleware at?
37
38
  app.config.middleware.insert_before(
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rake"
4
+
5
+ Rake::TaskManager.record_task_metadata = true
6
+
7
+ module Honeycomb
8
+ module Rake
9
+ ##
10
+ # Automatically capture rake tasks and create a trace
11
+ #
12
+ module Task
13
+ def execute(args = nil)
14
+ return super(args) if honeycomb_client.nil?
15
+
16
+ honeycomb_client.start_span(name: "rake.#{name}") do |span|
17
+ span.add_field("meta.package", "rake")
18
+ span.add_field("meta.package_version", ::Rake::VERSION)
19
+ full_comment && span.add_field("rake.description", full_comment)
20
+ arg_description && span.add_field("rake.arguments", arg_description)
21
+ super(args)
22
+ end
23
+ end
24
+
25
+ def honeycomb_client
26
+ application.honeycomb_client
27
+ end
28
+ end
29
+
30
+ ##
31
+ # Provide access to the honeycomb_client for the rake tasks, can be
32
+ # provided or uses the default global honeycomb client
33
+ #
34
+ module Application
35
+ attr_writer :honeycomb_client
36
+
37
+ def honeycomb_client
38
+ @honeycomb_client || Honeycomb.client
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ Rake::Application.include(Honeycomb::Rake::Application)
45
+ Rake::Task.prepend(Honeycomb::Rake::Task)
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "base64"
4
4
  require "json"
5
+ require "uri"
5
6
 
6
7
  module Honeycomb
7
8
  # Parse trace headers
@@ -28,7 +29,7 @@ module Honeycomb
28
29
  key, value = entry.split("=", 2)
29
30
  case key
30
31
  when "dataset"
31
- dataset = value
32
+ dataset = URI.decode_www_form_component(value)
32
33
  when "trace_id"
33
34
  trace_id = value
34
35
  when "parent_id"
@@ -52,7 +53,14 @@ module Honeycomb
52
53
  module PropagationSerializer
53
54
  def to_trace_header
54
55
  context = Base64.urlsafe_encode64(JSON.generate(trace.fields)).strip
55
- "1;trace_id=#{trace.id},parent_id=#{id},context=#{context}"
56
+ encoded_dataset = URI.encode_www_form_component(builder.dataset)
57
+ data_to_propogate = [
58
+ "dataset=#{encoded_dataset}",
59
+ "trace_id=#{trace.id}",
60
+ "parent_id=#{id}",
61
+ "context=#{context}",
62
+ ]
63
+ "1;#{data_to_propogate.join(',')}"
56
64
  end
57
65
  end
58
66
  end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Honeycomb
4
+ ##
5
+ # Functionality for including 'rollup_fields'. Which are fields that can be
6
+ # tracked numerically and will also be propogated up to an existing trace.
7
+ #
8
+ module RollupFields
9
+ def rollup_fields
10
+ @rollup_fields ||= Hash.new(0)
11
+ end
12
+
13
+ def add_rollup_field(key, value)
14
+ return unless value.is_a? Numeric
15
+
16
+ respond_to?(:trace) && trace.add_rollup_field(key, value)
17
+ rollup_fields[key] += value
18
+ end
19
+ end
20
+ end
@@ -1,45 +1,50 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "securerandom"
3
4
  require "forwardable"
4
5
  require "honeycomb/propagation"
6
+ require "honeycomb/deterministic_sampler"
7
+ require "honeycomb/rollup_fields"
5
8
 
6
9
  module Honeycomb
7
10
  # Represents a Honeycomb span, which wraps a Honeycomb event and adds specific
8
11
  # tracing functionality
9
12
  class Span
10
13
  include PropagationSerializer
14
+ include DeterministicSampler
15
+ include RollupFields
11
16
  extend Forwardable
12
17
 
13
18
  def_delegators :@event, :add_field, :add
19
+ def_delegator :@trace, :add_field, :add_trace_field
14
20
 
15
21
  attr_reader :id, :trace
16
22
 
17
23
  def initialize(trace:,
18
24
  builder:,
19
25
  context:,
20
- parent_id: nil,
21
- is_root: parent_id.nil?)
26
+ **options)
22
27
  @id = SecureRandom.uuid
23
28
  @context = context
24
29
  @context.current_span = self
25
30
  @builder = builder
26
31
  @event = builder.event
27
32
  @trace = trace
28
- @parent_id = parent_id
29
- @is_root = is_root
30
- @rollup_fields = Hash.new(0)
31
33
  @children = []
32
34
  @sent = false
33
35
  @started = clock_time
36
+ parse_options(**options)
34
37
  end
35
38
 
36
- def add_rollup_field(key, value)
37
- trace.add_rollup_field(key, value)
38
- rollup_fields[key] += value
39
- end
40
-
41
- def add_trace_field(key, value)
42
- trace.add_field(key, value)
39
+ def parse_options(parent_id: nil,
40
+ is_root: parent_id.nil?,
41
+ sample_hook: nil,
42
+ presend_hook: nil,
43
+ **_options)
44
+ @parent_id = parent_id
45
+ @is_root = is_root
46
+ @presend_hook = presend_hook
47
+ @sample_hook = sample_hook
43
48
  end
44
49
 
45
50
  def create_child
@@ -68,12 +73,13 @@ module Honeycomb
68
73
 
69
74
  private
70
75
 
71
- attr_reader :rollup_fields,
72
- :event,
76
+ attr_reader :event,
73
77
  :parent_id,
74
78
  :children,
75
79
  :builder,
76
- :context
80
+ :context,
81
+ :presend_hook,
82
+ :sample_hook
77
83
 
78
84
  def sent?
79
85
  @sent
@@ -93,7 +99,17 @@ module Honeycomb
93
99
  add trace.fields
94
100
  span_type == "root" && add(trace.rollup_fields)
95
101
  send_children
96
- event.send
102
+ sample = true
103
+ if sample_hook.nil?
104
+ sample = should_sample(event.sample_rate, trace.id)
105
+ else
106
+ sample, event.sample_rate = sample_hook.call(event.data)
107
+ end
108
+
109
+ if sample
110
+ presend_hook && presend_hook.call(event.data)
111
+ event.send_presampled
112
+ end
97
113
  @sent = true
98
114
  context.span_sent(self)
99
115
  end
@@ -4,37 +4,35 @@ require "forwardable"
4
4
  require "securerandom"
5
5
  require "honeycomb/span"
6
6
  require "honeycomb/propagation"
7
+ require "honeycomb/rollup_fields"
7
8
 
8
9
  module Honeycomb
9
10
  # Represents a Honeycomb trace, which groups spans together
10
11
  class Trace
11
12
  include PropagationParser
13
+ include RollupFields
12
14
  extend Forwardable
13
15
 
14
16
  def_delegators :@root_span, :send
15
17
 
16
- attr_reader :id, :fields, :root_span, :rollup_fields
18
+ attr_reader :id, :fields, :root_span
17
19
 
18
- def initialize(builder:, context:, serialized_trace: nil)
20
+ def initialize(builder:, context:, serialized_trace: nil, **options)
19
21
  trace_id, parent_span_id, trace_fields, dataset =
20
22
  parse serialized_trace
21
23
  dataset && builder.dataset = dataset
22
24
  @id = trace_id || SecureRandom.uuid
23
- @rollup_fields = Hash.new(0)
24
25
  @fields = trace_fields || {}
25
26
  @root_span = Span.new(trace: self,
26
27
  parent_id: parent_span_id,
27
28
  is_root: true,
28
29
  builder: builder,
29
- context: context)
30
+ context: context,
31
+ **options)
30
32
  end
31
33
 
32
34
  def add_field(key, value)
33
35
  @fields[key] = value
34
36
  end
35
-
36
- def add_rollup_field(key, value)
37
- @rollup_fields[key] += value
38
- end
39
37
  end
40
38
  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: 1.0.0.pre.alpha1
4
+ version: 1.0.0.pre.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Holman
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-06-27 00:00:00.000000000 Z
11
+ date: 2019-07-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: libhoney
@@ -221,14 +221,18 @@ files:
221
221
  - lib/honeycomb-beeline.rb
222
222
  - lib/honeycomb/beeline/version.rb
223
223
  - lib/honeycomb/client.rb
224
+ - lib/honeycomb/configuration.rb
224
225
  - lib/honeycomb/context.rb
226
+ - lib/honeycomb/deterministic_sampler.rb
225
227
  - lib/honeycomb/integrations/active_support.rb
226
228
  - lib/honeycomb/integrations/faraday.rb
227
229
  - lib/honeycomb/integrations/rack.rb
228
230
  - lib/honeycomb/integrations/rails.rb
231
+ - lib/honeycomb/integrations/rake.rb
229
232
  - lib/honeycomb/integrations/sequel.rb
230
233
  - lib/honeycomb/integrations/sinatra.rb
231
234
  - lib/honeycomb/propagation.rb
235
+ - lib/honeycomb/rollup_fields.rb
232
236
  - lib/honeycomb/span.rb
233
237
  - lib/honeycomb/trace.rb
234
238
  - lib/sequel/extensions/honeycomb.rb