stackify-ruby-apm 1.10.0 → 1.12.3

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.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/lib/stackify_apm/agent.rb +0 -2
  3. data/lib/stackify_apm/config.rb +33 -5
  4. data/lib/stackify_apm/context.rb +4 -1
  5. data/lib/stackify_apm/context/prefix.rb +30 -0
  6. data/lib/stackify_apm/context/request/headers.rb +30 -0
  7. data/lib/stackify_apm/context_builder.rb +1 -0
  8. data/lib/stackify_apm/helper/database_helper.rb +39 -1
  9. data/lib/stackify_apm/instrumenter_helper.rb +90 -4
  10. data/lib/stackify_apm/logger/log_device.rb +7 -5
  11. data/lib/stackify_apm/logger/logger_high_version.rb +5 -1
  12. data/lib/stackify_apm/logger/logger_lower_version.rb +5 -1
  13. data/lib/stackify_apm/middleware.rb +21 -3
  14. data/lib/stackify_apm/normalizers/active_record.rb +16 -8
  15. data/lib/stackify_apm/root_info.rb +7 -1
  16. data/lib/stackify_apm/serializers/transactions.rb +5 -0
  17. data/lib/stackify_apm/span/context.rb +39 -1
  18. data/lib/stackify_apm/spies.rb +4 -2
  19. data/lib/stackify_apm/spies/action_dispatch.rb +6 -1
  20. data/lib/stackify_apm/spies/curb.rb +41 -20
  21. data/lib/stackify_apm/spies/curb/easy.rb +220 -92
  22. data/lib/stackify_apm/spies/curb/multi.rb +26 -12
  23. data/lib/stackify_apm/spies/custom_instrumenter.rb +25 -4
  24. data/lib/stackify_apm/spies/delayed_job.rb +49 -0
  25. data/lib/stackify_apm/spies/httparty.rb +45 -24
  26. data/lib/stackify_apm/spies/httpclient.rb +41 -20
  27. data/lib/stackify_apm/spies/httprb.rb +39 -18
  28. data/lib/stackify_apm/spies/log4r.rb +59 -0
  29. data/lib/stackify_apm/spies/logger.rb +116 -0
  30. data/lib/stackify_apm/spies/logging.rb +65 -0
  31. data/lib/stackify_apm/spies/net_http.rb +38 -20
  32. data/lib/stackify_apm/spies/redis.rb +36 -30
  33. data/lib/stackify_apm/spies/sequel.rb +28 -11
  34. data/lib/stackify_apm/spies/sinatra_activerecord/mysql_adapter.rb +27 -25
  35. data/lib/stackify_apm/spies/sinatra_activerecord/postgresql_adapter.rb +27 -24
  36. data/lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb +18 -8
  37. data/lib/stackify_apm/spies/stackify_logger.rb +28 -16
  38. data/lib/stackify_apm/spies/yell.rb +64 -0
  39. data/lib/stackify_apm/util.rb +10 -9
  40. data/lib/stackify_apm/version.rb +1 -1
  41. data/stackify-ruby-apm.gemspec +1 -0
  42. metadata +23 -2
@@ -2,6 +2,8 @@
2
2
 
3
3
  # Spies for active record when sinatra framework is used and active_record is being extended. (mysql adapter)
4
4
 
5
+ require 'stackify_apm/helper/database_helper'
6
+
5
7
  module StackifyRubyAPM
6
8
  # @api private
7
9
  module Spies
@@ -21,15 +23,11 @@ module StackifyRubyAPM
21
23
  exec_query_without_apm(sql, name, binds)
22
24
  end
23
25
 
24
- ctx = Span::Context.new(
25
- CATEGORY: 'Database',
26
- SUBCATEGORY: 'Execute',
27
- COMPONENT_CATEGORY: 'DB Query',
28
- COMPONENT_DETAIL: 'Execute SQL Query',
29
- SQL: sql,
30
- PROVIDER: 'generic'
31
- )
26
+ payload = {sql: sql, binds: binds}
27
+ statement = query_variables(payload)
28
+ check_prepared_stmt(statement, payload)
32
29
 
30
+ ctx = Span::Context.new(statement)
33
31
  result = exec_query_without_apm(sql, name, binds)
34
32
 
35
33
  StackifyRubyAPM.span name, TYPE, context: ctx do
@@ -37,6 +35,18 @@ module StackifyRubyAPM
37
35
  end
38
36
  end
39
37
  # rubocop:enable Lint/UnusedMethodArgument
38
+
39
+ def query_variables(payload)
40
+ props = get_common_db_properties
41
+ props[:SQL] = payload[:sql]
42
+ props
43
+ end
44
+
45
+ def check_prepared_stmt(statement, payload)
46
+ if StackifyRubyAPM.agent.config.prefix_enabled
47
+ check_prepared_stmt_by_placeholder(payload[:sql].include?('?'), statement, payload)
48
+ end
49
+ end
40
50
  end
41
51
  end
42
52
  end
@@ -14,15 +14,21 @@ module StackifyRubyAPM
14
14
  def log_message_task(level, msg, call_trace)
15
15
  return log_message_task_without_apm(level, msg, call_trace) unless StackifyRubyAPM.current_transaction
16
16
 
17
- trans_id = StackifyRubyAPM.current_transaction.id
18
- log_uuid = SecureRandom.uuid
17
+ begin
18
+ trans_id = StackifyRubyAPM.current_transaction.id
19
+ log_uuid = SecureRandom.uuid
19
20
 
20
- # build span context
21
- ctx = Span::Context.new(
22
- CATEGORY: 'Stackify',
23
- SUBCATEGORY: 'Log',
24
- ID: log_uuid # matching the MsgObject id
25
- )
21
+ # build span context
22
+ ctx = Span::Context.new(
23
+ CATEGORY: 'Stackify',
24
+ SUBCATEGORY: 'Log',
25
+ ID: log_uuid # matching the MsgObject id
26
+ )
27
+ rescue Exception => e
28
+ StackifyRubyAPM.agent.error "[StackifyLoggerSpy] Error: creating span context."
29
+ StackifyRubyAPM.agent.error "[StackifyLoggerSpy] #{e.inspect}"
30
+ return log_message_task_without_apm(level, msg, call_trace)
31
+ end
26
32
 
27
33
  # create log span
28
34
  StackifyRubyAPM.span(msg, 'stackify.log', context: ctx) do
@@ -34,15 +40,21 @@ module StackifyRubyAPM
34
40
  def log_exception_task(level, ex)
35
41
  return log_exception_task_without_apm(level, ex) unless StackifyRubyAPM.current_transaction
36
42
 
37
- trans_id = StackifyRubyAPM.agent.current_transaction.id
38
- log_uuid = SecureRandom.uuid
43
+ begin
44
+ trans_id = StackifyRubyAPM.agent.current_transaction.id
45
+ log_uuid = SecureRandom.uuid
39
46
 
40
- # build span context
41
- ctx = Span::Context.new(
42
- CATEGORY: 'Stackify',
43
- SUBCATEGORY: 'Log',
44
- ID: log_uuid # matching the MsgObject id
45
- )
47
+ # build span context
48
+ ctx = Span::Context.new(
49
+ CATEGORY: 'Stackify',
50
+ SUBCATEGORY: 'Log',
51
+ ID: log_uuid # matching the MsgObject id
52
+ )
53
+ rescue Exception => e
54
+ StackifyRubyAPM.agent.error "[StackifyLoggerSpy] Error: creating span context."
55
+ StackifyRubyAPM.agent.error "[StackifyLoggerSpy] #{e.inspect}"
56
+ return log_exception_task_without_apm(level, ex)
57
+ end
46
58
 
47
59
  # create log span
48
60
  StackifyRubyAPM.span(ex.message, 'stackify.log', context: ctx) do
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Monkey patch for the Yell::Logger class for logging log messages.
4
+ #
5
+ module StackifyRubyAPM
6
+ # @api private
7
+ module Spies
8
+ # @api private
9
+ class YellSpy
10
+ SEVERITIES = ['DEBUG', 'INFO', 'WARN', 'ERROR', 'FATAL', 'UNKNOWN'].freeze
11
+
12
+ def install
13
+ Yell::Logger.module_eval do
14
+ alias_method 'add_without_apm', 'add'
15
+
16
+ # Log messages
17
+ def add(options, *messages, &block)
18
+ return add_without_apm(options, *messages, &block) unless StackifyRubyAPM.current_transaction
19
+
20
+ begin
21
+ name = 'yell;'
22
+ type = 'ext.yell'
23
+ log_message = []
24
+ exception = []
25
+
26
+ messages.each { |msg|
27
+ case msg
28
+ when ::String
29
+ log_message.push(msg)
30
+ when ::Exception
31
+ log_message.push(msg.message)
32
+ exception.push("(#{ msg.class })\n#{ msg.backtrace.join("\n") if msg.backtrace }")
33
+ else
34
+ log_message.push(msg.inspect)
35
+ end
36
+ }
37
+
38
+ ctx = Span::Context.new(
39
+ CATEGORY: 'Log',
40
+ SUBCATEGORY: 'Yell',
41
+ LEVEL: SEVERITIES[options.severity],
42
+ MESSAGE: log_message.to_s
43
+ )
44
+
45
+ if exception.length > 0
46
+ ctx.EXCEPTION = exception.to_s
47
+ end
48
+ rescue Exception => e
49
+ StackifyRubyAPM.agent.error "[YellSpy] Error: creating span context."
50
+ StackifyRubyAPM.agent.error "[YellSpy] #{e.inspect}"
51
+ return add_without_apm(options, *messages, &block)
52
+ end
53
+
54
+ StackifyRubyAPM.span name, type, context: ctx do
55
+ add_without_apm(options, *messages, &block)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ register 'Yell', 'yell', YellSpy.new
63
+ end
64
+ end
@@ -8,15 +8,6 @@ module StackifyRubyAPM
8
8
  target.to_i * 1_000_000 + target.usec
9
9
  end
10
10
 
11
- #
12
- # This method will check if there is any rake task is running.
13
- # If rake task is detected we set instrument=false and don't load the spies.
14
- #
15
- def self.apm_disabled_in_rake
16
- cmd_rake = ($PROGRAM_NAME =~ /rake$/)
17
- StackifyRubyAPM.agent.config.instrument = false if cmd_rake
18
- end
19
-
20
11
  def self.host_os
21
12
  host_os = RbConfig::CONFIG['host_os']
22
13
  case host_os
@@ -34,6 +25,16 @@ module StackifyRubyAPM
34
25
  "UNKNOWN #{host_os}"
35
26
  end
36
27
  end
28
+
29
+ # Push the element to existing array of object with incremented index(key/value pair)
30
+ # We get the prepared statement values ['J.K. Rowling', 'Harry Potter', ...] and restructure it.
31
+ # Example structured: [{'1': 'J.K. Rowling'},{'2': 'Harry Potter'}, ..., {n: 'other data'}]
32
+ def self.pushToAryIndex(ary, idx, val)
33
+ obj = {}
34
+ i = idx + 1
35
+ obj[i] = val.to_s
36
+ ary.push(obj)
37
+ end
37
38
  end
38
39
  end
39
40
  require 'stackify_apm/util/inspector'
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Sets the version of the APM
4
4
  module StackifyRubyAPM
5
- VERSION = '1.10.0'.freeze
5
+ VERSION = '1.12.3'.freeze
6
6
  end
@@ -54,6 +54,7 @@ Gem::Specification.new do |spec|
54
54
  spec.add_development_dependency 'timecop'
55
55
  spec.add_development_dependency 'to_bool'
56
56
  spec.add_development_dependency 'webmock'
57
+ spec.add_development_dependency 'delayed_job'
57
58
 
58
59
  spec.add_dependency('concurrent-ruby', '~> 1.0')
59
60
  spec.add_dependency('delegate_matcher', '~> 0.4')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stackify-ruby-apm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.10.0
4
+ version: 1.12.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stackify
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-08 00:00:00.000000000 Z
11
+ date: 2020-07-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -332,6 +332,20 @@ dependencies:
332
332
  - - ">="
333
333
  - !ruby/object:Gem::Version
334
334
  version: '0'
335
+ - !ruby/object:Gem::Dependency
336
+ name: delayed_job
337
+ requirement: !ruby/object:Gem::Requirement
338
+ requirements:
339
+ - - ">="
340
+ - !ruby/object:Gem::Version
341
+ version: '0'
342
+ type: :development
343
+ prerelease: false
344
+ version_requirements: !ruby/object:Gem::Requirement
345
+ requirements:
346
+ - - ">="
347
+ - !ruby/object:Gem::Version
348
+ version: '0'
335
349
  - !ruby/object:Gem::Dependency
336
350
  name: concurrent-ruby
337
351
  requirement: !ruby/object:Gem::Requirement
@@ -419,7 +433,9 @@ files:
419
433
  - lib/stackify_apm/agent.rb
420
434
  - lib/stackify_apm/config.rb
421
435
  - lib/stackify_apm/context.rb
436
+ - lib/stackify_apm/context/prefix.rb
422
437
  - lib/stackify_apm/context/request.rb
438
+ - lib/stackify_apm/context/request/headers.rb
423
439
  - lib/stackify_apm/context/request/socket.rb
424
440
  - lib/stackify_apm/context/request/url.rb
425
441
  - lib/stackify_apm/context/response.rb
@@ -457,9 +473,13 @@ files:
457
473
  - lib/stackify_apm/spies/curb/easy.rb
458
474
  - lib/stackify_apm/spies/curb/multi.rb
459
475
  - lib/stackify_apm/spies/custom_instrumenter.rb
476
+ - lib/stackify_apm/spies/delayed_job.rb
460
477
  - lib/stackify_apm/spies/httparty.rb
461
478
  - lib/stackify_apm/spies/httpclient.rb
462
479
  - lib/stackify_apm/spies/httprb.rb
480
+ - lib/stackify_apm/spies/log4r.rb
481
+ - lib/stackify_apm/spies/logger.rb
482
+ - lib/stackify_apm/spies/logging.rb
463
483
  - lib/stackify_apm/spies/mongo.rb
464
484
  - lib/stackify_apm/spies/net_http.rb
465
485
  - lib/stackify_apm/spies/redis.rb
@@ -471,6 +491,7 @@ files:
471
491
  - lib/stackify_apm/spies/sinatra_activerecord/sqlite_adapter.rb
472
492
  - lib/stackify_apm/spies/stackify_logger.rb
473
493
  - lib/stackify_apm/spies/tilt.rb
494
+ - lib/stackify_apm/spies/yell.rb
474
495
  - lib/stackify_apm/stacktrace.rb
475
496
  - lib/stackify_apm/stacktrace/frame.rb
476
497
  - lib/stackify_apm/stacktrace_builder.rb