stackify-ruby-apm 1.14.8 → 1.16.0.beta1

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.
@@ -29,8 +29,8 @@ module StackifyRubyAPM
29
29
  ::Sequel::Database.class_eval do
30
30
  alias_method 'log_connection_yield_without_apm', 'log_connection_yield'
31
31
 
32
- def log_connection_yield(sql, *args, &block)
33
- return log_connection_yield_without_apm(sql, *args, &block) unless StackifyRubyAPM.current_transaction
32
+ def log_connection_yield(sql, *args, **kwargs, &block)
33
+ return log_connection_yield_without_apm(sql, *args, **kwargs, &block) unless StackifyRubyAPM.current_transaction
34
34
 
35
35
  name = summarize sql
36
36
  db_adapter = ''
@@ -12,7 +12,7 @@ module StackifyRubyAPM
12
12
  Sidekiq::Processor.class_eval do
13
13
  alias_method 'process_without_apm', 'process'
14
14
 
15
- def process(work, *args, &block)
15
+ def process(work, *args, **kwargs, &block)
16
16
  ret = nil
17
17
  begin
18
18
  job = nil
@@ -24,7 +24,7 @@ module StackifyRubyAPM
24
24
  job_hash = JSON.parse job
25
25
  name = job_hash["class"]
26
26
  transaction = StackifyRubyAPM.transaction name, 'TASK'
27
- ret = process_without_apm(work, *args, &block)
27
+ ret = process_without_apm(work, *args, **kwargs, &block)
28
28
  rescue StackifyRubyAPM::InternalError
29
29
  raise # Don't report StackifyRubyAPM errors
30
30
  rescue StandardError => e
@@ -11,11 +11,12 @@ module StackifyRubyAPM
11
11
  ::Sinatra::Base.class_eval do
12
12
  alias_method 'dispatch_without_apm!', 'dispatch!'
13
13
  alias_method 'compile_template_without_apm', 'compile_template'
14
+ alias_method 'route_eval_without_apm', 'route_eval'
14
15
 
15
16
  # Sets transaction name from Sinatra env's route name
16
17
  #
17
- def dispatch!(*args, &block)
18
- dispatch_without_apm!(*args, &block).tap do
18
+ def dispatch!(*args, **kwargs, &block)
19
+ dispatch_without_apm!(*args, **kwargs, &block).tap do
19
20
  next unless (transaction = StackifyRubyAPM.current_transaction)
20
21
  next unless (route = env['sinatra.route'])
21
22
 
@@ -25,14 +26,23 @@ module StackifyRubyAPM
25
26
 
26
27
  # Tilt engine template
27
28
  #
28
- def compile_template(engine, data, opts, *args, &block)
29
+ def compile_template(engine, data, opts, *args, **kwargs, &block)
29
30
  opts[:__stackify_apm_template_name] =
30
31
  case data
31
32
  when Symbol then data.to_s
32
33
  else format('Inline %s', engine)
33
34
  end
34
35
 
35
- compile_template_without_apm(engine, data, opts, *args, &block)
36
+ compile_template_without_apm(engine, data, opts, *args, **kwargs, &block)
37
+ end
38
+
39
+ def route_eval(*args, **kwargs, &block)
40
+ if defined?(StackifyRubyAPM.current_transaction)
41
+ if env.key?('sinatra.route')
42
+ StackifyRubyAPM.current_transaction.name = env['sinatra.route']
43
+ end
44
+ end
45
+ route_eval_without_apm(*args, **kwargs, &block)
36
46
  end
37
47
  end
38
48
  end
@@ -12,14 +12,14 @@ module StackifyRubyAPM
12
12
  SuckerPunch::Job::ClassMethods.class_eval do
13
13
  alias_method '__run_perform_without_elastic_apm', '__run_perform'
14
14
 
15
- def __run_perform(*args)
15
+ def __run_perform(*args, **kwargs)
16
16
  ret = nil
17
17
  begin
18
18
  name = "#{to_s}.perform"
19
19
  ctx = StackifyRubyAPM::Context.new
20
20
  ctx.category = 'SuckerPunch::Job'
21
21
  transaction = StackifyRubyAPM.transaction name, 'TASK', context: ctx
22
- ret = __run_perform_without_elastic_apm(*args)
22
+ ret = __run_perform_without_elastic_apm(*args, **kwargs)
23
23
  rescue StackifyRubyAPM::InternalError
24
24
  raise # Don't report StackifyRubyAPM errors
25
25
  rescue StandardError => e
@@ -15,13 +15,13 @@ module StackifyRubyAPM
15
15
  ::Tilt::Template.class_eval do
16
16
  alias_method 'render_without_apm', 'render'
17
17
 
18
- def render(*args, &block)
18
+ def render(*args, **kwargs, &block)
19
19
  name = options[:__stackify_apm_template_name] || 'Unknown template'
20
20
 
21
21
  # Creates new span for Tilt templating
22
22
  #
23
23
  StackifyRubyAPM.span name, TYPE do
24
- render_without_apm(*args, &block)
24
+ render_without_apm(*args, **kwargs, &block)
25
25
  end
26
26
  end
27
27
  end
@@ -35,6 +35,92 @@ module StackifyRubyAPM
35
35
  obj[i] = val.to_s
36
36
  ary.push(obj)
37
37
  end
38
+
39
+ URL_ID_REGEX = /^(\d+)$/
40
+ URL_GUID_REGEX = /^(?i)(\b[A-F0-9]{8}(?:-[A-F0-9]{4}){3}-[A-F0-9]{12}\b)$/
41
+ URL_EMAIL_REGEX = /^((([!#$%&'*+\-\/=?^_`{|}~\w])|([!#$%&'*+\-\/=?^_`{|}~\w][!#$%&'*+\-\/=?^_`{|}~\.\w]{0,}[!#$%&'*+\-\/=?^_`{|}~\w]))[@]\w+([-.]\w+)*\.\w+([-.]\w+)*)$/
42
+ URL_IP_REGEX = /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
43
+
44
+ def self.maskReportingUrl(url)
45
+ parts = url.split('/', -1)
46
+
47
+ if (!parts.length)
48
+ return '/'
49
+ end
50
+
51
+ maskedParts = []
52
+ parts.each do |part|
53
+ maskedParts.push(maskString(part))
54
+ end
55
+
56
+ maskedUrl = maskedParts.join('/')
57
+
58
+ if (maskedUrl.length == 1)
59
+ return maskedUrl
60
+ end
61
+
62
+ if maskedUrl.end_with?('/')
63
+ trimmedUrl = maskedUrl.slice(0, maskedUrl.length-1)
64
+ if (!trimmedUrl.length)
65
+ return '/'
66
+ end
67
+
68
+ return trimmedUrl
69
+ end
70
+
71
+ maskedUrl
72
+ end
73
+
74
+ def self.maskString(string)
75
+ return '{id}' if string =~ URL_ID_REGEX
76
+ return '{guid}' if string =~ URL_GUID_REGEX
77
+ return '{email}' if string =~ URL_EMAIL_REGEX
78
+ return '{ip}' if string =~ URL_IP_REGEX
79
+
80
+ if string.include? ';'
81
+ string_index = string.index(';');
82
+ return '' if (string_index <= 0)
83
+ return string[0..string.index(';')-1] if (string_index)
84
+ end
85
+
86
+ # Default
87
+ string
88
+ end
89
+
90
+ def self.fileExists?(dir_name)
91
+ # Ruby 3.2 changed File.exists to File.exist.
92
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("3.2")
93
+ return File.exists?(dir_name)
94
+ else
95
+ return File.exist?(dir_name)
96
+ end
97
+ end
98
+
99
+ def self.checkOrCreateFolder(dir_name)
100
+ if (dir_name.to_s.empty?)
101
+ return false
102
+ end
103
+
104
+ if (!fileExists?(dir_name))
105
+ umask = File.umask
106
+ File.umask(0)
107
+ FileUtils.mkdir_p(dir_name)
108
+ File.chmod(0777, dir_name)
109
+ File.umask(umask)
110
+ end
111
+
112
+ if (!fileExists?(dir_name))
113
+ puts "Util::Stackify Profiler unable to find [" + dir_name + "]"
114
+ return false
115
+ end
116
+
117
+ if (!File.writable?(dir_name))
118
+ puts "Util::Stackify Profiler unable to access/write [" + dir_name + "]"
119
+ return false
120
+ end
121
+
122
+ return true
123
+ end
38
124
  end
39
125
  end
40
126
  require 'stackify_apm/util/inspector'
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # Sets the version of the APM
3
+ # Sets the version of the APM:
4
4
  module StackifyRubyAPM
5
- VERSION = '1.14.8'.freeze
5
+ VERSION = '1.16.0.beta1'.freeze
6
6
  end
@@ -50,22 +50,67 @@ module StackifyRubyAPM
50
50
  end
51
51
 
52
52
  def self.inject_rum_script
53
- config = StackifyRubyAPM::Config.new
54
- client_id = config.client_id
55
- device_id = config.device_id
56
- client_rundomain = config.client_run_domain
57
- transaction_id = defined?(StackifyRubyAPM.current_transaction.id) ? StackifyRubyAPM.current_transaction.id : nil
53
+ transaction = defined?(StackifyRubyAPM.current_transaction) ? StackifyRubyAPM.current_transaction : nil
54
+ return '' unless transaction
55
+
56
+ transaction_id = defined?(transaction.id) ? transaction.id : nil
58
57
  inject_flag = false
59
58
 
60
- if client_id && device_id
61
- inject_flag = true if check_isdomain(client_rundomain)
59
+ config = nil
60
+ if defined?(agent.config)
61
+ config = agent.config
62
+ end
63
+
64
+ return '' unless config
65
+
66
+ if transaction_id
67
+ inject_flag = true
68
+ end
69
+
70
+ return '' unless inject_flag
71
+
72
+ return '' if config.rum_script_url.to_s.empty? || config.rum_key.to_s.empty?
73
+
74
+ rum_settings = {
75
+ "ID" => transaction_id
76
+ }
77
+
78
+ if defined?(config.environment_name)
79
+ environment_name = 'Development'
80
+ if !config.environment_name.to_s.empty?
81
+ environment_name = config.environment_name
82
+ end
83
+
84
+ rum_settings["Env"] = Base64.strict_encode64(environment_name.encode('utf-8'))
85
+ end
86
+
87
+ application_name = config.application_name
88
+ return '' if application_name.to_s.empty?
89
+
90
+ rum_settings["Name"] = Base64.strict_encode64(application_name.strip.encode('utf-8'))
91
+
92
+ if defined?(transaction.name) && !transaction.name.to_s.empty?
93
+ reporting_url = Util.maskReportingUrl(transaction.name)
94
+
95
+ if defined?(transaction.context.request.method) && !transaction.context.request.nil? && !transaction.context.request.method.nil?
96
+ reporting_url = "#{transaction.context.request.method}-#{reporting_url}"
97
+ end
98
+
99
+ rum_settings["Trans"] = Base64.strict_encode64(reporting_url.encode('utf-8'))
62
100
  end
63
101
 
64
- return unless inject_flag
65
- data_request_id = "V2|#{transaction_id}|#{client_id}|#{device_id}"
66
102
  @rum_script_injected = true
67
- "<script src=\"#{config.rum_script_src}\" data-host=\"#{client_rundomain}\" data-requestId=\"#{data_request_id}\"
68
- data-a=\"#{config.application_name}\" data-e=\"#{config.environment_name}\" data-enableInternalLogging=\"#{config.debug_logging}\" type=\"text/javascript\" async></script>"
103
+
104
+ if defined?(transaction.context)
105
+ transaction.context.rum = true
106
+ end
107
+
108
+ rum_content = "<script type=\"text/javascript\">(window.StackifySettings || (window.StackifySettings = #{rum_settings.to_json}))</script><script src=\"#{config.rum_script_url}\" data-key=\"#{config.rum_key}\" async></script>"
109
+ if rum_content.respond_to?(:html_safe)
110
+ rum_content.html_safe
111
+ else
112
+ rum_content
113
+ end
69
114
  end
70
115
 
71
116
  # Run the custom instrument
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path('lib', __dir__)
3
+ lib = File.expand_path('lib', File.dirname(__FILE__))
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
  require 'stackify_apm/version'
6
6
 
@@ -13,6 +13,9 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'http://www.stackify.com'
14
14
  spec.license = 'Stackify'
15
15
 
16
+ # Set the minimum Ruby version required
17
+ spec.required_ruby_version = '>= 3.0.0'
18
+
16
19
  git_tracked_files = `git ls-files -z`.split("\x0")
17
20
  gem_ignored_files = `git ls-files -i -X .gemignore -z`.split("\x0")
18
21
  spec.files = git_tracked_files - gem_ignored_files
@@ -22,10 +25,13 @@ Gem::Specification.new do |spec|
22
25
  spec.require_paths = ['lib']
23
26
 
24
27
  # rails
25
- if RUBY_VERSION > '2.5'
28
+ if RUBY_VERSION > '2.9'
29
+ spec.add_development_dependency 'rails', '~> 6.1'
30
+ elsif RUBY_VERSION > '2.5'
26
31
  spec.add_development_dependency 'rails', '~> 5.0'
27
32
  else
28
33
  spec.add_development_dependency 'rails', '~> 4.0'
34
+ spec.add_development_dependency 'sprockets', '~> 3.0'
29
35
  end
30
36
 
31
37
  # bigdecimal
@@ -33,32 +39,63 @@ Gem::Specification.new do |spec|
33
39
  spec.add_development_dependency 'bigdecimal'
34
40
  end
35
41
 
36
- spec.add_development_dependency 'bundler', '~> 1.16'
37
- spec.add_development_dependency 'rake', '~> 10.0'
38
- spec.add_development_dependency 'rspec', '~> 3.0'
42
+ if RUBY_PLATFORM == 'i386-mingw32'
43
+ spec.add_development_dependency 'tzinfo-data'
44
+ end
45
+
46
+ if RUBY_VERSION > '2.9'
47
+ spec.add_development_dependency 'bundler', '~> 2.4.12'
48
+ else
49
+ spec.add_development_dependency 'bundler', '~> 1.16'
50
+ end
51
+
52
+ if RUBY_VERSION > '2.9'
53
+ spec.add_development_dependency 'rake'
54
+ spec.add_development_dependency 'rspec', '3.9.0'
55
+ spec.add_development_dependency 'curb', '1.0.3'
56
+ spec.add_development_dependency 'pg'
57
+ spec.add_development_dependency 'sqlite3'
58
+ else
59
+ spec.add_development_dependency 'rake', '~> 10.0'
60
+ spec.add_development_dependency 'rspec', '~> 3.0'
61
+ spec.add_development_dependency 'curb', '0.9.8'
62
+ spec.add_development_dependency 'pg', '~> 0.20'
63
+ spec.add_development_dependency 'sqlite3', '1.3.13'
64
+ spec.add_development_dependency('delegate_matcher', '~> 0.4') # for testing
65
+ end
66
+
67
+
39
68
  spec.add_development_dependency 'activerecord'
40
- spec.add_development_dependency 'curb', '0.9.8'
41
69
  spec.add_development_dependency 'fakeredis'
42
70
  spec.add_development_dependency 'http'
43
71
  spec.add_development_dependency 'httpclient'
44
72
  spec.add_development_dependency 'mongo'
45
73
  spec.add_development_dependency 'mysql2'
46
- spec.add_development_dependency 'pg', '~> 0.20'
74
+
47
75
  spec.add_development_dependency 'rack-test'
48
76
  spec.add_development_dependency 'rubocop'
49
77
  spec.add_development_dependency 'sequel'
50
78
  spec.add_development_dependency 'sinatra'
51
79
  spec.add_development_dependency 'sinatra-activerecord'
52
- spec.add_development_dependency 'sqlite3', '1.3.13'
80
+
53
81
  spec.add_development_dependency 'stackify-api-ruby'
54
82
  spec.add_development_dependency 'timecop'
55
83
  spec.add_development_dependency 'to_bool'
56
84
  spec.add_development_dependency 'webmock'
57
85
  spec.add_development_dependency 'delayed_job'
58
86
 
59
- spec.add_dependency('concurrent-ruby', '~> 1.0')
60
- spec.add_dependency('delegate_matcher', '~> 0.4')
61
- spec.add_dependency('faraday', '~> 0.8')
62
- spec.add_dependency('net_http_unix', '~> 0.2')
63
- spec.add_dependency('rufus-scheduler', '~> 3.0')
64
- end
87
+ if RUBY_VERSION > '2.9'
88
+ spec.add_dependency('concurrent-ruby')
89
+ spec.add_dependency('delegate_matcher')
90
+ spec.add_dependency('faraday')
91
+ spec.add_dependency('net_http_unix')
92
+ spec.add_dependency('rufus-scheduler')
93
+ else
94
+ spec.add_dependency('concurrent-ruby', '~> 1.0')
95
+ spec.add_dependency('delegate_matcher', '~> 0.4')
96
+ spec.add_dependency('faraday', '~> 0.8')
97
+ spec.add_dependency('net_http_unix', '~> 0.2')
98
+ spec.add_dependency('rufus-scheduler', '~> 3.0')
99
+ end
100
+
101
+ end