instana 1.195.2 → 1.197.0

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -2
  3. data/Rakefile +1 -1
  4. data/instana.gemspec +3 -7
  5. data/lib/instana.rb +3 -0
  6. data/lib/instana/activator.rb +2 -0
  7. data/lib/instana/backend/agent.rb +60 -0
  8. data/lib/instana/backend/gc_snapshot.rb +41 -0
  9. data/lib/instana/backend/host_agent.rb +74 -0
  10. data/lib/instana/backend/host_agent_activation_observer.rb +97 -0
  11. data/lib/instana/backend/host_agent_lookup.rb +57 -0
  12. data/lib/instana/backend/host_agent_reporting_observer.rb +106 -0
  13. data/lib/instana/backend/process_info.rb +64 -0
  14. data/lib/instana/backend/request_client.rb +73 -0
  15. data/lib/instana/backend/serverless_agent.rb +118 -0
  16. data/lib/instana/base.rb +8 -27
  17. data/lib/instana/config.rb +8 -22
  18. data/lib/instana/instrumentation/excon.rb +17 -8
  19. data/lib/instana/instrumentation/instrumented_request.rb +62 -7
  20. data/lib/instana/instrumentation/net-http.rb +7 -5
  21. data/lib/instana/instrumentation/rack.rb +12 -7
  22. data/lib/instana/logger_delegator.rb +31 -0
  23. data/lib/instana/{opentracing → open_tracing}/carrier.rb +0 -0
  24. data/lib/instana/open_tracing/instana_tracer.rb +99 -0
  25. data/lib/instana/secrets.rb +6 -2
  26. data/lib/instana/setup.rb +20 -11
  27. data/lib/instana/snapshot/deltable.rb +25 -0
  28. data/lib/instana/snapshot/docker_container.rb +151 -0
  29. data/lib/instana/snapshot/fargate_container.rb +88 -0
  30. data/lib/instana/snapshot/fargate_process.rb +67 -0
  31. data/lib/instana/snapshot/fargate_task.rb +72 -0
  32. data/lib/instana/snapshot/lambda_function.rb +36 -0
  33. data/lib/instana/snapshot/ruby_process.rb +48 -0
  34. data/lib/instana/tracer.rb +25 -143
  35. data/lib/instana/tracing/processor.rb +14 -22
  36. data/lib/instana/tracing/span.rb +31 -34
  37. data/lib/instana/tracing/span_context.rb +15 -10
  38. data/lib/instana/util.rb +8 -69
  39. data/lib/instana/version.rb +1 -1
  40. data/lib/opentracing.rb +26 -3
  41. data/test/backend/agent_test.rb +54 -0
  42. data/test/backend/gc_snapshot_test.rb +11 -0
  43. data/test/backend/host_agent_activation_observer_test.rb +72 -0
  44. data/test/backend/host_agent_lookup_test.rb +78 -0
  45. data/test/backend/host_agent_reporting_observer_test.rb +192 -0
  46. data/test/backend/host_agent_test.rb +47 -0
  47. data/test/backend/process_info_test.rb +63 -0
  48. data/test/backend/request_client_test.rb +39 -0
  49. data/test/backend/serverless_agent_test.rb +73 -0
  50. data/test/config_test.rb +10 -0
  51. data/test/instana_test.rb +11 -4
  52. data/test/instrumentation/excon_test.rb +15 -1
  53. data/test/instrumentation/rack_instrumented_request_test.rb +5 -2
  54. data/test/instrumentation/rack_test.rb +2 -14
  55. data/test/secrets_test.rb +41 -22
  56. data/test/snapshot/deltable_test.rb +17 -0
  57. data/test/snapshot/docker_container_test.rb +82 -0
  58. data/test/snapshot/fargate_container_test.rb +82 -0
  59. data/test/snapshot/fargate_process_test.rb +35 -0
  60. data/test/snapshot/fargate_task_test.rb +49 -0
  61. data/test/snapshot/ruby_process_test.rb +14 -0
  62. data/test/support/mock_timer.rb +20 -0
  63. data/test/test_helper.rb +16 -4
  64. data/test/tracing/custom_test.rb +1 -3
  65. data/test/tracing/id_management_test.rb +4 -0
  66. data/test/tracing/opentracing_test.rb +15 -2
  67. data/test/tracing/processor_test.rb +58 -0
  68. data/test/tracing/span_context_test.rb +21 -0
  69. data/test/tracing/span_test.rb +136 -0
  70. data/test/tracing/tracer_async_test.rb +29 -0
  71. data/test/tracing/tracer_test.rb +82 -16
  72. data/test/util_test.rb +10 -0
  73. metadata +71 -43
  74. data/lib/instana/agent.rb +0 -508
  75. data/lib/instana/agent/helpers.rb +0 -87
  76. data/lib/instana/agent/hooks.rb +0 -44
  77. data/lib/instana/agent/tasks.rb +0 -51
  78. data/lib/instana/collector.rb +0 -119
  79. data/lib/instana/collectors/gc.rb +0 -60
  80. data/lib/instana/collectors/memory.rb +0 -37
  81. data/lib/instana/collectors/thread.rb +0 -33
  82. data/lib/instana/eum/eum-test.js.erb +0 -17
  83. data/lib/instana/eum/eum.js.erb +0 -17
  84. data/lib/instana/helpers.rb +0 -47
  85. data/lib/instana/opentracing/tracer.rb +0 -21
  86. data/lib/instana/thread_local.rb +0 -18
  87. data/lib/oj_check.rb +0 -19
  88. data/test/agent/agent_test.rb +0 -151
@@ -1,87 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2018
3
-
4
- module AgentHelpers
5
- # Attempts to determine if we're running inside a container.
6
- # The qualifications are:
7
- # 1. Linux based OS
8
- # 2. /proc/self/cpuset exists and contents include a container id
9
- def running_in_container?
10
- return false unless @is_linux
11
-
12
- cpuset_contents = get_cpuset_contents
13
-
14
- if cpuset_contents.nil? or cpuset_contents == '/'
15
- ::Instana.logger.debug "running_in_container? == no"
16
- return false
17
- end
18
- ::Instana.logger.debug "running_in_container? == yes"
19
- true
20
- end
21
-
22
- # Attempts to determine the true process ID by querying the
23
- # /proc/<pid>/sched file. This works on linux currently.
24
- #
25
- def get_sched_pid
26
- sched_file = "/proc/self/sched"
27
- pid = Process.pid
28
-
29
- if File.exist?(sched_file)
30
- v = File.open(sched_file, &:readline)
31
- pid = v.match(/\d+/).to_s.to_i
32
- end
33
- pid
34
- end
35
-
36
- # Open and read /proc/<pid>/cpuset and return as a string. Used as
37
- # part of the announce payload for process differentiation.
38
- #
39
- def get_cpuset_contents
40
- cpuset_file = "/proc/#{Process.pid}/cpuset"
41
- contents = ""
42
-
43
- if File.exist?(cpuset_file)
44
- contents = File.open(cpuset_file, "r").read
45
- end
46
- contents.chomp
47
- rescue Exception => e
48
- Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
49
- return nil
50
- end
51
-
52
- # Returns the PID that we are reporting to
53
- #
54
- def report_pid
55
- @process[:report_pid]
56
- end
57
-
58
- # Determine whether the pid has changed since Agent start.
59
- #
60
- # @ return [Boolean] true or false to indicate if forked
61
- #
62
- def forked?
63
- @process[:pid] != Process.pid
64
- end
65
-
66
- # Indicates if the agent is ready to send metrics
67
- # and/or data.
68
- #
69
- def ready?
70
- # In test, we're always ready :-)
71
- return true if ENV.key?('INSTANA_TEST')
72
-
73
- # Occasionally Run Fork detection
74
- if rand(10) > 8
75
- if !@is_resque_worker && (@process[:pid] != Process.pid)
76
- ::Instana.logger.debug "Instana: detected fork. (this pid: #{Process.pid}/#{Process.ppid}) Calling after_fork"
77
- after_fork
78
- end
79
- end
80
-
81
- @state == :ready || @state == :announced
82
- rescue => e
83
- Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
84
- Instana.logger.debug { e.backtrace.join("\r\n") } unless ENV.key?('INSTANA_TEST')
85
- return false
86
- end
87
- end
@@ -1,44 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2018
3
-
4
- module AgentHooks
5
- # Used post fork to re-initialize state and restart communications with
6
- # the host agent.
7
- #
8
- def after_fork
9
- ::Instana.logger.debug "after_fork hook called. Falling back to unannounced state and spawning a new background agent thread."
10
-
11
- @timers.cancel
12
-
13
- # Reseed the random number generator for this
14
- # new thread.
15
- srand
16
-
17
- transition_to(:unannounced)
18
-
19
- setup
20
- spawn_background_thread
21
- end
22
-
23
- def before_resque_fork
24
- ::Instana.logger.debug "before_resque_fork hook called. pid/ppid: #{Process.pid}/#{Process.ppid}"
25
- @is_resque_worker = true
26
- end
27
-
28
- def after_resque_fork
29
- ::Instana.logger.debug "after_resque_fork hook called. pid/ppid: #{Process.pid}/#{Process.ppid}"
30
-
31
- @timers.cancel
32
-
33
- # Reseed the random number generator for this
34
- # new thread.
35
- srand
36
-
37
- ::Instana.config[:metrics][:enabled] = false
38
-
39
- @process[:pid] = Process.pid
40
-
41
- setup
42
- spawn_background_thread
43
- end
44
- end
@@ -1,51 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2018
3
-
4
- module AgentTasks
5
- # When request(s) are received by the host agent, it is sent here
6
- # for handling & processing.
7
- #
8
- # @param json_string [String] the requests from the host agent
9
- #
10
-
11
- OJ_OPTIONS = {mode: :strict}
12
-
13
- def handle_agent_tasks(json_string)
14
- tasks = Oj.load(json_string, OJ_OPTIONS)
15
-
16
- if tasks.is_a?(Hash)
17
- process_agent_task(tasks)
18
- elsif tasks.is_a?(Array)
19
- tasks.each do |t|
20
- process_agent_task(t)
21
- end
22
- end
23
- end
24
-
25
- # Process a task sent from the host agent.
26
- #
27
- # @param task [String] the request json from the host agent
28
- #
29
- def process_agent_task(task)
30
- if task.key?("action")
31
- if task["action"] == "ruby.source"
32
- payload = ::Instana::Util.get_rb_source(task["args"]["file"])
33
- else
34
- payload = { :error => "Unrecognized action: #{task["action"]}. An newer Instana gem may be required for this. Current version: #{::Instana::VERSION}" }
35
- end
36
- else
37
- payload = { :error => "Instana Ruby: No action specified in request." }
38
- end
39
-
40
- path = "com.instana.plugin.ruby/response.#{@process[:report_pid]}?messageId=#{URI.encode(task['messageId'])}"
41
- uri = URI.parse("http://#{@discovered[:agent_host]}:#{@discovered[:agent_port]}/#{path}")
42
- req = Net::HTTP::Post.new(uri)
43
- req.body = Oj.dump(payload, OJ_OPTIONS)
44
- ::Instana.logger.debug "Responding to agent request: #{req.inspect}"
45
- make_host_agent_request(req)
46
-
47
- rescue StandardError => e
48
- Instana.logger.debug { "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}" }
49
- Instana.logger.debug { e.backtrace.join("\r\n") }
50
- end
51
- end
@@ -1,119 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2016
3
-
4
- module Instana
5
- class Collector
6
- attr_accessor :collectors
7
- attr_accessor :last_report_log
8
-
9
- def initialize
10
- @collectors = []
11
-
12
- # Snapshot data is collected once per process but resent
13
- # every 10 minutes along side process metrics.
14
- @snapshot = ::Instana::Util.take_snapshot
15
-
16
- # Set last snapshot to just under 10 minutes ago
17
- # so we send a snapshot sooner than later
18
- @last_snapshot = Time.now - 570
19
-
20
- # We track what we last sent as a metric payload so that
21
- # we can do delta reporting
22
- @last_values = {}
23
- end
24
-
25
- # Register an individual collector.
26
- #
27
- # @param [Object] klass of the collector to register
28
- #
29
- def register(klass)
30
- ::Instana.logger.debug "Adding #{klass} to collectors..."
31
- @collectors << klass.new
32
- end
33
-
34
- # Resets the timer on when to send process snapshot data.
35
- #
36
- def reset_snapshot_timer!
37
- # Set last snapshot to 10 minutes ago
38
- # so that we send a snapshot on first report
39
- @last_snapshot = Time.now - 601
40
- end
41
-
42
- ##
43
- # collect_and_report
44
- #
45
- # Run through each collector, let them collect up
46
- # data and then report what we have via the agent
47
- #
48
- # @return Boolean true on success
49
- #
50
- def collect_and_report
51
- return unless ::Instana.config[:metrics][:enabled]
52
-
53
- payload = {}
54
- with_snapshot = false
55
-
56
- # Run through the registered collectors and
57
- # get all the metrics
58
- #
59
- @collectors.each do |c|
60
- metrics = c.collect
61
- if metrics
62
- payload[c.payload_key] = metrics
63
- else
64
- payload.delete(c.payload_key)
65
- end
66
- end
67
-
68
- # Every 5 minutes, send snapshot data as well
69
- if (Time.now - @last_snapshot) > 600
70
- with_snapshot = true
71
- payload.merge!(@snapshot)
72
-
73
- # Add in process related that could have changed since
74
- # snapshot was taken.
75
- p = { :pid => ::Instana.agent.report_pid }
76
- p[:name] = ::Instana::Util.get_app_name
77
- p[:exec_args] = ::Instana.agent.process[:arguments]
78
- payload.merge!(p)
79
- else
80
- payload = enforce_deltas(payload, @last_values)
81
- end
82
-
83
- if ENV.key?('INSTANA_TEST')
84
- true
85
- else
86
- # Report all the collected goodies
87
- if ::Instana.agent.report_metrics(payload) && with_snapshot
88
- @last_snapshot = Time.now
89
- end
90
- end
91
- end
92
-
93
- # Take two hashes and enforce delta reporting.
94
- # We only report when values change (instead of reporting all of
95
- # the time). This is a recursive method.
96
- #
97
- # @param [Hash] the payload have delta reporting applied to
98
- # @param [Hash] a hash of the last values reported
99
- #
100
- # @return [Hash] the candidate hash with delta reporting applied
101
- #
102
- def enforce_deltas(candidate, last)
103
- candidate.each do |k,v|
104
- if v.is_a?(Hash)
105
- last[k] ||= {}
106
- candidate[k] = enforce_deltas(candidate[k], last[k])
107
- candidate.delete(k) if candidate[k].empty?
108
- else
109
- if last[k] == v
110
- candidate.delete(k)
111
- else
112
- last[k] = candidate[k]
113
- end
114
- end
115
- end
116
- candidate
117
- end
118
- end
119
- end
@@ -1,60 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2016
3
-
4
- module Instana
5
- module Collectors
6
- class GC
7
- attr_accessor :payload_key
8
-
9
- def initialize
10
- @payload_key = :gc
11
- @this_gc = {}
12
- @last_major_count = 0
13
- @last_minor_count = 0
14
- ::GC::Profiler.enable
15
- end
16
-
17
- ##
18
- # collect
19
- #
20
- # To collect garbage collector related metrics.
21
- #
22
- def collect
23
- @this_gc.clear
24
- stats = ::GC.stat
25
-
26
- # Time spent in GC. Report in milliseconds
27
- @this_gc[:totalTime] = ::GC::Profiler.total_time * 1000
28
- ::GC::Profiler.clear
29
-
30
- # GC metrics only available on newer Ruby versions
31
- if RUBY_VERSION >= '2.1'
32
- # GC runs. Calculate how many have occurred since the last call
33
- @this_gc[:minorGcs] = stats[:minor_gc_count] - @last_minor_count
34
- @this_gc[:majorGcs] = stats[:major_gc_count] - @last_major_count
35
-
36
- # Store these counts so that we have something to compare to next
37
- # time around.
38
- @last_major_count = stats[:major_gc_count]
39
- @last_minor_count = stats[:minor_gc_count]
40
-
41
- @this_gc[:heap_live] = stats[:heap_live_slots] || stats[:heap_live_num]
42
- @this_gc[:heap_free] = stats[:heap_free_slots] || stats[:heap_free_num]
43
- else
44
- @this_gc[:heap_live] = stats[:heap_live_slot] || stats[:heap_live_num]
45
- @this_gc[:heap_free] = stats[:heap_free_slot] || stats[:heap_free_num]
46
- end
47
-
48
- @this_gc
49
- rescue => e
50
- ::Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
51
- ::Instana.logger.debug { e.backtrace.join("\r\n") }
52
- end
53
- end
54
- end
55
- end
56
-
57
- # Register the metrics collector if enabled
58
- if ::Instana.config[:metrics][:gc][:enabled]
59
- ::Instana.collector.register(::Instana::Collectors::GC)
60
- end
@@ -1,37 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2016
3
-
4
- require 'get_process_mem'
5
-
6
- module Instana
7
- module Collectors
8
- class Memory
9
- attr_accessor :payload_key
10
-
11
- def initialize
12
- @payload_key = :memory
13
- @this_mem = {}
14
- end
15
-
16
- ##
17
- # collect
18
- #
19
- # To collect process memory usage.
20
- #
21
- # @return [Hash] a collection of metrics (if any)
22
- #
23
- def collect
24
- @this_mem[:rss_size] = ::GetProcessMem.new(Process.pid).kb
25
- @this_mem
26
- rescue => e
27
- ::Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
28
- ::Instana.logger.debug { e.backtrace.join("\r\n") }
29
- end
30
- end
31
- end
32
- end
33
-
34
- # Register the metrics collector if enabled
35
- if ::Instana.config[:metrics][:memory][:enabled]
36
- ::Instana.collector.register(::Instana::Collectors::Memory)
37
- end
@@ -1,33 +0,0 @@
1
- # (c) Copyright IBM Corp. 2021
2
- # (c) Copyright Instana Inc. 2016
3
-
4
- module Instana
5
- module Collectors
6
- class Thread
7
- attr_accessor :payload_key
8
-
9
- def initialize
10
- @payload_key = :thread
11
- @this_count = {}
12
- end
13
-
14
- ##
15
- # collect
16
- #
17
- # To collect thread count
18
- #
19
- def collect
20
- @this_count[:count] = ::Thread.list.count
21
- @this_count
22
- rescue => e
23
- ::Instana.logger.info "#{__method__}:#{File.basename(__FILE__)}:#{__LINE__}: #{e.message}"
24
- ::Instana.logger.debug { e.backtrace.join("\r\n") }
25
- end
26
- end
27
- end
28
- end
29
-
30
- # Register the metrics collector if enabled
31
- if ::Instana.config[:metrics][:thread][:enabled]
32
- ::Instana.collector.register(::Instana::Collectors::Thread)
33
- end
@@ -1,17 +0,0 @@
1
- <script>
2
- (function(c,e,f,k,g,h,b,a,d){c[g]||(c[g]=h,b=c[h]=function(){
3
- b.q.push(arguments)},b.q=[],b.l=1*new Date,a=e.createElement(f),a.async=1,
4
- a.src=k,a.setAttribute("crossorigin", "anonymous"),d=e.getElementsByTagName(f)[0],
5
- d.parentNode.insertBefore(a,d))})(window,document,"script",
6
- "//pink.instana.rocks/eum/eum.min.js","InstanaEumObject","ineum");
7
-
8
- ineum('reportingUrl', 'https://pink.instana.rocks/eum/');
9
- ineum('key', '<%=::Instana.config[:eum_api_key]%>');
10
- ineum('traceId', '<%=::Instana.tracer.trace_id_header%>');
11
-
12
- <% if !::Instana.config[:eum_baggage].empty? %>
13
- <% ::Instana.config[:eum_baggage].each do |k, v| %>
14
- ineum('meta', '<%=k%>', '<%=v%>');
15
- <% end %>
16
- <% end %>
17
- </script>