bc-lightstep-ruby 1.6.4 → 2.2.1

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: 176f7abe094e0d366207e675aaa721861fbc9a34f86a9a79b9eb0ce87991f9f1
4
- data.tar.gz: ff90d1766bfd13ac1fcb0488dfa90abd787eb2d7978293f7ec30ccd75df75f46
3
+ metadata.gz: da452a7f373b4db3b6ee125e9b42787c4dca7e3848ef91fdbe24fc0991044b45
4
+ data.tar.gz: 10eb39929ce15f3df29924becdf69afd397f52297a8f74dd1504fc67ea634e2a
5
5
  SHA512:
6
- metadata.gz: ed5eff2bac04cd1ead578eaf651bf7595b26bb1e1ff1487d42ee67df0f2b2dd08b483ca376c59991ca6712a8dc83e1f86daf863e4174d54a4c9e4ce5ebb8b497
7
- data.tar.gz: 1a4ef5813fe88651c82c60763d355b8b419939d50240097f712bc482afcaa286579238b1bd5940adb27cba9d7e375e09f4186a65764f5306e9020c68c3899142
6
+ metadata.gz: 4474f23f5dc1c0a7046df0cd3a748450df0c91619dedf5d123eb6ace4a5cc81884be514fbc70f62cfa4875ba3f4ebb3f59b580e8d59a7c2460d9949d68bdb476
7
+ data.tar.gz: 33d96552fe76aa2e70b20ef0e35c7b532ba0baf7d3e8528fd7fceafea7132b6a13fac6fa5d6f14bb54672090ce9e1f8ecf7c5f34f0e0e30ecbd2e808ec02baf8
@@ -1,137 +1,156 @@
1
1
  Changelog for the bc-lightstep-ruby gem.
2
2
 
3
- h3. Pending Release
3
+ ### Pending Release
4
4
 
5
- h3. 1.6.4
5
+ ### 2.2.1
6
+
7
+ - Only set error tag in exceptions if not already set
8
+ - Update to Rubocop 1.0
9
+
10
+ ### 2.1.1
11
+
12
+ - Bump lightstep gem to 0.16.0
13
+ - Bump faraday gem to <= 0.17.3
14
+
15
+ ### 2.1.0
16
+
17
+ - Add support for automatically-generated mysql spans in tracing
18
+
19
+ ### 2.0.0
20
+
21
+ - Drop support for Ruby < 2.6
22
+ - Set default log level to INFO when no logger is provided
23
+
24
+ ### 1.6.4
6
25
 
7
26
  - Add `nomad.node.id` and `nomad.node.name` span tags via ENV mappings
8
27
 
9
- h3. 1.6.3
28
+ ### 1.6.3
10
29
 
11
30
  - Add service.version to tags
12
31
 
13
- h3. 1.6.2
32
+ ### 1.6.2
14
33
 
15
34
  - Add span.kind tags to boundary spans
16
35
 
17
- h3. 1.6.1
36
+ ### 1.6.1
18
37
 
19
38
  - Add interception context for thread-safe interception per trace
20
39
  - Fix issue when there are no interceptors configured
21
40
  - Fix issue where there is more than one interceptor configured
22
41
  - Only pass env tags if root span for service
23
42
 
24
- h3. 1.6.0
43
+ ### 1.6.0
25
44
 
26
45
  - Allow for instantiation of interceptors at initialization time
27
46
  - Pre-build tag values for ENV interceptor at initialization to reduce CPU usage per-span
28
47
 
29
- h3. 1.5.2
48
+ ### 1.5.2
30
49
 
31
50
  - Add rspec helper for testing custom lightstep spans
32
51
 
33
- h3. 1.5.1
52
+ ### 1.5.1
34
53
 
35
54
  - Add `hostname` preset for env var injection into spans
36
55
 
37
- h3. 1.5.0
56
+ ### 1.5.0
38
57
 
39
58
  - Add interceptors that allow for global injection of tags into spans
40
59
 
41
- h3. 1.4.0
60
+ ### 1.4.0
42
61
 
43
62
  - Add `frozen_string_literal: true` to all files
44
63
  - Deprecate ruby 2.2 support
45
64
 
46
- h3. 1.3.3
65
+ ### 1.3.3
47
66
 
48
67
  - Updates gemspec to allow for newer Faraday versions
49
68
 
50
- h3. 1.3.2
69
+ ### 1.3.2
51
70
 
52
71
  - Fix compatibility issues with resque-scheduler and redis instrumentation
53
72
 
54
- h3. 1.3.1
73
+ ### 1.3.1
55
74
 
56
75
  - Add various options to suppress redis trace spam
57
76
  - Fix issue with pipeline commands in redis instrumentation
58
77
 
59
- h3. 1.3.0
78
+ ### 1.3.0
60
79
 
61
80
  - Adds automatic Redis instrumentation support
62
81
 
63
- h3. 1.2.2
82
+ ### 1.2.2
64
83
 
65
84
  - Allow for usage of blank access tokens, which can be used with disabled token checking + project-specific satellites
66
85
 
67
- h3. 1.2.1
86
+ ### 1.2.1
68
87
 
69
88
  - Fix issue where in Rails controllers before the action occurs that an uninitialized reporter would cause a
70
89
  NoMethodError to occur (this most commonly occurs in test suites)
71
90
 
72
- h3. 1.2.0
91
+ ### 1.2.0
73
92
 
74
93
  - Bump lightstep gem to 0.13
75
94
  - Add LIGHTSTEP_MAX_BUFFERED_SPANS config ENV + setting for maximum number of spans to buffer
76
95
  - Add LIGHTSTEP_MAX_LOG_RECORDS config ENV + setting for maximum number of log records that can be on a span
77
96
  - Add LIGHTSTEP_MAX_REPORTING_INTERVAL_SECONDS config ENV + setting for max reporting flush interval to collector
78
97
 
79
- h3. 1.1.8
98
+ ### 1.1.8
80
99
 
81
100
  - Handle issue that occurs if lightstep is disabled but the start_span method is still called
82
101
  - Remove FORMAT_TEXT_MAP reference as this is no longer present in later lightstep gem versions
83
102
 
84
- h3. 1.1.7
103
+ ### 1.1.7
85
104
 
86
105
  - Better handling of exceptions and tagged errors
87
106
  - Lower timeouts for collector connections to reduce impact if collector is down/unreachable
88
107
  - Always ensure spans are reported even in the case of exceptional failure
89
108
 
90
- h3. 1.1.6
109
+ ### 1.1.6
91
110
 
92
111
  - First OSS release
93
112
 
94
- h3. 1.1.5
113
+ ### 1.1.5
95
114
 
96
115
  - Pin lightstep gem to 0.11.x due to backwards-incompatible change in 0.12.x
97
116
 
98
- h3. 1.1.4
117
+ ### 1.1.4
99
118
 
100
119
  - Add enabled setting to explicitly disable lightstep at runtime. Can be toggled with LIGHTSTEP_ENABLED ENV var.
101
120
 
102
- h3. 1.1.3
121
+ ### 1.1.3
103
122
 
104
123
  - Have http1 errors only flag as error if they are 500+ status codes
105
124
 
106
- h3. 1.1.2
125
+ ### 1.1.2
107
126
 
108
127
  - Prevent span from starting if the reporter is not yet configured, as LightStep gem does not guard this case
109
128
 
110
- h3. 1.1.1
129
+ ### 1.1.1
111
130
 
112
131
  - Fix issues where Rack/Rails is prepending HTTP_ to headers, ensure right key format into carrier
113
132
 
114
- h3. 1.1.0
133
+ ### 1.1.0
115
134
 
116
135
  - Add Faraday middleware for automatic tracing of outbound service calls
117
136
 
118
- h3. 1.0.5
137
+ ### 1.0.5
119
138
 
120
139
  - Do not send GET params in rails controller instrumentation for http.url tag
121
140
 
122
- h3. 1.0.4
141
+ ### 1.0.4
123
142
 
124
143
  - Rename span tags to fit the BigCommerce standardized tags
125
144
  - Handle 500 errors in H1 requests properly
126
145
 
127
- h3. 1.0.3
146
+ ### 1.0.3
128
147
 
129
148
  - Fix bug where active parent span was persisting between requests in rails controller requests
130
149
 
131
- h3. 1.0.2
150
+ ### 1.0.2
132
151
 
133
152
  - Add Bigcommerce::Lightstep::Rails::ControllerInstrumentation module for tracing H1 controllers in Rails
134
153
 
135
- h3. 1.0.0
154
+ ### 1.0.0
136
155
 
137
156
  - Initial public release
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:
@@ -31,12 +31,22 @@ Gem::Specification.new do |spec|
31
31
 
32
32
  spec.files = Dir['README.md', 'CHANGELOG.md', 'CODE_OF_CONDUCT.md', 'lib/**/*', 'bc-lightstep-ruby.gemspec']
33
33
  spec.require_paths = ['lib']
34
+ spec.required_ruby_version = '>= 2.6'
34
35
 
36
+ spec.add_development_dependency 'activerecord', '> 4'
35
37
  spec.add_development_dependency 'bundler', '~> 1.11'
36
- spec.add_development_dependency 'rake', '~> 10.0'
37
- spec.add_development_dependency 'rspec', '~> 3.0'
38
- spec.add_development_dependency 'pry'
38
+ spec.add_development_dependency 'bundler-audit', '~> 0.6'
39
+ spec.add_development_dependency 'rake', '>= 12.0'
40
+ spec.add_development_dependency 'rspec', '~> 3.8'
41
+ spec.add_development_dependency 'rspec_junit_formatter', '~> 0.4'
42
+ spec.add_development_dependency 'rubocop', '~> 1.0'
43
+ spec.add_development_dependency 'simplecov', '~> 0.15'
44
+ spec.add_development_dependency 'pry', '>= 0.12'
39
45
 
40
- spec.add_runtime_dependency 'lightstep', '~> 0.13.0'
41
- spec.add_runtime_dependency 'faraday', ['>= 0.8', '<= 0.15.4']
46
+ spec.add_development_dependency 'null-logger', '~> 0.1'
47
+ spec.add_development_dependency 'redis', '~> 4'
48
+
49
+ spec.add_runtime_dependency 'activesupport', '>= 4'
50
+ spec.add_runtime_dependency 'lightstep', '~> 0.16.0'
51
+ spec.add_runtime_dependency 'faraday', ['>= 0.8', '<= 0.17.3']
42
52
  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,19 +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
101
+ default_logger = ::Logger.new($stdout)
102
+ default_logger.level = ::Logger::INFO
103
+ self.logger = defined?(Rails) ? Rails.logger : default_logger
106
104
 
107
- self.verbosity = ENV.fetch('LIGHTSTEP_VERBOSITY', 1).to_i
108
- self.logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
109
- self.enabled = ENV.fetch('LIGHTSTEP_ENABLED', 1).to_i.positive?
110
105
  self.interceptors = ::Bigcommerce::Lightstep::Interceptors::Registry.new
111
106
  end
112
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
@@ -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,28 +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
- @logger = logger || ::Logger.new(STDOUT)
86
+
87
+ default_logger = ::Logger.new($stdout)
88
+ default_logger.level = ::Logger::INFO
89
+ @logger = logger || default_logger
90
+ super()
69
91
  end
70
92
 
71
93
  ##
@@ -75,12 +97,12 @@ module Bigcommerce
75
97
  # @return [NilClass]
76
98
  #
77
99
  def report(report)
78
- @logger.info report if @verbose >= 3
100
+ @logger.info report if @verbose >= Verbosity::INFO
79
101
 
80
102
  req = build_request(report)
81
103
  res = connection.request(req)
82
104
 
83
- @logger.info res.to_s if @verbose >= 3
105
+ @logger.info res.to_s if @verbose >= Verbosity::INFO
84
106
 
85
107
  nil
86
108
  end
@@ -106,7 +128,7 @@ module Bigcommerce
106
128
  def connection
107
129
  unless @connection
108
130
  @connection = ::Net::HTTP.new(@host, @port)
109
- if @port == 443
131
+ if @port == @ssl_port
110
132
  @connection.use_ssl = @encryption == ENCRYPTION_TLS
111
133
  @connection.verify_mode = ::OpenSSL::SSL::VERIFY_NONE unless @ssl_verify_peer
112
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 = '1.6.4'
20
+ VERSION = '2.2.1'
21
21
  end
22
22
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bc-lightstep-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.4
4
+ version: 2.2.1
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: 2019-08-30 00:00:00.000000000 Z
11
+ date: 2020-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '4'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '4'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -25,61 +39,159 @@ dependencies:
25
39
  - !ruby/object:Gem::Version
26
40
  version: '1.11'
27
41
  - !ruby/object:Gem::Dependency
28
- name: rake
42
+ name: bundler-audit
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
- version: '10.0'
47
+ version: '0.6'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
52
  - - "~>"
39
53
  - !ruby/object:Gem::Version
40
- version: '10.0'
54
+ version: '0.6'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '12.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '12.0'
41
69
  - !ruby/object:Gem::Dependency
42
70
  name: rspec
43
71
  requirement: !ruby/object:Gem::Requirement
44
72
  requirements:
45
73
  - - "~>"
46
74
  - !ruby/object:Gem::Version
47
- version: '3.0'
75
+ version: '3.8'
48
76
  type: :development
49
77
  prerelease: false
50
78
  version_requirements: !ruby/object:Gem::Requirement
51
79
  requirements:
52
80
  - - "~>"
53
81
  - !ruby/object:Gem::Version
54
- version: '3.0'
82
+ version: '3.8'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec_junit_formatter
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '0.4'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '0.4'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '1.0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '1.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: simplecov
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '0.15'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '0.15'
55
125
  - !ruby/object:Gem::Dependency
56
126
  name: pry
57
127
  requirement: !ruby/object:Gem::Requirement
58
128
  requirements:
59
129
  - - ">="
60
130
  - !ruby/object:Gem::Version
61
- version: '0'
131
+ version: '0.12'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0.12'
139
+ - !ruby/object:Gem::Dependency
140
+ name: null-logger
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - "~>"
144
+ - !ruby/object:Gem::Version
145
+ version: '0.1'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - "~>"
151
+ - !ruby/object:Gem::Version
152
+ version: '0.1'
153
+ - !ruby/object:Gem::Dependency
154
+ name: redis
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '4'
62
160
  type: :development
63
161
  prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '4'
167
+ - !ruby/object:Gem::Dependency
168
+ name: activesupport
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: '4'
174
+ type: :runtime
175
+ prerelease: false
64
176
  version_requirements: !ruby/object:Gem::Requirement
65
177
  requirements:
66
178
  - - ">="
67
179
  - !ruby/object:Gem::Version
68
- version: '0'
180
+ version: '4'
69
181
  - !ruby/object:Gem::Dependency
70
182
  name: lightstep
71
183
  requirement: !ruby/object:Gem::Requirement
72
184
  requirements:
73
185
  - - "~>"
74
186
  - !ruby/object:Gem::Version
75
- version: 0.13.0
187
+ version: 0.16.0
76
188
  type: :runtime
77
189
  prerelease: false
78
190
  version_requirements: !ruby/object:Gem::Requirement
79
191
  requirements:
80
192
  - - "~>"
81
193
  - !ruby/object:Gem::Version
82
- version: 0.13.0
194
+ version: 0.16.0
83
195
  - !ruby/object:Gem::Dependency
84
196
  name: faraday
85
197
  requirement: !ruby/object:Gem::Requirement
@@ -89,7 +201,7 @@ dependencies:
89
201
  version: '0.8'
90
202
  - - "<="
91
203
  - !ruby/object:Gem::Version
92
- version: 0.15.4
204
+ version: 0.17.3
93
205
  type: :runtime
94
206
  prerelease: false
95
207
  version_requirements: !ruby/object:Gem::Requirement
@@ -99,7 +211,7 @@ dependencies:
99
211
  version: '0.8'
100
212
  - - "<="
101
213
  - !ruby/object:Gem::Version
102
- version: 0.15.4
214
+ version: 0.17.3
103
215
  description: Gem for lightstep distributed tracing
104
216
  email:
105
217
  - shaun.mccormick@bigcommerce.com
@@ -112,6 +224,8 @@ files:
112
224
  - README.md
113
225
  - bc-lightstep-ruby.gemspec
114
226
  - lib/bigcommerce/lightstep.rb
227
+ - lib/bigcommerce/lightstep/active_record/adapter.rb
228
+ - lib/bigcommerce/lightstep/active_record/tracer.rb
115
229
  - lib/bigcommerce/lightstep/configuration.rb
116
230
  - lib/bigcommerce/lightstep/errors.rb
117
231
  - lib/bigcommerce/lightstep/interceptors/base.rb
@@ -131,7 +245,7 @@ homepage: https://github.com/bigcommerce/bc-lightstep-ruby
131
245
  licenses:
132
246
  - MIT
133
247
  metadata: {}
134
- post_install_message:
248
+ post_install_message:
135
249
  rdoc_options: []
136
250
  require_paths:
137
251
  - lib
@@ -139,7 +253,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
139
253
  requirements:
140
254
  - - ">="
141
255
  - !ruby/object:Gem::Version
142
- version: '0'
256
+ version: '2.6'
143
257
  required_rubygems_version: !ruby/object:Gem::Requirement
144
258
  requirements:
145
259
  - - ">="
@@ -147,7 +261,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
147
261
  version: '0'
148
262
  requirements: []
149
263
  rubygems_version: 3.0.6
150
- signing_key:
264
+ signing_key:
151
265
  specification_version: 4
152
266
  summary: Gem for lightstep distributed tracing
153
267
  test_files: []