honeycomb-beeline 2.8.2 → 2.9.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/.rubocop.yml +4 -0
- data/CHANGELOG.md +6 -0
- data/lib/generators/honeycomb/honeycomb_generator.rb +2 -2
- data/lib/honeycomb/beeline/version.rb +1 -1
- data/lib/honeycomb/client.rb +7 -0
- data/lib/honeycomb/configuration.rb +59 -5
- data/lib/honeycomb/context.rb +5 -0
- data/lib/honeycomb/propagation/default_modern.rb +29 -0
- data/lib/honeycomb/propagation/honeycomb_modern.rb +89 -0
- data/lib/honeycomb/propagation/w3c.rb +2 -6
- data/lib/honeycomb/trace.rb +11 -5
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2dd1c8587f1aaa8ca239aa4a526f1be4aea49814f3c92134a9dd59ecdb79f4dc
|
4
|
+
data.tar.gz: cc1e21f4d0e2d5e65d58502196fd74eb862d5890b577f789875b4427c66c2d0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53765870c5c3d5b2eda2992e472f270412548a0f5f71e5ed36fa005129d9ae831bbb1ad19903797c558909fc9d2e93e42002d0d15fba05756fa4a785064f1eb9
|
7
|
+
data.tar.gz: c3be19aed350b937ff3ec4d9789861f609afc490f16670c370d9a60f263eea4759198ce4a93ec3802cd42948abc87745f1a8b06cd0c56c4f1fcfe8b6a25a31a4
|
data/.rubocop.yml
CHANGED
@@ -26,6 +26,7 @@ Metrics/MethodLength:
|
|
26
26
|
- lib/generators/honeycomb/honeycomb_generator.rb
|
27
27
|
|
28
28
|
Metrics/LineLength:
|
29
|
+
Max: 100
|
29
30
|
Exclude:
|
30
31
|
- spec/honeycomb/integrations/active_support_spec.rb
|
31
32
|
- spec/support/event_data_shared_examples.rb
|
@@ -71,3 +72,6 @@ Style/AsciiComments:
|
|
71
72
|
|
72
73
|
Style/Alias:
|
73
74
|
EnforcedStyle: prefer_alias_method
|
75
|
+
|
76
|
+
Style/IfUnlessModifier:
|
77
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -11,7 +11,7 @@ class HoneycombGenerator < Rails::Generators::Base
|
|
11
11
|
|
12
12
|
argument :write_key, required: true, desc: "required"
|
13
13
|
|
14
|
-
class_option :
|
14
|
+
class_option :service_name, type: :string, default: "rails"
|
15
15
|
|
16
16
|
gem "honeycomb-beeline"
|
17
17
|
|
@@ -22,7 +22,7 @@ class HoneycombGenerator < Rails::Generators::Base
|
|
22
22
|
<<-RUBY.strip_heredoc
|
23
23
|
Honeycomb.configure do |config|
|
24
24
|
config.write_key = #{write_key.inspect}
|
25
|
-
config.
|
25
|
+
config.service_name = #{options['service_name'].inspect}
|
26
26
|
config.presend_hook do |fields|
|
27
27
|
if fields["name"] == "redis" && fields.has_key?("redis.command")
|
28
28
|
# remove potential PII from the redis command
|
data/lib/honeycomb/client.rb
CHANGED
@@ -30,8 +30,11 @@ module Honeycomb
|
|
30
30
|
|
31
31
|
# maybe make `service_name` a required parameter
|
32
32
|
@libhoney.add_field "service_name", configuration.service_name
|
33
|
+
@libhoney.add_field "service.name", configuration.service_name
|
33
34
|
@context = Context.new
|
34
35
|
|
36
|
+
@context.classic = classic_write_key?(configuration.write_key)
|
37
|
+
|
35
38
|
@additional_trace_options = {
|
36
39
|
presend_hook: configuration.presend_hook,
|
37
40
|
sample_hook: configuration.sample_hook,
|
@@ -125,5 +128,9 @@ module Honeycomb
|
|
125
128
|
span.add_field("error_backtrace_limit", error_backtrace_limit)
|
126
129
|
span.add_field("error_backtrace_total_length", exception.backtrace.length)
|
127
130
|
end
|
131
|
+
|
132
|
+
def classic_write_key?(write_key)
|
133
|
+
write_key.nil? || write_key.length == 32
|
134
|
+
end
|
128
135
|
end
|
129
136
|
end
|
@@ -2,16 +2,16 @@
|
|
2
2
|
|
3
3
|
require "socket"
|
4
4
|
require "honeycomb/propagation/default"
|
5
|
+
require "honeycomb/propagation/default_modern"
|
5
6
|
|
6
7
|
module Honeycomb
|
7
8
|
# Used to configure the Honeycomb client
|
8
9
|
class Configuration
|
9
10
|
attr_accessor :write_key,
|
10
|
-
:dataset,
|
11
11
|
:api_host,
|
12
12
|
:debug
|
13
13
|
|
14
|
-
attr_writer :service_name, :client, :host_name
|
14
|
+
attr_writer :service_name, :client, :host_name, :dataset
|
15
15
|
attr_reader :error_backtrace_limit
|
16
16
|
|
17
17
|
def initialize
|
@@ -23,8 +23,31 @@ module Honeycomb
|
|
23
23
|
@client = nil
|
24
24
|
end
|
25
25
|
|
26
|
+
def classic?
|
27
|
+
@write_key.nil? || @write_key.length == 32
|
28
|
+
end
|
29
|
+
|
26
30
|
def service_name
|
27
|
-
@service_name
|
31
|
+
return @service_name if service_name_given?
|
32
|
+
return @dataset if classic?
|
33
|
+
|
34
|
+
"unknown_service:" + $PROGRAM_NAME.split("/").last
|
35
|
+
end
|
36
|
+
|
37
|
+
def dataset
|
38
|
+
return @dataset if classic?
|
39
|
+
return "unknown_service" if service_name.nil?
|
40
|
+
|
41
|
+
stripped_service_name = service_name.strip
|
42
|
+
|
43
|
+
warn("found extra whitespace in service name") if stripped_service_name != service_name
|
44
|
+
|
45
|
+
if stripped_service_name.empty? || stripped_service_name.start_with?("unknown_service")
|
46
|
+
# don't use process name in dataset
|
47
|
+
"unknown_service"
|
48
|
+
else
|
49
|
+
stripped_service_name
|
50
|
+
end
|
28
51
|
end
|
29
52
|
|
30
53
|
def error_backtrace_limit=(val)
|
@@ -39,6 +62,7 @@ module Honeycomb
|
|
39
62
|
if debug
|
40
63
|
Libhoney::LogClient.new
|
41
64
|
else
|
65
|
+
validate_options
|
42
66
|
Libhoney::Client.new(**libhoney_client_options)
|
43
67
|
end
|
44
68
|
end
|
@@ -73,9 +97,11 @@ module Honeycomb
|
|
73
97
|
@http_trace_parser_hook = hook
|
74
98
|
elsif @http_trace_parser_hook
|
75
99
|
@http_trace_parser_hook
|
100
|
+
elsif classic?
|
101
|
+
DefaultPropagation::UnmarshalTraceContext.method(:parse_rack_env)
|
76
102
|
else
|
77
103
|
# by default we try to parse incoming honeycomb traces
|
78
|
-
|
104
|
+
DefaultModernPropagation::UnmarshalTraceContext.method(:parse_rack_env)
|
79
105
|
end
|
80
106
|
end
|
81
107
|
|
@@ -84,9 +110,11 @@ module Honeycomb
|
|
84
110
|
@http_trace_propagation_hook = hook
|
85
111
|
elsif @http_trace_propagation_hook
|
86
112
|
@http_trace_propagation_hook
|
113
|
+
elsif classic?
|
114
|
+
HoneycombPropagation::MarshalTraceContext.method(:parse_faraday_env)
|
87
115
|
else
|
88
116
|
# by default we send outgoing honeycomb trace headers
|
89
|
-
|
117
|
+
HoneycombModernPropagation::MarshalTraceContext.method(:parse_faraday_env)
|
90
118
|
end
|
91
119
|
end
|
92
120
|
|
@@ -102,5 +130,31 @@ module Honeycomb
|
|
102
130
|
options[:api_host] = api_host if api_host
|
103
131
|
end
|
104
132
|
end
|
133
|
+
|
134
|
+
def validate_options
|
135
|
+
warn("missing write_key") if write_key.nil? || write_key.empty?
|
136
|
+
if classic?
|
137
|
+
validate_options_classic
|
138
|
+
else
|
139
|
+
warn("service_name is unknown, will set to " + service_name) \
|
140
|
+
if service_name.start_with?("unknown_service")
|
141
|
+
warn("dataset will be ignored, sending data to " + service_name) \
|
142
|
+
if dataset_given?
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
def validate_options_classic
|
147
|
+
warn("empty service_name option") unless service_name_given?
|
148
|
+
warn("empty dataset option") unless dataset_given?
|
149
|
+
end
|
150
|
+
|
151
|
+
def service_name_given?
|
152
|
+
# check the instance variables, not the accessor method
|
153
|
+
@service_name && !@service_name.empty?
|
154
|
+
end
|
155
|
+
|
156
|
+
def dataset_given?
|
157
|
+
@dataset && !@dataset.empty?
|
158
|
+
end
|
105
159
|
end
|
106
160
|
end
|
data/lib/honeycomb/context.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
module Honeycomb
|
4
4
|
# Stores the current span and trace context
|
5
5
|
class Context
|
6
|
+
attr_writer :classic
|
6
7
|
def current_trace
|
7
8
|
return if current_span.nil?
|
8
9
|
|
@@ -23,6 +24,10 @@ module Honeycomb
|
|
23
24
|
spans.pop
|
24
25
|
end
|
25
26
|
|
27
|
+
def classic?
|
28
|
+
@classic
|
29
|
+
end
|
30
|
+
|
26
31
|
private
|
27
32
|
|
28
33
|
def spans
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "honeycomb/propagation/honeycomb_modern"
|
4
|
+
require "honeycomb/propagation/w3c"
|
5
|
+
|
6
|
+
module Honeycomb
|
7
|
+
# Default behavior for handling trace propagation
|
8
|
+
module DefaultModernPropagation
|
9
|
+
# Parse incoming trace headers.
|
10
|
+
#
|
11
|
+
# Checks for and parses Honeycomb's trace header or, if not found,
|
12
|
+
# then checks for and parses W3C trace parent header.
|
13
|
+
module UnmarshalTraceContext
|
14
|
+
def parse_rack_env(env)
|
15
|
+
if env["HTTP_X_HONEYCOMB_TRACE"]
|
16
|
+
HoneycombModernPropagation::UnmarshalTraceContext.parse_rack_env env
|
17
|
+
elsif env["HTTP_TRACEPARENT"]
|
18
|
+
W3CPropagation::UnmarshalTraceContext.parse_rack_env env
|
19
|
+
else
|
20
|
+
[nil, nil, nil, nil]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
# rubocop:disable Style/AccessModifierDeclarations
|
24
|
+
module_function :parse_rack_env
|
25
|
+
public :parse_rack_env
|
26
|
+
# rubocop:enable Style/AccessModifierDeclarations
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "base64"
|
4
|
+
require "json"
|
5
|
+
require "uri"
|
6
|
+
|
7
|
+
module Honeycomb
|
8
|
+
# Parsing and propagation for honeycomb trace headers
|
9
|
+
module HoneycombModernPropagation
|
10
|
+
# Parse trace headers
|
11
|
+
module UnmarshalTraceContext
|
12
|
+
def parse_rack_env(env)
|
13
|
+
parse env["HTTP_X_HONEYCOMB_TRACE"]
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse(serialized_trace)
|
17
|
+
unless serialized_trace.nil?
|
18
|
+
version, payload = serialized_trace.split(";", 2)
|
19
|
+
|
20
|
+
if version == "1"
|
21
|
+
trace_id, parent_span_id, trace_fields = parse_v1(payload)
|
22
|
+
|
23
|
+
if !trace_id.nil? && !parent_span_id.nil?
|
24
|
+
return [trace_id, parent_span_id, trace_fields, nil]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
[nil, nil, nil, nil]
|
30
|
+
end
|
31
|
+
|
32
|
+
def parse_v1(payload)
|
33
|
+
trace_id, parent_span_id, trace_fields = nil
|
34
|
+
payload.split(",").each do |entry|
|
35
|
+
key, value = entry.split("=", 2)
|
36
|
+
case key.downcase
|
37
|
+
when "trace_id"
|
38
|
+
trace_id = value
|
39
|
+
when "parent_id"
|
40
|
+
parent_span_id = value
|
41
|
+
when "context"
|
42
|
+
Base64.decode64(value).tap do |json|
|
43
|
+
begin
|
44
|
+
trace_fields = JSON.parse json
|
45
|
+
rescue JSON::ParserError
|
46
|
+
trace_fields = {}
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
[trace_id, parent_span_id, trace_fields, nil]
|
53
|
+
end
|
54
|
+
|
55
|
+
module_function :parse_rack_env, :parse, :parse_v1
|
56
|
+
public :parse_rack_env, :parse
|
57
|
+
end
|
58
|
+
|
59
|
+
# Serialize trace headers
|
60
|
+
module MarshalTraceContext
|
61
|
+
def to_trace_header
|
62
|
+
context = Base64.urlsafe_encode64(JSON.generate(trace.fields)).strip
|
63
|
+
data_to_propogate = [
|
64
|
+
"trace_id=#{trace.id}",
|
65
|
+
"parent_id=#{id}",
|
66
|
+
"context=#{context}",
|
67
|
+
]
|
68
|
+
"1;#{data_to_propogate.join(',')}"
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.parse_faraday_env(_env, propagation_context)
|
72
|
+
{
|
73
|
+
"X-Honeycomb-Trace" => to_trace_header(propagation_context),
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.to_trace_header(propagation_context)
|
78
|
+
fields = propagation_context.trace_fields
|
79
|
+
context = Base64.urlsafe_encode64(JSON.generate(fields)).strip
|
80
|
+
data_to_propogate = [
|
81
|
+
"trace_id=#{propagation_context.trace_id}",
|
82
|
+
"parent_id=#{propagation_context.parent_id}",
|
83
|
+
"context=#{context}",
|
84
|
+
]
|
85
|
+
"1;#{data_to_propogate.join(',')}"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
@@ -31,12 +31,8 @@ module Honeycomb
|
|
31
31
|
def parse_v1(payload)
|
32
32
|
trace_id, parent_span_id, trace_flags = payload.split("-", 3)
|
33
33
|
|
34
|
-
if trace_flags
|
35
|
-
|
36
|
-
return [nil, nil]
|
37
|
-
end
|
38
|
-
|
39
|
-
if trace_id == INVALID_TRACE_ID || parent_span_id == INVALID_SPAN_ID
|
34
|
+
# if trace_flags is nil, it means a field is missing
|
35
|
+
if trace_flags.nil? || trace_id == INVALID_TRACE_ID || parent_span_id == INVALID_SPAN_ID
|
40
36
|
return [nil, nil]
|
41
37
|
end
|
42
38
|
|
data/lib/honeycomb/trace.rb
CHANGED
@@ -9,7 +9,6 @@ require "honeycomb/rollup_fields"
|
|
9
9
|
module Honeycomb
|
10
10
|
# Represents a Honeycomb trace, which groups spans together
|
11
11
|
class Trace
|
12
|
-
include PropagationParser
|
13
12
|
include RollupFields
|
14
13
|
extend Forwardable
|
15
14
|
|
@@ -19,9 +18,14 @@ module Honeycomb
|
|
19
18
|
|
20
19
|
def initialize(builder:, context:, serialized_trace: nil, **options)
|
21
20
|
trace_id, parent_span_id, trace_fields, dataset =
|
22
|
-
internal_parse(serialized_trace: serialized_trace, **options)
|
21
|
+
internal_parse(context: context, serialized_trace: serialized_trace, **options)
|
22
|
+
|
23
|
+
# if dataset is not nil,
|
24
|
+
# set trace's builder.dataset = dataset from trace header
|
25
|
+
if context.classic?
|
26
|
+
dataset && builder.dataset = dataset
|
27
|
+
end
|
23
28
|
|
24
|
-
dataset && builder.dataset = dataset
|
25
29
|
@id = trace_id || generate_trace_id
|
26
30
|
@fields = trace_fields || {}
|
27
31
|
@root_span = Span.new(trace: self,
|
@@ -47,15 +51,17 @@ module Honeycomb
|
|
47
51
|
end
|
48
52
|
end
|
49
53
|
|
50
|
-
def internal_parse(serialized_trace: nil, parser_hook: nil, **_options)
|
54
|
+
def internal_parse(context:, serialized_trace: nil, parser_hook: nil, **_options)
|
51
55
|
# previously we passed in the header directly as a string for us to parse
|
52
56
|
# now we get passed the rack env to use as an argument to the provided
|
53
57
|
# parser_hook. This preserves the current behaviour and allows us to
|
54
58
|
# move forward with the new behaviour without breaking changes
|
55
59
|
if serialized_trace.is_a?(Hash) && parser_hook
|
56
60
|
parser_hook.call(serialized_trace)
|
61
|
+
elsif context.classic?
|
62
|
+
HoneycombPropagation::UnmarshalTraceContext.parse serialized_trace
|
57
63
|
else
|
58
|
-
parse serialized_trace
|
64
|
+
HoneycombModernPropagation::UnmarshalTraceContext.parse serialized_trace
|
59
65
|
end
|
60
66
|
end
|
61
67
|
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: 2.
|
4
|
+
version: 2.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Holman
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-03-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: libhoney
|
@@ -288,7 +288,9 @@ files:
|
|
288
288
|
- lib/honeycomb/propagation/aws.rb
|
289
289
|
- lib/honeycomb/propagation/context.rb
|
290
290
|
- lib/honeycomb/propagation/default.rb
|
291
|
+
- lib/honeycomb/propagation/default_modern.rb
|
291
292
|
- lib/honeycomb/propagation/honeycomb.rb
|
293
|
+
- lib/honeycomb/propagation/honeycomb_modern.rb
|
292
294
|
- lib/honeycomb/propagation/w3c.rb
|
293
295
|
- lib/honeycomb/rollup_fields.rb
|
294
296
|
- lib/honeycomb/span.rb
|