bc-lightstep-ruby 2.0.0 → 2.2.2
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/CHANGELOG.md +19 -0
- data/README.md +21 -2
- data/bc-lightstep-ruby.gemspec +6 -5
- data/lib/bigcommerce/lightstep.rb +13 -1
- data/lib/bigcommerce/lightstep/active_record/adapter.rb +117 -0
- data/lib/bigcommerce/lightstep/active_record/tracer.rb +83 -0
- data/lib/bigcommerce/lightstep/configuration.rb +22 -30
- data/lib/bigcommerce/lightstep/interceptors/env.rb +1 -0
- data/lib/bigcommerce/lightstep/middleware/faraday.rb +1 -1
- data/lib/bigcommerce/lightstep/tracer.rb +18 -2
- data/lib/bigcommerce/lightstep/transport.rb +37 -18
- data/lib/bigcommerce/lightstep/transport_factory.rb +4 -0
- data/lib/bigcommerce/lightstep/version.rb +1 -1
- metadata +37 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f3a1bf19d2bd647344092637b395c79889582497e7505fe88a15e54ca490f49
|
4
|
+
data.tar.gz: 3dd48770cacc6e088edcbb63e26a9da3954b5112cc840890d79df3285c73b3b0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d8849b91e102c4ad4cac2272368d19b8f523f3195b280f9a7007344135c436ca9f7f0e44a0a0403dc4f1ea854a5de27e001d96eb96b40498d28ce63280f3501
|
7
|
+
data.tar.gz: 4fe13e2093848bba17236988b49649fbeeba3291f4c545d0732e7b4b79182c855719dcc7363f36e39141ff895976047fb369560abaaf328c688df2b426855dba
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,25 @@ Changelog for the bc-lightstep-ruby gem.
|
|
2
2
|
|
3
3
|
### Pending Release
|
4
4
|
|
5
|
+
### 2.2.2
|
6
|
+
|
7
|
+
- Fix issue where parent span determination can be nil if lightstep is not initialized
|
8
|
+
- Add tests for Ruby 2.7
|
9
|
+
|
10
|
+
### 2.2.1
|
11
|
+
|
12
|
+
- Only set error tag in exceptions if not already set
|
13
|
+
- Update to Rubocop 1.0
|
14
|
+
|
15
|
+
### 2.1.1
|
16
|
+
|
17
|
+
- Bump lightstep gem to 0.16.0
|
18
|
+
- Bump faraday gem to <= 0.17.3
|
19
|
+
|
20
|
+
### 2.1.0
|
21
|
+
|
22
|
+
- Add support for automatically-generated mysql spans in tracing
|
23
|
+
|
5
24
|
### 2.0.0
|
6
25
|
|
7
26
|
- Drop support for Ruby < 2.6
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# bc-lightstep-ruby - LightStep distributed tracing
|
2
2
|
|
3
|
-
[](https://circleci.com/gh/bigcommerce/bc-lightstep-ruby/tree/main) [](https://badge.fury.io/rb/bc-lightstep-ruby) [](http://inch-ci.org/github/bigcommerce/bc-lightstep-ruby)
|
4
4
|
|
5
5
|
Adds [LightStep](https://lightstep.com) tracing support for Ruby. This is an extension of the
|
6
6
|
[LightStep ruby gem](https://github.com/lightstep/lightstep-tracer-ruby) and adds extra functionality and resiliency.
|
@@ -45,10 +45,18 @@ bc-lightstep-ruby can be automatically configured from these ENV vars, if you'd
|
|
45
45
|
| LIGHTSTEP_ACCESS_TOKEN | The access token to use to connect to the collector. Optional. | '' |
|
46
46
|
| LIGHTSTEP_HOST | Host of the collector. | `lightstep-collector.linkerd` |
|
47
47
|
| LIGHTSTEP_PORT | Port of the collector. | `4140` |
|
48
|
+
| LIGHTSTEP_HTTP1_ERROR_CODE | The HTTP error code to report in spans for internal errors | 500 |
|
49
|
+
| LIGHTSTEP_HTTP1_ERROR_CODE_MINIMUM | The minimum HTTP error code value to be considered an error for span tag purposes. | 500 |
|
50
|
+
| LIGHTSTEP_CONTROLLER_PREFIX | The prefix for Rails controllers to use | `controllers.` |
|
48
51
|
| LIGHTSTEP_SSL_VERIFY_PEER | If using 443 as the port, toggle SSL verification. | true |
|
49
52
|
| LIGHTSTEP_MAX_BUFFERED_SPANS | The maximum number of spans to buffer before dropping. | `1_000` |
|
50
53
|
| LIGHTSTEP_MAX_LOG_RECORDS | Maximum number of log records on a span to accept. | `1_000` |
|
51
54
|
| LIGHTSTEP_MAX_REPORTING_INTERVAL_SECONDS | The maximum number of seconds to wait before flushing the report to the collector. | 3.0 |
|
55
|
+
| LIGHTSTEP_ACTIVE_RECORD_ENABLED | Whether or not to add ActiveRecord mysql spans. Only works with mysql2 gem. | 1 |
|
56
|
+
| LIGHTSTEP_ACTIVE_RECORD_ALLOW_AS_ROOT_SPAN | Allow ActiveRecord mysql spans to be the root span? | 0 |
|
57
|
+
| LIGHTSTEP_ACTIVE_RECORD_SPAN_PREFIX | What to prefix the ActiveRecord mysql span with | '' |
|
58
|
+
| LIGHTSTEP_REDIS_ALLOW_AS_ROOT_SPAN | Allow redis to be the root span? | 0 |
|
59
|
+
| LIGHTSTEP_REDIS_EXCLUDED_COMMANDS | Redis commands to exclude from spans. Comma-separated list. | ping |
|
52
60
|
| LIGHTSTEP_VERBOSITY | The verbosity level of lightstep logs. | 1 |
|
53
61
|
|
54
62
|
Most systems will only need to customize the component name.
|
@@ -77,7 +85,7 @@ or systems outside of your instrumenting control.
|
|
77
85
|
|
78
86
|
### Redis
|
79
87
|
|
80
|
-
This gem will automatically detect and
|
88
|
+
This gem will automatically detect and instrument Redis calls when they are made using the `Redis::Client` class.
|
81
89
|
It will set as tags on the span the host, port, db instance, and the command (but no arguments).
|
82
90
|
|
83
91
|
Note that this will not record redis timings if they are a root span. This is to prevent trace spamming. You can
|
@@ -86,6 +94,17 @@ re-enable this by setting the `redis_allow_root_spans` configuration option to `
|
|
86
94
|
It also excludes `ping` commands, and you can provide a custom list by setting the `redis_excluded_commands`
|
87
95
|
configuration option to an array of commands to exclude.
|
88
96
|
|
97
|
+
### ActiveRecord and MySQL
|
98
|
+
|
99
|
+
This gem will automatically instrument MySQL queries with spans when made with the `mysql2` gem and ActiveRecord.
|
100
|
+
It will set as tags on the span the host, database type, database name, and a sanitized version of the SQL query made.
|
101
|
+
The query will have no values - replaced with `?` - to ensure secure logging and no leaking of PII data.
|
102
|
+
|
103
|
+
Note that this will not record mysql timings if they are a root span. This is to prevent trace spamming. You can
|
104
|
+
configure this gem to allow it via ENV, but it is not recommended.
|
105
|
+
|
106
|
+
By default, it will also exclude `COMMIT`, `SCHEMA`, and `SHOW FULL FIELDS` queries.
|
107
|
+
|
89
108
|
## RSpec
|
90
109
|
|
91
110
|
This library comes with a built-in matcher for testing span blocks. In your rspec config:
|
data/bc-lightstep-ruby.gemspec
CHANGED
@@ -33,18 +33,19 @@ Gem::Specification.new do |spec|
|
|
33
33
|
spec.require_paths = ['lib']
|
34
34
|
spec.required_ruby_version = '>= 2.6'
|
35
35
|
|
36
|
-
spec.add_development_dependency '
|
36
|
+
spec.add_development_dependency 'activerecord', '> 4'
|
37
37
|
spec.add_development_dependency 'bundler-audit', '~> 0.6'
|
38
|
-
spec.add_development_dependency 'rake', '
|
38
|
+
spec.add_development_dependency 'rake', '>= 12.0'
|
39
39
|
spec.add_development_dependency 'rspec', '~> 3.8'
|
40
40
|
spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4'
|
41
|
-
spec.add_development_dependency 'rubocop', '~> 0
|
41
|
+
spec.add_development_dependency 'rubocop', '~> 1.0'
|
42
42
|
spec.add_development_dependency 'simplecov', '~> 0.15'
|
43
43
|
spec.add_development_dependency 'pry', '>= 0.12'
|
44
44
|
|
45
45
|
spec.add_development_dependency 'null-logger', '~> 0.1'
|
46
46
|
spec.add_development_dependency 'redis', '~> 4'
|
47
47
|
|
48
|
-
spec.add_runtime_dependency '
|
49
|
-
spec.add_runtime_dependency '
|
48
|
+
spec.add_runtime_dependency 'activesupport', '>= 4'
|
49
|
+
spec.add_runtime_dependency 'lightstep', '~> 0.16.0'
|
50
|
+
spec.add_runtime_dependency 'faraday', ['>= 0.8', '<= 0.17.3']
|
50
51
|
end
|
@@ -17,6 +17,7 @@
|
|
17
17
|
#
|
18
18
|
require 'lightstep'
|
19
19
|
require 'faraday'
|
20
|
+
require 'active_support/concern'
|
20
21
|
require_relative 'lightstep/version'
|
21
22
|
require_relative 'lightstep/errors'
|
22
23
|
require_relative 'lightstep/interceptors/registry'
|
@@ -27,6 +28,8 @@ require_relative 'lightstep/transport_factory'
|
|
27
28
|
require_relative 'lightstep/transport'
|
28
29
|
require_relative 'lightstep/rails_controller_instrumentation'
|
29
30
|
require_relative 'lightstep/middleware/faraday'
|
31
|
+
require_relative 'lightstep/active_record/tracer'
|
32
|
+
require_relative 'lightstep/active_record/adapter'
|
30
33
|
require_relative 'lightstep/redis/tracer'
|
31
34
|
|
32
35
|
##
|
@@ -39,6 +42,12 @@ module Bigcommerce
|
|
39
42
|
module Lightstep
|
40
43
|
extend Configuration
|
41
44
|
|
45
|
+
##
|
46
|
+
# Start the global tracer and configure LightStep
|
47
|
+
#
|
48
|
+
# @param [String] component_name
|
49
|
+
# @param [::Bigcommerce::Lightstep::TransportFactory] transport_factory
|
50
|
+
#
|
42
51
|
def self.start(component_name: nil, transport_factory: nil)
|
43
52
|
component_name ||= ::Bigcommerce::Lightstep.component_name
|
44
53
|
transport_factory ||= ::Bigcommerce::Lightstep::TransportFactory.new
|
@@ -54,7 +63,10 @@ module Bigcommerce
|
|
54
63
|
::LightStep.instance.max_log_records = ::Bigcommerce::Lightstep.max_log_records
|
55
64
|
::LightStep.instance.report_period_seconds = ::Bigcommerce::Lightstep.max_reporting_interval_seconds
|
56
65
|
|
57
|
-
|
66
|
+
return unless ::Bigcommerce::Lightstep.enabled
|
67
|
+
|
68
|
+
::Bigcommerce::Lightstep::Redis::Wrapper.patch
|
69
|
+
::Bigcommerce::Lightstep::ActiveRecord::Adapter.patch
|
58
70
|
end
|
59
71
|
end
|
60
72
|
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2020-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
module Bigcommerce
|
19
|
+
module Lightstep
|
20
|
+
module ActiveRecord
|
21
|
+
##
|
22
|
+
# Patches mysql and ActiveRecord to allow for mysql span tracing
|
23
|
+
#
|
24
|
+
module Adapter
|
25
|
+
extend ::ActiveSupport::Concern
|
26
|
+
|
27
|
+
##
|
28
|
+
# Patch ActiveRecord to enable mysql span traces
|
29
|
+
#
|
30
|
+
def self.patch
|
31
|
+
return unless enabled?
|
32
|
+
|
33
|
+
# rubocop:disable Lint/SendWithMixinArgument
|
34
|
+
::ActiveRecord::ConnectionAdapters::Mysql2Adapter.send(:include, ::Bigcommerce::Lightstep::ActiveRecord::Adapter)
|
35
|
+
# rubocop:enable Lint/SendWithMixinArgument
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Note: we only support patching mysql2 gem at this point
|
40
|
+
#
|
41
|
+
# @return [Boolean]
|
42
|
+
#
|
43
|
+
def self.enabled?
|
44
|
+
defined?(::ActiveRecord) && ::Bigcommerce::Lightstep.active_record && ::ActiveRecord::Base.connection_config[:adapter].to_s.downcase == 'mysql2'
|
45
|
+
rescue StandardError => e
|
46
|
+
::Bigcommerce::Lightstep.logger&.warn "Failed to determine ActiveRecord database adapter in bc-lightstep-ruby initializer: #{e.message}"
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# @param [String] sql The raw sql query
|
52
|
+
# @param [String] name The type of sql query
|
53
|
+
#
|
54
|
+
def execute_with_inst(sql, name = 'SQL')
|
55
|
+
# bail out early if not enabled. This should not get here, but is provided as a failsafe.
|
56
|
+
return execute_without_inst(sql, name) unless ::Bigcommerce::Lightstep.active_record
|
57
|
+
|
58
|
+
sanitized_sql = lightstep_sanitize_sql(sql)
|
59
|
+
name = name.to_s.strip.empty? ? 'QUERY' : name
|
60
|
+
|
61
|
+
# we dont need to track all sql
|
62
|
+
return execute_without_inst(sql, name) if lightstep_skip_tracing?(name, sanitized_sql)
|
63
|
+
|
64
|
+
lightstep_tracer.db_trace(
|
65
|
+
statement: sanitized_sql,
|
66
|
+
host: @config[:host],
|
67
|
+
adapter: @config[:adapter],
|
68
|
+
database: @config[:database]
|
69
|
+
) do
|
70
|
+
execute_without_inst(sql, name)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# Sanitize the sql for safe logging
|
76
|
+
#
|
77
|
+
# @param [String]
|
78
|
+
# @return [String]
|
79
|
+
#
|
80
|
+
def lightstep_sanitize_sql(sql)
|
81
|
+
sql.to_s.gsub(lightstep_sanitization_regexp, '?').tr("\n", ' ').to_s
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# @return [Regexp]
|
86
|
+
#
|
87
|
+
def lightstep_sanitization_regexp
|
88
|
+
@lightstep_sanitization_regexp ||= ::Regexp.new('(\'[\s\S][^\']*\'|\d*\.\d+|\d+|NULL)', ::Regexp::IGNORECASE)
|
89
|
+
end
|
90
|
+
|
91
|
+
##
|
92
|
+
# Filter out sql queries from tracing we don't care about
|
93
|
+
#
|
94
|
+
# @param [String] name
|
95
|
+
# @param [String] sql
|
96
|
+
# @return [Boolean]
|
97
|
+
def lightstep_skip_tracing?(name, sql)
|
98
|
+
name.empty? || sql.empty? || sql.include?('COMMIT') || sql.include?('SCHEMA') || sql.include?('SHOW FULL FIELDS')
|
99
|
+
end
|
100
|
+
|
101
|
+
##
|
102
|
+
# @return [::Bigcommerce::Lightstep::ActiveRecord::Tracer]
|
103
|
+
#
|
104
|
+
def lightstep_tracer
|
105
|
+
@lightstep_tracer ||= ::Bigcommerce::Lightstep::ActiveRecord::Tracer.new
|
106
|
+
end
|
107
|
+
|
108
|
+
included do
|
109
|
+
if defined?(::ActiveRecord) && ::ActiveRecord::VERSION::MAJOR > 3
|
110
|
+
alias_method :execute_without_inst, :execute
|
111
|
+
alias_method :execute, :execute_with_inst
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2020-present, BigCommerce Pty. Ltd. All rights reserved
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
|
6
|
+
# documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
|
7
|
+
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
|
8
|
+
# persons to whom the Software is furnished to do so, subject to the following conditions:
|
9
|
+
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
|
11
|
+
# Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
|
14
|
+
# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
15
|
+
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
16
|
+
# OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
17
|
+
#
|
18
|
+
module Bigcommerce
|
19
|
+
module Lightstep
|
20
|
+
module ActiveRecord
|
21
|
+
##
|
22
|
+
# Tracer adapter for ActiveRecord
|
23
|
+
#
|
24
|
+
class Tracer
|
25
|
+
##
|
26
|
+
# @param [Bigcommerce::Lightstep::Tracer] tracer
|
27
|
+
# @param [String] span_prefix
|
28
|
+
# @param [Boolean] allow_root_spans
|
29
|
+
# @param [String] span_name
|
30
|
+
#
|
31
|
+
def initialize(tracer: nil, span_prefix: nil, span_name: nil, allow_root_spans: nil)
|
32
|
+
@tracer = tracer || ::Bigcommerce::Lightstep::Tracer.instance
|
33
|
+
@span_prefix = span_prefix || ::Bigcommerce::Lightstep.active_record_span_prefix
|
34
|
+
@span_name = span_name || 'mysql'
|
35
|
+
@allow_root_spans = !allow_root_spans.nil? ? allow_root_spans : ::Bigcommerce::Lightstep.active_record_allow_root_spans
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Trace a DB call
|
40
|
+
#
|
41
|
+
# @param [String] statement
|
42
|
+
# @param [String] host
|
43
|
+
# @param [String] adapter
|
44
|
+
# @param [String] database
|
45
|
+
#
|
46
|
+
def db_trace(statement:, host:, adapter:, database:)
|
47
|
+
return yield unless @tracer
|
48
|
+
|
49
|
+
# skip if not allowing root spans and there is no active span
|
50
|
+
return yield if !@allow_root_spans && !active_span?
|
51
|
+
|
52
|
+
@tracer.start_span(key) do |span|
|
53
|
+
span.set_tag('db.host', host.to_s)
|
54
|
+
span.set_tag('db.type', adapter.to_s)
|
55
|
+
span.set_tag('db.name', database.to_s)
|
56
|
+
span.set_tag('db.statement', statement.to_s)
|
57
|
+
span.set_tag('span.kind', 'client')
|
58
|
+
begin
|
59
|
+
yield
|
60
|
+
rescue StandardError => _e
|
61
|
+
span.set_tag('error', true)
|
62
|
+
raise # re-raise the error
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
##
|
68
|
+
# @return [String]
|
69
|
+
#
|
70
|
+
def key
|
71
|
+
!@span_prefix.to_s.empty? ? "#{@span_prefix}.mysql" : 'mysql'
|
72
|
+
end
|
73
|
+
|
74
|
+
##
|
75
|
+
# @return [Boolean]
|
76
|
+
#
|
77
|
+
def active_span?
|
78
|
+
@tracer.respond_to?(:active_span) && @tracer.active_span
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -23,27 +23,30 @@ module Bigcommerce
|
|
23
23
|
#
|
24
24
|
module Configuration
|
25
25
|
VALID_CONFIG_KEYS = {
|
26
|
-
component_name: '',
|
27
|
-
controller_trace_prefix: 'controllers.',
|
28
|
-
access_token: '',
|
29
|
-
host: 'lightstep-collector.linkerd',
|
26
|
+
component_name: ENV.fetch('LIGHTSTEP_COMPONENT_NAME', ''),
|
27
|
+
controller_trace_prefix: ENV.fetch('LIGHTSTEP_CONTROLLER_PREFIX', 'controllers.'),
|
28
|
+
access_token: ENV.fetch('LIGHTSTEP_ACCESS_TOKEN', ''),
|
29
|
+
host: ENV.fetch('LIGHTSTEP_HOST', 'lightstep-collector.linkerd'),
|
30
30
|
interceptors: nil,
|
31
|
-
port:
|
32
|
-
ssl_verify_peer:
|
33
|
-
open_timeout:
|
34
|
-
read_timeout:
|
31
|
+
port: ENV.fetch('LIGHTSTEP_PORT', 4_140).to_i,
|
32
|
+
ssl_verify_peer: ENV.fetch('LIGHTSTEP_SSL_VERIFY_PEER', 1).to_i.positive?,
|
33
|
+
open_timeout: ENV.fetch('LIGHTSTEP_OPEN_TIMEOUT', 2).to_i,
|
34
|
+
read_timeout: ENV.fetch('LIGHTSTEP_READ_TIMEOUT', 2).to_i,
|
35
35
|
continue_timeout: nil,
|
36
|
-
keep_alive_timeout: 2,
|
36
|
+
keep_alive_timeout: ENV.fetch('LIGHTSTEP_KEEP_ALIVE_TIMEOUT', 2).to_i,
|
37
37
|
logger: nil,
|
38
|
-
verbosity: 1,
|
39
|
-
http1_error_code: 500,
|
40
|
-
http1_error_code_minimum: 500,
|
41
|
-
max_buffered_spans: 1_000,
|
42
|
-
max_log_records: 1_000,
|
43
|
-
max_reporting_interval_seconds: 3.0,
|
44
|
-
redis_excluded_commands:
|
45
|
-
redis_allow_root_spans:
|
46
|
-
|
38
|
+
verbosity: ENV.fetch('LIGHTSTEP_VERBOSITY', 1).to_i,
|
39
|
+
http1_error_code: ENV.fetch('LIGHTSTEP_HTTP1_ERROR_CODE', 500).to_i,
|
40
|
+
http1_error_code_minimum: ENV.fetch('LIGHTSTEP_HTTP1_ERROR_CODE_MINIMUM', 500).to_i,
|
41
|
+
max_buffered_spans: ENV.fetch('LIGHTSTEP_MAX_BUFFERED_SPANS', 1_000).to_i,
|
42
|
+
max_log_records: ENV.fetch('LIGHTSTEP_MAX_LOG_RECORDS', 1_000).to_i,
|
43
|
+
max_reporting_interval_seconds: ENV.fetch('LIGHTSTEP_MAX_REPORTING_INTERVAL_SECONDS', 3.0).to_f,
|
44
|
+
redis_excluded_commands: ENV.fetch('LIGHTSTEP_REDIS_EXCLUDED_COMMANDS', 'ping').to_s.split(','),
|
45
|
+
redis_allow_root_spans: ENV.fetch('LIGHTSTEP_REDIS_ALLOW_AS_ROOT_SPAN', 0).to_i.positive?,
|
46
|
+
active_record: ENV.fetch('LIGHTSTEP_ACTIVE_RECORD_ENABLED', 1).to_i.positive?,
|
47
|
+
active_record_allow_root_spans: ENV.fetch('LIGHTSTEP_ACTIVE_RECORD_ALLOW_AS_ROOT_SPAN', 0).to_i.positive?,
|
48
|
+
active_record_span_prefix: ENV.fetch('LIGHTSTEP_ACTIVE_RECORD_SPAN_PREFIX', ''),
|
49
|
+
enabled: ENV.fetch('LIGHTSTEP_ENABLED', 1).to_i.positive?
|
47
50
|
}.freeze
|
48
51
|
|
49
52
|
attr_accessor *VALID_CONFIG_KEYS.keys
|
@@ -94,22 +97,11 @@ module Bigcommerce
|
|
94
97
|
VALID_CONFIG_KEYS.each do |k, v|
|
95
98
|
send("#{k}=".to_sym, v)
|
96
99
|
end
|
97
|
-
self.component_name = ENV.fetch('LIGHTSTEP_COMPONENT_NAME', '')
|
98
|
-
self.access_token = ENV.fetch('LIGHTSTEP_ACCESS_TOKEN', '')
|
99
|
-
self.host = ENV.fetch('LIGHTSTEP_HOST', 'lightstep-collector.linkerd')
|
100
|
-
self.port = ENV.fetch('LIGHTSTEP_PORT', 4140).to_i
|
101
|
-
self.ssl_verify_peer = ENV.fetch('LIGHTSTEP_SSL_VERIFY_PEER', true)
|
102
100
|
|
103
|
-
|
104
|
-
self.max_log_records = ENV.fetch('LIGHTSTEP_MAX_LOG_RECORDS', 1_000).to_i
|
105
|
-
self.max_reporting_interval_seconds = ENV.fetch('LIGHTSTEP_MAX_REPORTING_INTERVAL_SECONDS', 3.0).to_f
|
106
|
-
|
107
|
-
default_logger = ::Logger.new(STDOUT)
|
101
|
+
default_logger = ::Logger.new($stdout)
|
108
102
|
default_logger.level = ::Logger::INFO
|
109
103
|
self.logger = defined?(Rails) ? Rails.logger : default_logger
|
110
|
-
self.verbosity = ENV.fetch('LIGHTSTEP_VERBOSITY', 1).to_i
|
111
104
|
|
112
|
-
self.enabled = ENV.fetch('LIGHTSTEP_ENABLED', 1).to_i.positive?
|
113
105
|
self.interceptors = ::Bigcommerce::Lightstep::Interceptors::Registry.new
|
114
106
|
end
|
115
107
|
|
@@ -66,7 +66,7 @@ module Bigcommerce
|
|
66
66
|
result = yield inner_span
|
67
67
|
end
|
68
68
|
rescue StandardError
|
69
|
-
span.set_tag('error', true)
|
69
|
+
span.set_tag('error', true) unless span.tags.key?('error')
|
70
70
|
raise
|
71
71
|
ensure
|
72
72
|
# finish this span if the reporter is initialized
|
@@ -128,7 +128,7 @@ module Bigcommerce
|
|
128
128
|
def determine_parent(context:)
|
129
129
|
# first attempt to find parent from args, if not, use carrier (headers) to lookup parent
|
130
130
|
# 1 = FORMAT_TEXT_MAP (this constant is removed in future lightstep versions)
|
131
|
-
current_parent =
|
131
|
+
current_parent = extract_parent_from_context(context)
|
132
132
|
# if no passed in parent, use the active thread parent
|
133
133
|
current_parent = active_span if current_parent.nil?
|
134
134
|
current_parent
|
@@ -155,6 +155,22 @@ module Bigcommerce
|
|
155
155
|
def mark_root_span(span)
|
156
156
|
span.instance_variable_set(:@root_span, true)
|
157
157
|
end
|
158
|
+
|
159
|
+
##
|
160
|
+
# @param [Hash|::LightStep::SpanContext] context
|
161
|
+
# @return [::LightStep::SpanContext]
|
162
|
+
# @return [NilClass]
|
163
|
+
#
|
164
|
+
def extract_parent_from_context(context)
|
165
|
+
return context if context.is_a?(::LightStep::SpanContext)
|
166
|
+
|
167
|
+
tracer.extract(1, context || {})
|
168
|
+
rescue StandardError => _e
|
169
|
+
# sometimes LightStep, when `start` is not run first, will error here. This protects this until the upstream
|
170
|
+
# library can be fixed. We essentially just want to silently no-op here, as this failing simply means there's
|
171
|
+
# no context to extract.
|
172
|
+
nil
|
173
|
+
end
|
158
174
|
end
|
159
175
|
end
|
160
176
|
end
|
@@ -34,6 +34,22 @@ module Bigcommerce
|
|
34
34
|
LIGHTSTEP_PORT = 443
|
35
35
|
REPORTS_API_ENDPOINT = '/api/v0/reports'
|
36
36
|
|
37
|
+
DEFAULT_OPEN_TIMEOUT = 20
|
38
|
+
DEFAULT_READ_TIMEOUT = 20
|
39
|
+
DEFAULT_KEEPALIVE_TIMEOUT = 2
|
40
|
+
DEFAULT_SSL_PORT = 443
|
41
|
+
|
42
|
+
##
|
43
|
+
# Verbosity levels for the transport
|
44
|
+
#
|
45
|
+
class Verbosity
|
46
|
+
FATAL = 0
|
47
|
+
ERROR = 1
|
48
|
+
WARN = 2
|
49
|
+
INFO = 3
|
50
|
+
DEBUG = 4
|
51
|
+
end
|
52
|
+
|
37
53
|
# Initialize the transport
|
38
54
|
# @param host [String] host of the domain to the endpoind to push data
|
39
55
|
# @param port [Numeric] port on which to connect
|
@@ -44,31 +60,34 @@ module Bigcommerce
|
|
44
60
|
# @return [Transport]
|
45
61
|
def initialize(
|
46
62
|
access_token:,
|
47
|
-
host:
|
48
|
-
port:
|
49
|
-
verbose:
|
50
|
-
encryption:
|
63
|
+
host: nil,
|
64
|
+
port: nil,
|
65
|
+
verbose: nil,
|
66
|
+
encryption: nil,
|
51
67
|
ssl_verify_peer: true,
|
52
|
-
|
53
|
-
|
68
|
+
ssl_port: nil,
|
69
|
+
open_timeout: nil,
|
70
|
+
read_timeout: nil,
|
54
71
|
continue_timeout: nil,
|
55
|
-
keep_alive_timeout:
|
72
|
+
keep_alive_timeout: nil,
|
56
73
|
logger: nil
|
57
74
|
)
|
58
|
-
@host = host
|
59
|
-
@port = port
|
60
|
-
@verbose = verbose
|
61
|
-
@encryption = encryption
|
75
|
+
@host = host || LIGHTSTEP_HOST
|
76
|
+
@port = port || LIGHTSTEP_PORT
|
77
|
+
@verbose = verbose || Verbosity::FATAL
|
78
|
+
@encryption = encryption || ENCRYPTION_TLS
|
62
79
|
@ssl_verify_peer = ssl_verify_peer
|
63
|
-
@
|
64
|
-
@
|
80
|
+
@ssl_port = (ssl_port || DEFAULT_SSL_PORT).to_i
|
81
|
+
@open_timeout = (open_timeout || DEFAULT_OPEN_TIMEOUT).to_i
|
82
|
+
@read_timeout = (read_timeout || DEFAULT_READ_TIMEOUT).to_i
|
65
83
|
@continue_timeout = continue_timeout
|
66
|
-
@keep_alive_timeout = keep_alive_timeout.to_i
|
84
|
+
@keep_alive_timeout = (keep_alive_timeout || DEFAULT_KEEPALIVE_TIMEOUT).to_i
|
67
85
|
@access_token = access_token.to_s
|
68
86
|
|
69
|
-
default_logger = ::Logger.new(
|
87
|
+
default_logger = ::Logger.new($stdout)
|
70
88
|
default_logger.level = ::Logger::INFO
|
71
89
|
@logger = logger || default_logger
|
90
|
+
super()
|
72
91
|
end
|
73
92
|
|
74
93
|
##
|
@@ -78,12 +97,12 @@ module Bigcommerce
|
|
78
97
|
# @return [NilClass]
|
79
98
|
#
|
80
99
|
def report(report)
|
81
|
-
@logger.info report if @verbose >=
|
100
|
+
@logger.info report if @verbose >= Verbosity::INFO
|
82
101
|
|
83
102
|
req = build_request(report)
|
84
103
|
res = connection.request(req)
|
85
104
|
|
86
|
-
@logger.info res.to_s if @verbose >=
|
105
|
+
@logger.info res.to_s if @verbose >= Verbosity::INFO
|
87
106
|
|
88
107
|
nil
|
89
108
|
end
|
@@ -109,7 +128,7 @@ module Bigcommerce
|
|
109
128
|
def connection
|
110
129
|
unless @connection
|
111
130
|
@connection = ::Net::HTTP.new(@host, @port)
|
112
|
-
if @port ==
|
131
|
+
if @port == @ssl_port
|
113
132
|
@connection.use_ssl = @encryption == ENCRYPTION_TLS
|
114
133
|
@connection.verify_mode = ::OpenSSL::SSL::VERIFY_NONE unless @ssl_verify_peer
|
115
134
|
end
|
@@ -32,6 +32,10 @@ module Bigcommerce
|
|
32
32
|
encryption: ::Bigcommerce::Lightstep.port.to_i == 443 ? ::Bigcommerce::Lightstep::Transport::ENCRYPTION_TLS : ::Bigcommerce::Lightstep::Transport::ENCRYPTION_NONE,
|
33
33
|
ssl_verify_peer: ::Bigcommerce::Lightstep.ssl_verify_peer,
|
34
34
|
access_token: ::Bigcommerce::Lightstep.access_token,
|
35
|
+
open_timeout: ::Bigcommerce::Lightstep.open_timeout,
|
36
|
+
read_timeout: ::Bigcommerce::Lightstep.read_timeout,
|
37
|
+
continue_timeout: ::Bigcommerce::Lightstep.continue_timeout,
|
38
|
+
keep_alive_timeout: ::Bigcommerce::Lightstep.keep_alive_timeout,
|
35
39
|
logger: ::Bigcommerce::Lightstep.logger
|
36
40
|
)
|
37
41
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bc-lightstep-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shaun McCormick
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '4'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '4'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler-audit
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -42,16 +42,16 @@ dependencies:
|
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '12.0'
|
48
48
|
type: :development
|
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: '
|
54
|
+
version: '12.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,14 +86,14 @@ dependencies:
|
|
86
86
|
requirements:
|
87
87
|
- - "~>"
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: '0
|
89
|
+
version: '1.0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
94
|
- - "~>"
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: '0
|
96
|
+
version: '1.0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
98
|
name: simplecov
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,20 +150,34 @@ dependencies:
|
|
150
150
|
- - "~>"
|
151
151
|
- !ruby/object:Gem::Version
|
152
152
|
version: '4'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: activesupport
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '4'
|
160
|
+
type: :runtime
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '4'
|
153
167
|
- !ruby/object:Gem::Dependency
|
154
168
|
name: lightstep
|
155
169
|
requirement: !ruby/object:Gem::Requirement
|
156
170
|
requirements:
|
157
171
|
- - "~>"
|
158
172
|
- !ruby/object:Gem::Version
|
159
|
-
version: 0.
|
173
|
+
version: 0.16.0
|
160
174
|
type: :runtime
|
161
175
|
prerelease: false
|
162
176
|
version_requirements: !ruby/object:Gem::Requirement
|
163
177
|
requirements:
|
164
178
|
- - "~>"
|
165
179
|
- !ruby/object:Gem::Version
|
166
|
-
version: 0.
|
180
|
+
version: 0.16.0
|
167
181
|
- !ruby/object:Gem::Dependency
|
168
182
|
name: faraday
|
169
183
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,7 +187,7 @@ dependencies:
|
|
173
187
|
version: '0.8'
|
174
188
|
- - "<="
|
175
189
|
- !ruby/object:Gem::Version
|
176
|
-
version: 0.
|
190
|
+
version: 0.17.3
|
177
191
|
type: :runtime
|
178
192
|
prerelease: false
|
179
193
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -183,7 +197,7 @@ dependencies:
|
|
183
197
|
version: '0.8'
|
184
198
|
- - "<="
|
185
199
|
- !ruby/object:Gem::Version
|
186
|
-
version: 0.
|
200
|
+
version: 0.17.3
|
187
201
|
description: Gem for lightstep distributed tracing
|
188
202
|
email:
|
189
203
|
- shaun.mccormick@bigcommerce.com
|
@@ -196,6 +210,8 @@ files:
|
|
196
210
|
- README.md
|
197
211
|
- bc-lightstep-ruby.gemspec
|
198
212
|
- lib/bigcommerce/lightstep.rb
|
213
|
+
- lib/bigcommerce/lightstep/active_record/adapter.rb
|
214
|
+
- lib/bigcommerce/lightstep/active_record/tracer.rb
|
199
215
|
- lib/bigcommerce/lightstep/configuration.rb
|
200
216
|
- lib/bigcommerce/lightstep/errors.rb
|
201
217
|
- lib/bigcommerce/lightstep/interceptors/base.rb
|
@@ -215,7 +231,7 @@ homepage: https://github.com/bigcommerce/bc-lightstep-ruby
|
|
215
231
|
licenses:
|
216
232
|
- MIT
|
217
233
|
metadata: {}
|
218
|
-
post_install_message:
|
234
|
+
post_install_message:
|
219
235
|
rdoc_options: []
|
220
236
|
require_paths:
|
221
237
|
- lib
|
@@ -230,8 +246,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
230
246
|
- !ruby/object:Gem::Version
|
231
247
|
version: '0'
|
232
248
|
requirements: []
|
233
|
-
rubygems_version: 3.
|
234
|
-
signing_key:
|
249
|
+
rubygems_version: 3.2.3
|
250
|
+
signing_key:
|
235
251
|
specification_version: 4
|
236
252
|
summary: Gem for lightstep distributed tracing
|
237
253
|
test_files: []
|