honeycomb-beeline 2.0.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,12 @@
1
+ root = true
2
+
3
+ [*]
4
+ indent_style = space
5
+ indent_size = 2
6
+ charset = utf-8
7
+ trim_trailing_whitespace = true
8
+ insert_final_newline = true
9
+
10
+ [*.md]
11
+ indent_size = 4
12
+ trim_trailing_whitespace = true
@@ -0,0 +1,5 @@
1
+ # Code owners file.
2
+ # This file controls who is tagged for review for any given pull request.
3
+
4
+ # For anything not explicitly taken by someone else:
5
+ * @honeycombio/integrations-team @martin308
@@ -29,6 +29,15 @@ Metrics/LineLength:
29
29
  Exclude:
30
30
  - spec/support/event_data_shared_examples.rb
31
31
 
32
+ Metrics/ParameterLists:
33
+ Max: 6
34
+
35
+ Style/AccessModifierDeclarations:
36
+ Exclude:
37
+ - lib/honeycomb/propagation/aws.rb
38
+ - lib/honeycomb/propagation/w3c.rb
39
+ - lib/honeycomb/propagation/honeycomb.rb
40
+
32
41
  Style/FrozenStringLiteralComment:
33
42
  EnforcedStyle: always
34
43
  Exclude:
@@ -1,24 +1,27 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- honeycomb-beeline (2.0.0)
4
+ honeycomb-beeline (2.3.0)
5
5
  libhoney (~> 1.14, >= 1.14.2)
6
6
 
7
7
  GEM
8
8
  remote: https://rubygems.org/
9
9
  specs:
10
- addressable (2.6.0)
11
- public_suffix (>= 2.0.2, < 4.0)
10
+ addressable (2.7.0)
11
+ public_suffix (>= 2.0.2, < 5.0)
12
12
  ansi (1.5.0)
13
13
  appraisal (2.2.0)
14
14
  bundler
15
15
  rake
16
16
  thor (>= 0.14.0)
17
17
  ast (2.4.0)
18
- bump (0.8.0)
19
- byebug (11.0.1)
18
+ bump (0.9.0)
19
+ byebug (10.0.2)
20
20
  childprocess (0.9.0)
21
21
  ffi (~> 1.0, >= 1.0.11)
22
+ codecov (0.2.8)
23
+ json
24
+ simplecov
22
25
  coderay (1.1.2)
23
26
  crack (0.4.3)
24
27
  safe_yaml (~> 1.0.0)
@@ -26,12 +29,12 @@ GEM
26
29
  docile (1.3.2)
27
30
  domain_name (0.5.20190701)
28
31
  unf (>= 0.0.5, < 1.0.0)
29
- ffi (1.11.1)
32
+ ffi (1.12.2)
30
33
  ffi-compiler (1.0.1)
31
34
  ffi (>= 1.0.0)
32
35
  rake
33
- hashdiff (0.4.0)
34
- http (4.3.0)
36
+ hashdiff (1.0.1)
37
+ http (4.4.1)
35
38
  addressable (~> 2.3)
36
39
  http-cookie (~> 1.0)
37
40
  http-form_data (~> 2.2)
@@ -41,41 +44,41 @@ GEM
41
44
  http-form_data (2.3.0)
42
45
  http-parser (1.2.1)
43
46
  ffi-compiler (>= 1.0, < 2.0)
44
- iniparse (1.4.4)
45
- jaro_winkler (1.5.3)
46
- json (2.2.0)
47
- libhoney (1.14.4)
47
+ iniparse (1.5.0)
48
+ jaro_winkler (1.5.4)
49
+ json (2.3.1)
50
+ libhoney (1.14.5)
48
51
  addressable (~> 2.0)
49
52
  http (>= 2.0, < 5.0)
50
53
  method_source (0.9.2)
51
54
  overcommit (0.46.0)
52
55
  childprocess (~> 0.6, >= 0.6.3)
53
56
  iniparse (~> 1.4)
54
- parallel (1.17.0)
55
- parser (2.6.3.0)
57
+ parallel (1.19.1)
58
+ parser (2.7.1.2)
56
59
  ast (~> 2.4.0)
57
60
  pry (0.12.2)
58
61
  coderay (~> 1.1.0)
59
62
  method_source (~> 0.9.0)
60
- pry-byebug (3.7.0)
61
- byebug (~> 11.0)
63
+ pry-byebug (3.6.0)
64
+ byebug (~> 10.0)
62
65
  pry (~> 0.10)
63
- public_suffix (3.1.1)
66
+ public_suffix (4.0.4)
64
67
  rainbow (3.0.0)
65
68
  rake (13.0.1)
66
- rspec (3.8.0)
67
- rspec-core (~> 3.8.0)
68
- rspec-expectations (~> 3.8.0)
69
- rspec-mocks (~> 3.8.0)
70
- rspec-core (3.8.1)
71
- rspec-support (~> 3.8.0)
72
- rspec-expectations (3.8.4)
69
+ rspec (3.9.0)
70
+ rspec-core (~> 3.9.0)
71
+ rspec-expectations (~> 3.9.0)
72
+ rspec-mocks (~> 3.9.0)
73
+ rspec-core (3.9.2)
74
+ rspec-support (~> 3.9.3)
75
+ rspec-expectations (3.9.2)
73
76
  diff-lcs (>= 1.2.0, < 2.0)
74
- rspec-support (~> 3.8.0)
75
- rspec-mocks (3.8.1)
77
+ rspec-support (~> 3.9.0)
78
+ rspec-mocks (3.9.1)
76
79
  diff-lcs (>= 1.2.0, < 2.0)
77
- rspec-support (~> 3.8.0)
78
- rspec-support (3.8.2)
80
+ rspec-support (~> 3.9.0)
81
+ rspec-support (3.9.3)
79
82
  rubocop (0.68.1)
80
83
  jaro_winkler (~> 1.5.1)
81
84
  parallel (~> 1.10)
@@ -87,23 +90,22 @@ GEM
87
90
  rubocop (>= 0.68.0)
88
91
  ruby-progressbar (1.10.1)
89
92
  safe_yaml (1.0.5)
90
- simplecov (0.16.1)
93
+ simplecov (0.18.5)
91
94
  docile (~> 1.1)
92
- json (>= 1.8, < 3)
93
- simplecov-html (~> 0.10.0)
94
- simplecov-console (0.5.0)
95
+ simplecov-html (~> 0.11)
96
+ simplecov-console (0.7.2)
95
97
  ansi
96
98
  simplecov
97
99
  terminal-table
98
- simplecov-html (0.10.2)
100
+ simplecov-html (0.12.2)
99
101
  terminal-table (1.8.0)
100
102
  unicode-display_width (~> 1.1, >= 1.1.1)
101
- thor (0.20.3)
103
+ thor (1.0.1)
102
104
  unf (0.1.4)
103
105
  unf_ext
104
- unf_ext (0.0.7.6)
106
+ unf_ext (0.0.7.7)
105
107
  unicode-display_width (1.5.0)
106
- webmock (3.6.0)
108
+ webmock (3.8.3)
107
109
  addressable (>= 2.3.6)
108
110
  crack (>= 0.3.2)
109
111
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -115,9 +117,11 @@ DEPENDENCIES
115
117
  appraisal
116
118
  bump
117
119
  bundler
120
+ codecov
118
121
  honeycomb-beeline!
119
122
  overcommit (~> 0.46.0)
120
- pry-byebug
123
+ pry (< 0.13.0)
124
+ pry-byebug (~> 3.6.0)
121
125
  rake
122
126
  rspec (~> 3.0)
123
127
  rubocop (< 0.69)
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  [![Build Status](https://circleci.com/gh/honeycombio/beeline-ruby.svg?style=svg)](https://circleci.com/gh/honeycombio/beeline-ruby)
4
4
  [![Gem Version](https://badge.fury.io/rb/honeycomb-beeline.svg)](https://badge.fury.io/rb/honeycomb-beeline)
5
+ [![codecov](https://codecov.io/gh/honeycombio/beeline-ruby/branch/main/graph/badge.svg)](https://codecov.io/gh/honeycombio/beeline-ruby)
5
6
 
6
7
  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
8
  - [Usage and Examples](https://docs.honeycomb.io/getting-data-in/beelines/ruby-beeline/)
@@ -24,6 +25,13 @@ Built in instrumentation for:
24
25
  - Sequel
25
26
  - Sinatra
26
27
 
28
+ ## Testing
29
+ Find `rspec` test files in the `spec` directory.
30
+
31
+ To run tests on gem-specific instrumentations or across various dependency versions, use [appraisal](https://github.com/thoughtbot/appraisal) (further instructions in the readme for that gem). Find gem sets in the `Appraisals` config.
32
+
33
+ To run a specific file: `bundle exec appraisal <gem set> rspec <path/to/file>`
34
+
27
35
  ## Get in touch
28
36
 
29
37
  Please reach out to [support@honeycomb.io](mailto:support@honeycomb.io) or ping
@@ -42,8 +42,10 @@ Gem::Specification.new do |spec|
42
42
  spec.add_development_dependency "appraisal"
43
43
  spec.add_development_dependency "bump"
44
44
  spec.add_development_dependency "bundler"
45
+ spec.add_development_dependency "codecov"
45
46
  spec.add_development_dependency "overcommit", "~> 0.46.0"
46
- spec.add_development_dependency "pry-byebug"
47
+ spec.add_development_dependency "pry", "< 0.13.0"
48
+ spec.add_development_dependency "pry-byebug", "~> 3.6.0"
47
49
  spec.add_development_dependency "rake"
48
50
  spec.add_development_dependency "rspec", "~> 3.0"
49
51
  spec.add_development_dependency "rubocop", "< 0.69"
@@ -3,7 +3,7 @@
3
3
  module Honeycomb
4
4
  module Beeline
5
5
  NAME = "honeycomb-beeline".freeze
6
- VERSION = "2.0.0".freeze
6
+ VERSION = "2.3.0".freeze
7
7
  USER_AGENT_SUFFIX = "#{NAME}/#{VERSION}".freeze
8
8
  end
9
9
  end
@@ -35,6 +35,8 @@ module Honeycomb
35
35
  @additional_trace_options = {
36
36
  presend_hook: configuration.presend_hook,
37
37
  sample_hook: configuration.sample_hook,
38
+ parser_hook: configuration.http_trace_parser_hook,
39
+ propagation_hook: configuration.http_trace_propagation_hook,
38
40
  }
39
41
 
40
42
  configuration.after_initialize(self)
@@ -54,24 +56,24 @@ module Honeycomb
54
56
  context.current_span.create_child
55
57
  end
56
58
 
59
+ current_span = context.current_span
60
+
57
61
  fields.each do |key, value|
58
- context.current_span.add_field(key, value)
62
+ current_span.add_field(key, value)
59
63
  end
60
64
 
61
- context.current_span.add_field("name", name)
62
-
63
- if block_given?
64
- begin
65
- yield context.current_span
66
- rescue StandardError => e
67
- context.current_span.add_field("error", e.class.name)
68
- context.current_span.add_field("error_detail", e.message)
69
- raise e
70
- ensure
71
- context.current_span.send
72
- end
73
- else
74
- context.current_span
65
+ current_span.add_field("name", name)
66
+
67
+ return current_span unless block_given?
68
+
69
+ begin
70
+ yield current_span
71
+ rescue StandardError => e
72
+ current_span.add_field("error", e.class.name)
73
+ current_span.add_field("error_detail", e.message)
74
+ raise e
75
+ ensure
76
+ current_span.send
75
77
  end
76
78
  end
77
79
 
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "socket"
4
+ require "honeycomb/propagation/honeycomb"
4
5
 
5
6
  module Honeycomb
6
7
  # Used to configure the Honeycomb client
@@ -33,7 +34,7 @@ module Honeycomb
33
34
 
34
35
  @client ||
35
36
  (debug && Libhoney::LogClient.new) ||
36
- Libhoney::Client.new(options)
37
+ Libhoney::Client.new(**options)
37
38
  end
38
39
 
39
40
  def after_initialize(client)
@@ -60,5 +61,27 @@ module Honeycomb
60
61
  @sample_hook
61
62
  end
62
63
  end
64
+
65
+ def http_trace_parser_hook(&hook)
66
+ if block_given?
67
+ @http_trace_parser_hook = hook
68
+ elsif @http_trace_parser_hook
69
+ @http_trace_parser_hook
70
+ else
71
+ # by default we try to parse incoming honeycomb traces
72
+ HoneycombPropagation::UnmarshalTraceContext.method(:parse_rack_env)
73
+ end
74
+ end
75
+
76
+ def http_trace_propagation_hook(&hook)
77
+ if block_given?
78
+ @http_trace_propagation_hook = hook
79
+ elsif @http_trace_propagation_hook
80
+ @http_trace_propagation_hook
81
+ else
82
+ # by default we send outgoing honeycomb trace headers
83
+ HoneycombPropagation::MarshalTraceContext.method(:parse_faraday_env)
84
+ end
85
+ end
63
86
  end
64
87
  end
@@ -65,7 +65,7 @@ module Honeycomb
65
65
  def finish(name, id, payload)
66
66
  return unless (span = spans[id].pop)
67
67
 
68
- handlers[name].call(name, span, payload)
68
+ handler_for(name).call(name, span, payload)
69
69
 
70
70
  span.send
71
71
  end
@@ -77,6 +77,16 @@ module Honeycomb
77
77
  def spans
78
78
  Thread.current[key] ||= Hash.new { |h, id| h[id] = [] }
79
79
  end
80
+
81
+ def handler_for(name)
82
+ handlers.fetch(name) do
83
+ handlers[
84
+ handlers.keys.detect do |key|
85
+ key.is_a?(Regexp) && key =~ name
86
+ end
87
+ ]
88
+ end
89
+ end
80
90
  end
81
91
  end
82
92
  end
@@ -22,7 +22,9 @@ module Honeycomb
22
22
  span.add_field "meta.package", "faraday"
23
23
  span.add_field "meta.package_version", ::Faraday::VERSION
24
24
 
25
- env.request_headers["X-Honeycomb-Trace"] = span.to_trace_header
25
+ if (headers = span.trace_headers(env)).is_a?(Hash)
26
+ env.request_headers.merge!(headers)
27
+ end
26
28
 
27
29
  @app.call(env).tap do |response|
28
30
  span.add_field "response.status_code", response.status
@@ -13,7 +13,11 @@ module Honeycomb
13
13
  ["HTTP_VERSION", "request.http_version"],
14
14
  ["HTTP_HOST", "request.host"],
15
15
  ["REMOTE_ADDR", "request.remote_addr"],
16
+ ["HTTP_X_FORWARDED_FOR", "request.header.x_forwarded_for"],
17
+ ["HTTP_X_FORWARDED_PROTO", "request.header.x_forwarded_proto"],
18
+ ["HTTP_X_FORWARDED_PORT", "request.header.x_forwarded_port"],
16
19
  ["HTTP_ACCEPT", "request.header.accept"],
20
+ ["HTTP_ACCEPT_LANGUAGE", "request.header.accept_language"],
17
21
  ["CONTENT_TYPE", "request.header.content_type"],
18
22
  ["HTTP_USER_AGENT", "request.header.user_agent"],
19
23
  ["rack.url_scheme", "request.scheme"],
@@ -28,12 +32,14 @@ module Honeycomb
28
32
 
29
33
  def call(env)
30
34
  req = ::Rack::Request.new(env)
31
- hny = env["HTTP_X_HONEYCOMB_TRACE"]
32
- client.start_span(name: "http_request", serialized_trace: hny) do |span|
35
+ client.start_span(
36
+ name: "http_request",
37
+ serialized_trace: env,
38
+ ) do |span|
33
39
  add_field = lambda do |key, value|
34
- next unless value && !value.empty?
35
-
36
- span.add_field(key, value)
40
+ unless value.nil? || (value.respond_to?(:empty?) && value.empty?)
41
+ span.add_field(key, value)
42
+ end
37
43
  end
38
44
 
39
45
  extract_fields(env, RACK_FIELDS, &add_field)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Honeycomb
4
- # Methods for extracing common warden/devise fields from a rack env hash
4
+ # Methods for extracting common warden/devise fields from a rack env hash
5
5
  module Warden
6
6
  COMMON_USER_FIELDS = %i[
7
7
  email
@@ -24,7 +24,7 @@ module Honeycomb
24
24
  key.match(SCOPE_PATTERN)
25
25
  end
26
26
  warden_scopes = keys.map do |key|
27
- key.gsub(SCOPE_PATTERN, "\1")
27
+ key.gsub(SCOPE_PATTERN, "\\1")
28
28
  end
29
29
  best_scope = warden_scopes.include?("user") ? "user" : warden_scopes.first
30
30
 
@@ -4,63 +4,16 @@ require "base64"
4
4
  require "json"
5
5
  require "uri"
6
6
 
7
+ require "honeycomb/propagation/honeycomb"
8
+
7
9
  module Honeycomb
8
10
  # Parse trace headers
9
11
  module PropagationParser
10
- def parse(serialized_trace)
11
- unless serialized_trace.nil?
12
- version, payload = serialized_trace.split(";", 2)
13
-
14
- if version == "1"
15
- trace_id, parent_span_id, trace_fields, dataset = parse_v1(payload)
16
-
17
- if !trace_id.nil? && !parent_span_id.nil?
18
- return [trace_id, parent_span_id, trace_fields, dataset]
19
- end
20
- end
21
- end
22
-
23
- [nil, nil, nil, nil]
24
- end
25
-
26
- def parse_v1(payload)
27
- trace_id, parent_span_id, trace_fields, dataset = nil
28
- payload.split(",").each do |entry|
29
- key, value = entry.split("=", 2)
30
- case key
31
- when "dataset"
32
- dataset = URI.decode_www_form_component(value)
33
- when "trace_id"
34
- trace_id = value
35
- when "parent_id"
36
- parent_span_id = value
37
- when "context"
38
- Base64.decode64(value).tap do |json|
39
- begin
40
- trace_fields = JSON.parse json
41
- rescue JSON::ParserError
42
- trace_fields = {}
43
- end
44
- end
45
- end
46
- end
47
-
48
- [trace_id, parent_span_id, trace_fields, dataset]
49
- end
12
+ include HoneycombPropagation::UnmarshalTraceContext
50
13
  end
51
14
 
52
15
  # Serialize trace headers
53
16
  module PropagationSerializer
54
- def to_trace_header
55
- context = Base64.urlsafe_encode64(JSON.generate(trace.fields)).strip
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(',')}"
64
- end
17
+ include HoneycombPropagation::MarshalTraceContext
65
18
  end
66
19
  end