bc-lightstep-ruby 2.0.0 → 2.2.2

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: df74d5a5fd2cc148fb41c803f12eac56c610e36e2b1a952b722f54c13201a208
4
- data.tar.gz: 49b0fed7a13a6c1e28e693e0a83d1e5ed36fdfc7a70547e06ef9909687bb5bff
3
+ metadata.gz: 4f3a1bf19d2bd647344092637b395c79889582497e7505fe88a15e54ca490f49
4
+ data.tar.gz: 3dd48770cacc6e088edcbb63e26a9da3954b5112cc840890d79df3285c73b3b0
5
5
  SHA512:
6
- metadata.gz: 1d3803058a964cd7ff1a7ef892de004372175bfcefdb425dfe6764881b079e9ff802d21b55fca5278a59ace21d8c99951a79f80967fa23d45cac59d4c45797b1
7
- data.tar.gz: 1ce46c68f3f0ca5adfe8e380a6c2ad802fd985d685709ba58755db47906a4bb96290b0f5cd25dbb67d3087035f8160e63945868ac68f2ce33a88d11bd3b91b86
6
+ metadata.gz: 7d8849b91e102c4ad4cac2272368d19b8f523f3195b280f9a7007344135c436ca9f7f0e44a0a0403dc4f1ea854a5de27e001d96eb96b40498d28ce63280f3501
7
+ data.tar.gz: 4fe13e2093848bba17236988b49649fbeeba3291f4c545d0732e7b4b79182c855719dcc7363f36e39141ff895976047fb369560abaaf328c688df2b426855dba
@@ -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
- [![CircleCI](https://circleci.com/gh/bigcommerce/bc-lightstep-ruby/tree/master.svg?style=svg)](https://circleci.com/gh/bigcommerce/bc-lightstep-ruby/tree/master) [![Gem Version](https://badge.fury.io/rb/bc-lightstep-ruby.svg)](https://badge.fury.io/rb/bc-lightstep-ruby) [![Inline docs](http://inch-ci.org/github/bigcommerce/bc-lightstep-ruby.svg?branch=master)](http://inch-ci.org/github/bigcommerce/bc-lightstep-ruby)
3
+ [![CircleCI](https://circleci.com/gh/bigcommerce/bc-lightstep-ruby/tree/main.svg?style=svg)](https://circleci.com/gh/bigcommerce/bc-lightstep-ruby/tree/main) [![Gem Version](https://badge.fury.io/rb/bc-lightstep-ruby.svg)](https://badge.fury.io/rb/bc-lightstep-ruby) [![Inline docs](http://inch-ci.org/github/bigcommerce/bc-lightstep-ruby.svg?branch=main)](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 instrumnent Redis calls when they are made using the `Redis::Client` class.
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:
@@ -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 'bundler', '~> 1.11'
36
+ spec.add_development_dependency 'activerecord', '> 4'
37
37
  spec.add_development_dependency 'bundler-audit', '~> 0.6'
38
- spec.add_development_dependency 'rake', '~> 10.0'
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.79'
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 'lightstep', '~> 0.13.0'
49
- spec.add_runtime_dependency 'faraday', ['>= 0.8', '<= 0.15.4']
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
- ::Bigcommerce::Lightstep::Redis::Wrapper.patch if ::Bigcommerce::Lightstep.enabled
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: 4140,
32
- ssl_verify_peer: true,
33
- open_timeout: 20,
34
- read_timeout: 20,
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: %w[ping],
45
- redis_allow_root_spans: false,
46
- enabled: true
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
- self.max_buffered_spans = ENV.fetch('LIGHTSTEP_MAX_BUFFERED_SPANS', 1_000).to_i
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
 
@@ -43,6 +43,7 @@ module Bigcommerce
43
43
  # @param [Array<Symbol>] presets Specify presets that automatically setup keys
44
44
  #
45
45
  def initialize(keys: nil, env: nil, presets: [])
46
+ super()
46
47
  @keys = keys || {}
47
48
  @presets = presets || []
48
49
  @env = env || ENV
@@ -30,7 +30,7 @@ module Bigcommerce
30
30
  OT_TAG_SAMPLED = 'ot-tracer-sampled'
31
31
 
32
32
  def initialize(app, service_name = nil)
33
- @app = app
33
+ super(app)
34
34
  @service_name = (service_name || 'external').to_s
35
35
  end
36
36
 
@@ -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 = context.is_a?(::LightStep::SpanContext) ? context : tracer.extract(1, context || {})
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: LIGHTSTEP_HOST,
48
- port: LIGHTSTEP_PORT,
49
- verbose: 0,
50
- encryption: ENCRYPTION_TLS,
63
+ host: nil,
64
+ port: nil,
65
+ verbose: nil,
66
+ encryption: nil,
51
67
  ssl_verify_peer: true,
52
- open_timeout: 2,
53
- read_timeout: 2,
68
+ ssl_port: nil,
69
+ open_timeout: nil,
70
+ read_timeout: nil,
54
71
  continue_timeout: nil,
55
- keep_alive_timeout: 2,
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
- @open_timeout = open_timeout.to_i
64
- @read_timeout = read_timeout.to_i
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(STDOUT)
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 >= 3
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 >= 3
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 == 443
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
@@ -17,6 +17,6 @@
17
17
  #
18
18
  module Bigcommerce
19
19
  module Lightstep
20
- VERSION = '2.0.0'
20
+ VERSION = '2.2.2'
21
21
  end
22
22
  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.0.0
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: 2020-02-10 00:00:00.000000000 Z
11
+ date: 2021-01-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.11'
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: '1.11'
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: '10.0'
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: '10.0'
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.79'
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.79'
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.13.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.13.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.15.4
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.15.4
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.0.6
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: []