instana 1.11.6 → 1.209.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (274) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +263 -0
  3. data/.editorconfig +10 -0
  4. data/.github/ISSUE_TEMPLATE/bug.yml +39 -0
  5. data/.github/ISSUE_TEMPLATE/config.yml +5 -0
  6. data/.gitignore +3 -0
  7. data/.rubocop.yml +14 -1136
  8. data/.rubocop_todo.yml +1140 -0
  9. data/Appraisals +124 -0
  10. data/Gemfile +14 -32
  11. data/LICENSE +2 -1
  12. data/README.md +2 -6
  13. data/Rakefile +18 -49
  14. data/bin/console +8 -4
  15. data/docker-compose.yml +20 -0
  16. data/examples/opentracing.rb +4 -0
  17. data/examples/tracing.rb +4 -0
  18. data/extras/license_header.rb +44 -0
  19. data/gemfiles/.bundle/config +1 -2
  20. data/gemfiles/aws_30.gemfile +22 -0
  21. data/gemfiles/cuba_30.gemfile +18 -0
  22. data/gemfiles/dalli_20.gemfile +18 -0
  23. data/gemfiles/excon_02.gemfile +18 -0
  24. data/gemfiles/excon_021.gemfile +18 -0
  25. data/gemfiles/excon_079.gemfile +18 -0
  26. data/gemfiles/graphql_10.gemfile +18 -0
  27. data/gemfiles/grpc_10.gemfile +18 -0
  28. data/gemfiles/mongo_216.gemfile +18 -0
  29. data/gemfiles/net_http_01.gemfile +17 -0
  30. data/gemfiles/rack_16.gemfile +18 -0
  31. data/gemfiles/rack_20.gemfile +18 -0
  32. data/gemfiles/rails_42.gemfile +21 -0
  33. data/gemfiles/rails_50.gemfile +21 -0
  34. data/gemfiles/rails_52.gemfile +21 -0
  35. data/gemfiles/rails_60.gemfile +21 -0
  36. data/gemfiles/redis_40.gemfile +18 -0
  37. data/gemfiles/resque_122.gemfile +19 -0
  38. data/gemfiles/resque_20.gemfile +18 -0
  39. data/gemfiles/rest_client_16.gemfile +18 -0
  40. data/gemfiles/rest_client_20.gemfile +18 -0
  41. data/gemfiles/roda_20.gemfile +18 -0
  42. data/gemfiles/roda_30.gemfile +18 -0
  43. data/gemfiles/shoryuken_50.gemfile +19 -0
  44. data/gemfiles/sidekiq_42.gemfile +18 -0
  45. data/gemfiles/sidekiq_50.gemfile +18 -0
  46. data/gemfiles/sinatra_14.gemfile +18 -0
  47. data/instana.gemspec +8 -14
  48. data/lib/instana/activator.rb +58 -0
  49. data/lib/instana/activators/action_cable.rb +24 -0
  50. data/lib/instana/activators/action_controller_api.rb +21 -0
  51. data/lib/instana/activators/action_controller_base.rb +21 -0
  52. data/lib/instana/activators/action_mailer.rb +22 -0
  53. data/lib/instana/activators/action_view.rb +21 -0
  54. data/lib/instana/activators/active_job.rb +21 -0
  55. data/lib/instana/activators/active_record.rb +21 -0
  56. data/lib/instana/activators/aws_sdk_dynamodb.rb +20 -0
  57. data/lib/instana/activators/aws_sdk_lambda.rb +20 -0
  58. data/lib/instana/activators/aws_sdk_s3.rb +20 -0
  59. data/lib/instana/activators/aws_sdk_sns.rb +20 -0
  60. data/lib/instana/activators/aws_sdk_sqs.rb +20 -0
  61. data/lib/instana/activators/cuba.rb +21 -0
  62. data/lib/instana/activators/dalli.rb +23 -0
  63. data/lib/instana/activators/excon.rb +20 -0
  64. data/lib/instana/activators/graphql.rb +22 -0
  65. data/lib/instana/activators/grpc_client.rb +20 -0
  66. data/lib/instana/activators/grpc_server.rb +20 -0
  67. data/lib/instana/activators/mongo.rb +23 -0
  68. data/lib/instana/activators/net_http.rb +20 -0
  69. data/lib/instana/activators/rack.rb +16 -0
  70. data/lib/instana/activators/rails.rb +18 -0
  71. data/lib/instana/activators/redis.rb +20 -0
  72. data/lib/instana/activators/resque_client.rb +21 -0
  73. data/lib/instana/activators/resque_worker.rb +32 -0
  74. data/lib/instana/activators/rest_client.rb +20 -0
  75. data/lib/instana/activators/roda.rb +21 -0
  76. data/lib/instana/activators/shoryuken.rb +24 -0
  77. data/lib/instana/activators/sidekiq_client.rb +24 -0
  78. data/lib/instana/activators/sidekiq_worker.rb +24 -0
  79. data/lib/instana/activators/sinatra.rb +21 -0
  80. data/lib/instana/backend/agent.rb +68 -0
  81. data/lib/instana/backend/gc_snapshot.rb +41 -0
  82. data/lib/instana/backend/host_agent.rb +83 -0
  83. data/lib/instana/backend/host_agent_activation_observer.rb +99 -0
  84. data/lib/instana/backend/host_agent_lookup.rb +57 -0
  85. data/lib/instana/backend/host_agent_reporting_observer.rb +129 -0
  86. data/lib/instana/backend/process_info.rb +72 -0
  87. data/lib/instana/backend/request_client.rb +74 -0
  88. data/lib/instana/backend/serverless_agent.rb +116 -0
  89. data/lib/instana/base.rb +15 -29
  90. data/lib/instana/config.rb +31 -23
  91. data/lib/instana/frameworks/cuba.rb +32 -3
  92. data/lib/instana/frameworks/rails.rb +22 -32
  93. data/lib/instana/frameworks/roda.rb +41 -3
  94. data/lib/instana/frameworks/sinatra.rb +16 -3
  95. data/lib/instana/instrumentation/action_cable.rb +53 -0
  96. data/lib/instana/instrumentation/action_controller.rb +84 -0
  97. data/lib/instana/instrumentation/action_mailer.rb +22 -0
  98. data/lib/instana/instrumentation/action_view.rb +30 -0
  99. data/lib/instana/instrumentation/active_job.rb +52 -0
  100. data/lib/instana/instrumentation/active_record.rb +50 -0
  101. data/lib/instana/instrumentation/aws_sdk_dynamodb.rb +48 -0
  102. data/lib/instana/instrumentation/aws_sdk_lambda.rb +37 -0
  103. data/lib/instana/instrumentation/aws_sdk_s3.rb +55 -0
  104. data/lib/instana/instrumentation/aws_sdk_sns.rb +29 -0
  105. data/lib/instana/instrumentation/aws_sdk_sqs.rb +98 -0
  106. data/lib/instana/instrumentation/dalli.rb +10 -18
  107. data/lib/instana/instrumentation/excon.rb +73 -61
  108. data/lib/instana/instrumentation/graphql.rb +78 -0
  109. data/lib/instana/instrumentation/grpc.rb +73 -66
  110. data/lib/instana/instrumentation/instrumented_request.rb +190 -0
  111. data/lib/instana/instrumentation/mongo.rb +46 -0
  112. data/lib/instana/instrumentation/net-http.rb +54 -44
  113. data/lib/instana/instrumentation/rack.rb +57 -48
  114. data/lib/instana/instrumentation/redis.rb +13 -18
  115. data/lib/instana/instrumentation/resque.rb +28 -51
  116. data/lib/instana/instrumentation/rest-client.rb +5 -17
  117. data/lib/instana/instrumentation/shoryuken.rb +44 -0
  118. data/lib/instana/instrumentation/sidekiq-client.rb +4 -10
  119. data/lib/instana/instrumentation/sidekiq-worker.rb +4 -10
  120. data/lib/instana/instrumented_logger.rb +26 -0
  121. data/lib/instana/logger_delegator.rb +31 -0
  122. data/lib/instana/open_tracing/carrier.rb +7 -0
  123. data/lib/instana/open_tracing/instana_tracer.rb +99 -0
  124. data/lib/instana/rack.rb +4 -0
  125. data/lib/instana/secrets.rb +59 -0
  126. data/lib/instana/serverless.rb +160 -0
  127. data/lib/instana/setup.rb +36 -12
  128. data/lib/instana/snapshot/deltable.rb +25 -0
  129. data/lib/instana/snapshot/docker_container.rb +151 -0
  130. data/lib/instana/snapshot/fargate_container.rb +88 -0
  131. data/lib/instana/snapshot/fargate_process.rb +67 -0
  132. data/lib/instana/snapshot/fargate_task.rb +72 -0
  133. data/lib/instana/snapshot/google_cloud_run_instance.rb +69 -0
  134. data/lib/instana/snapshot/google_cloud_run_process.rb +58 -0
  135. data/lib/instana/snapshot/lambda_function.rb +39 -0
  136. data/lib/instana/snapshot/ruby_process.rb +48 -0
  137. data/lib/instana/tracer.rb +42 -148
  138. data/lib/instana/tracing/processor.rb +48 -21
  139. data/lib/instana/tracing/span.rb +70 -61
  140. data/lib/instana/tracing/span_context.rb +34 -2
  141. data/lib/instana/util.rb +25 -137
  142. data/lib/instana/version.rb +4 -1
  143. data/lib/instana.rb +12 -2
  144. data/lib/opentracing.rb +29 -3
  145. data/sonar-project.properties +9 -0
  146. data/test/activator_test.rb +30 -0
  147. data/test/backend/agent_test.rb +80 -0
  148. data/test/backend/gc_snapshot_test.rb +11 -0
  149. data/test/backend/host_agent_activation_observer_test.rb +73 -0
  150. data/test/backend/host_agent_lookup_test.rb +78 -0
  151. data/test/backend/host_agent_reporting_observer_test.rb +274 -0
  152. data/test/backend/host_agent_test.rb +57 -0
  153. data/test/backend/process_info_test.rb +83 -0
  154. data/test/backend/request_client_test.rb +39 -0
  155. data/test/backend/serverless_agent_test.rb +83 -0
  156. data/test/benchmarks/bench_id_generation.rb +3 -0
  157. data/test/benchmarks/bench_opentracing.rb +3 -0
  158. data/test/config_test.rb +11 -14
  159. data/test/frameworks/cuba_test.rb +44 -30
  160. data/test/frameworks/roda_test.rb +46 -30
  161. data/test/frameworks/sinatra_test.rb +52 -30
  162. data/test/instana_test.rb +14 -4
  163. data/test/instrumentation/aws_test.rb +196 -0
  164. data/test/instrumentation/dalli_test.rb +3 -0
  165. data/test/instrumentation/excon_test.rb +20 -3
  166. data/test/instrumentation/graphql_test.rb +119 -0
  167. data/test/instrumentation/grpc_test.rb +6 -2
  168. data/test/instrumentation/mongo_test.rb +37 -0
  169. data/test/instrumentation/{net-http_test.rb → net_http_test.rb} +40 -0
  170. data/test/instrumentation/rack_instrumented_request_test.rb +151 -0
  171. data/test/instrumentation/rack_test.rb +404 -0
  172. data/test/instrumentation/rails_action_cable_test.rb +131 -0
  173. data/test/{frameworks/rails/actioncontroller_test.rb → instrumentation/rails_action_controller_test.rb} +48 -17
  174. data/test/instrumentation/rails_action_mailer_test.rb +37 -0
  175. data/test/instrumentation/rails_action_view_test.rb +151 -0
  176. data/test/instrumentation/rails_active_job_test.rb +65 -0
  177. data/test/instrumentation/rails_active_record_database_missing_test.rb +43 -0
  178. data/test/instrumentation/rails_active_record_test.rb +115 -0
  179. data/test/instrumentation/redis_test.rb +13 -0
  180. data/test/instrumentation/resque_test.rb +63 -17
  181. data/test/instrumentation/{rest-client_test.rb → rest_client_test.rb} +9 -0
  182. data/test/instrumentation/shoryuken_test.rb +47 -0
  183. data/test/instrumentation/sidekiq-client_test.rb +4 -0
  184. data/test/instrumentation/sidekiq-worker_test.rb +4 -0
  185. data/test/secrets_test.rb +112 -0
  186. data/test/serverless_test.rb +369 -0
  187. data/test/snapshot/deltable_test.rb +17 -0
  188. data/test/snapshot/docker_container_test.rb +82 -0
  189. data/test/snapshot/fargate_container_test.rb +82 -0
  190. data/test/snapshot/fargate_process_test.rb +35 -0
  191. data/test/snapshot/fargate_task_test.rb +49 -0
  192. data/test/snapshot/google_cloud_run_instance_test.rb +74 -0
  193. data/test/snapshot/google_cloud_run_process_test.rb +33 -0
  194. data/test/snapshot/lambda_function_test.rb +37 -0
  195. data/test/snapshot/ruby_process_test.rb +14 -0
  196. data/test/support/apps/active_record/active_record.rb +24 -0
  197. data/test/{servers/grpc_50051.rb → support/apps/grpc/boot.rb} +4 -1
  198. data/test/{apps → support/apps/grpc}/grpc_server.rb +3 -0
  199. data/test/{servers/rackapp_6511.rb → support/apps/http_endpoint/boot.rb} +3 -0
  200. data/test/{servers/rails_3205.rb → support/apps/rails/boot.rb} +10 -13
  201. data/test/{models → support/apps/rails/models}/block.rb +4 -1
  202. data/test/{models → support/apps/rails/models}/block6.rb +3 -0
  203. data/test/support/apps/resque/boot.rb +5 -0
  204. data/test/{jobs → support/apps/resque/jobs}/resque_error_job.rb +3 -3
  205. data/test/{jobs → support/apps/resque/jobs}/resque_fast_job.rb +6 -3
  206. data/test/support/apps/sidekiq/boot.rb +25 -0
  207. data/test/{jobs → support/apps/sidekiq/jobs}/sidekiq_job_1.rb +3 -0
  208. data/test/{jobs → support/apps/sidekiq/jobs}/sidekiq_job_2.rb +3 -0
  209. data/test/{servers → support/apps}/sidekiq/worker.rb +5 -2
  210. data/test/support/helpers.rb +97 -0
  211. data/test/support/mock_timer.rb +20 -0
  212. data/test/test_helper.rb +49 -145
  213. data/test/tracing/custom_test.rb +4 -4
  214. data/test/tracing/id_management_test.rb +13 -63
  215. data/test/tracing/instrumented_logger_test.rb +39 -0
  216. data/test/tracing/opentracing_test.rb +21 -5
  217. data/test/tracing/processor_test.rb +58 -0
  218. data/test/tracing/span_context_test.rb +22 -0
  219. data/test/tracing/span_test.rb +165 -0
  220. data/test/tracing/tracer_async_test.rb +32 -0
  221. data/test/tracing/tracer_test.rb +113 -14
  222. data/test/util_test.rb +10 -0
  223. metadata +249 -160
  224. data/.travis.yml +0 -43
  225. data/Dockerfile +0 -16
  226. data/benchmarks/10k-rack-traces.rb +0 -92
  227. data/benchmarks/Gemfile +0 -7
  228. data/benchmarks/Gemfile.lock +0 -38
  229. data/benchmarks/id_generation.rb +0 -12
  230. data/benchmarks/opentracing.rb +0 -26
  231. data/benchmarks/rack_vanilla_vs_traced.rb +0 -85
  232. data/benchmarks/stackprof_rack_tracing.rb +0 -77
  233. data/benchmarks/time_processing.rb +0 -12
  234. data/gemfiles/libraries.gemfile +0 -71
  235. data/gemfiles/rails32.gemfile +0 -51
  236. data/gemfiles/rails42.gemfile +0 -50
  237. data/gemfiles/rails50.gemfile +0 -52
  238. data/gemfiles/rails52.gemfile +0 -52
  239. data/gemfiles/rails60.gemfile +0 -72
  240. data/lib/instana/agent/helpers.rb +0 -84
  241. data/lib/instana/agent/hooks.rb +0 -41
  242. data/lib/instana/agent/tasks.rb +0 -48
  243. data/lib/instana/agent.rb +0 -499
  244. data/lib/instana/collector.rb +0 -116
  245. data/lib/instana/collectors/gc.rb +0 -57
  246. data/lib/instana/collectors/memory.rb +0 -34
  247. data/lib/instana/collectors/thread.rb +0 -30
  248. data/lib/instana/eum/eum-test.js.erb +0 -17
  249. data/lib/instana/eum/eum.js.erb +0 -17
  250. data/lib/instana/frameworks/instrumentation/abstract_mysql_adapter.rb +0 -58
  251. data/lib/instana/frameworks/instrumentation/action_controller.rb +0 -183
  252. data/lib/instana/frameworks/instrumentation/action_view.rb +0 -43
  253. data/lib/instana/frameworks/instrumentation/active_record.rb +0 -27
  254. data/lib/instana/frameworks/instrumentation/mysql2_adapter.rb +0 -81
  255. data/lib/instana/frameworks/instrumentation/mysql_adapter.rb +0 -56
  256. data/lib/instana/frameworks/instrumentation/postgresql_adapter.rb +0 -85
  257. data/lib/instana/helpers.rb +0 -44
  258. data/lib/instana/instrumentation.rb +0 -25
  259. data/lib/instana/opentracing/carrier.rb +0 -4
  260. data/lib/instana/opentracing/tracer.rb +0 -18
  261. data/lib/instana/test.rb +0 -42
  262. data/lib/instana/thread_local.rb +0 -15
  263. data/lib/oj_check.rb +0 -16
  264. data/test/agent/agent_test.rb +0 -148
  265. data/test/apps/cuba.rb +0 -15
  266. data/test/apps/roda.rb +0 -10
  267. data/test/apps/sinatra.rb +0 -5
  268. data/test/frameworks/rack_test.rb +0 -200
  269. data/test/frameworks/rails/actionview3_test.rb +0 -210
  270. data/test/frameworks/rails/actionview4_test.rb +0 -208
  271. data/test/frameworks/rails/actionview5_test.rb +0 -221
  272. data/test/frameworks/rails/activerecord_test.rb +0 -227
  273. data/test/servers/helpers/sidekiq_worker_initializer.rb +0 -27
  274. data/test/tracing/trace_test.rb +0 -67
data/lib/instana/setup.rb CHANGED
@@ -1,23 +1,47 @@
1
- require 'oj_check'
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2016
3
+
4
+ require 'logger'
5
+ require 'concurrent'
6
+ require 'sys-proctable'
7
+
8
+ require 'instana/logger_delegator'
9
+ require 'instana/instrumented_logger'
2
10
 
3
11
  require "instana/base"
4
12
  require "instana/config"
5
- require "instana/agent"
6
- require "instana/collector"
13
+ require "instana/secrets"
7
14
  require "instana/tracer"
8
15
  require "instana/tracing/processor"
9
- require "instana/instrumentation"
10
16
 
11
- ::Instana.setup
12
- ::Instana.agent.setup
17
+ require 'instana/serverless'
18
+
19
+ require 'instana/activator'
13
20
 
14
- # Register the metric collectors
15
- unless RUBY_PLATFORM == 'java'.freeze
16
- require 'instana/collectors/gc'
17
- end
21
+ require 'instana/backend/request_client'
22
+ require 'instana/backend/gc_snapshot'
23
+ require 'instana/backend/process_info'
18
24
 
19
- require 'instana/collectors/memory'
20
- require 'instana/collectors/thread'
25
+ require 'instana/snapshot/deltable'
26
+ require 'instana/snapshot/ruby_process'
27
+ require 'instana/snapshot/fargate_process'
28
+ require 'instana/snapshot/fargate_task'
29
+ require 'instana/snapshot/fargate_container'
30
+ require 'instana/snapshot/docker_container'
31
+ require 'instana/snapshot/lambda_function'
32
+ require 'instana/snapshot/google_cloud_run_instance'
33
+ require 'instana/snapshot/google_cloud_run_process'
34
+
35
+ require 'instana/backend/host_agent_lookup'
36
+ require 'instana/backend/host_agent_activation_observer'
37
+ require 'instana/backend/host_agent_reporting_observer'
38
+
39
+ require 'instana/backend/host_agent'
40
+ require 'instana/backend/serverless_agent'
41
+ require 'instana/backend/agent'
42
+
43
+ ::Instana.setup
44
+ ::Instana.agent.setup
21
45
 
22
46
  # Require supported OpenTracing interfaces
23
47
  require "opentracing"
@@ -0,0 +1,25 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # @since 1.197.0
7
+ module Deltable
8
+ def delta(key, *rest, compute:, obj:, path: [key, *rest])
9
+ val = obj[key]
10
+ return val if val == nil
11
+
12
+ if rest.empty?
13
+ @__delta ||= Hash.new(0)
14
+ cache_key = path.join('.')
15
+ old = @__delta[cache_key]
16
+ @__delta[cache_key] = val
17
+
18
+ return compute.call(old, val)
19
+ end
20
+
21
+ delta(*rest, compute: compute, obj: val, path: path)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,151 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # Describes a Docker container visible to the current process
7
+ # @since 1.197.0
8
+ class DockerContainer
9
+ include Deltable
10
+ ID = 'com.instana.plugin.docker'.freeze
11
+
12
+ def initialize(container, metadata_uri: ENV['ECS_CONTAINER_METADATA_URI'])
13
+ @container = container
14
+ @metadata_uri = URI(metadata_uri)
15
+ @client = Backend::RequestClient.new(@metadata_uri.host, @metadata_uri.port, use_ssl: @metadata_uri.scheme == "https")
16
+ end
17
+
18
+ def entity_id
19
+ "#{@container['Labels']['com.amazonaws.ecs.task-arn']}::#{@container['Name']}"
20
+ end
21
+
22
+ def data
23
+ metrics = lookup('/task/stats').fetch(@container['DockerId'], {})
24
+
25
+ container_metrics(metrics)
26
+ .merge(container_metadata)
27
+ end
28
+
29
+ def snapshot
30
+ {
31
+ name: ID,
32
+ entityId: entity_id,
33
+ data: data
34
+ }
35
+ end
36
+
37
+ private
38
+
39
+ def container_metadata
40
+ {
41
+ Id: @container['DockerId'],
42
+ Created: @container['CreatedAt'],
43
+ Started: @container['StartedAt'],
44
+ Image: @container['Image'],
45
+ Labels: @container['Labels'],
46
+ Ports: @container['Ports'],
47
+ NetworkMode: @container['Networks'].first['NetworkMode']
48
+ }
49
+ end
50
+
51
+ def container_metrics(metrics)
52
+ return {} if metrics.empty?
53
+
54
+ {
55
+ memory: memory_stats(metrics),
56
+ blkio: blkio_stats(metrics),
57
+ cpu: cpu_stats(metrics),
58
+ network: network_stats(metrics)
59
+ }.reject { |_, v| v.nil? }
60
+ end
61
+
62
+ def memory_stats(metrics)
63
+ identity = ->(_old, new) { new }
64
+
65
+ {
66
+ active_anon: delta('memory_stats', 'stats', 'active_anon', compute: identity, obj: metrics),
67
+ active_file: delta('memory_stats', 'stats', 'active_file', compute: identity, obj: metrics),
68
+ inactive_anon: delta('memory_stats', 'stats', 'inactive_anon', compute: identity, obj: metrics),
69
+ inactive_file: delta('memory_stats', 'stats', 'inactive_file', compute: identity, obj: metrics),
70
+ total_cache: delta('memory_stats', 'stats', 'total_cache', compute: identity, obj: metrics),
71
+ total_rss: delta('memory_stats', 'stats', 'total_rss', compute: identity, obj: metrics),
72
+ usage: delta('memory_stats', 'usage', compute: identity, obj: metrics),
73
+ max_usage: delta('memory_stats', 'max_usage', compute: identity, obj: metrics),
74
+ limit: delta('memory_stats', 'limit', compute: identity, obj: metrics)
75
+ }
76
+ end
77
+
78
+ def blkio_stats(metrics)
79
+ delta = ->(old, new) { new - old }
80
+ bytes = {
81
+ 'block_bytes' => metrics['blkio_stats']['io_service_bytes_recursive'].map { |r| [r['op'], r['value']] }.to_h
82
+ }
83
+
84
+ {
85
+ blk_read: delta('block_bytes', 'Read', compute: delta, obj: bytes),
86
+ blk_write: delta('block_bytes', 'Write', compute: delta, obj: bytes)
87
+ }
88
+ end
89
+
90
+ def cpu_stats(metrics)
91
+ delta = ->(old, new) { new - old }
92
+ identity = ->(_old, new) { new }
93
+
94
+ cpu_system_delta = delta('cpu_stats', 'system_cpu_usage', compute: delta, obj: metrics).to_f
95
+ online_cpus = delta('cpu_stats', 'online_cpus', compute: identity, obj: metrics) || 1
96
+
97
+ {
98
+ total_usage: (delta('cpu_stats', 'cpu_usage', 'total_usage', compute: delta, obj: metrics) / cpu_system_delta) * online_cpus,
99
+ user_usage: (delta('cpu_stats', 'cpu_usage', 'usage_in_usermode', compute: delta, obj: metrics) / cpu_system_delta) * online_cpus,
100
+ system_usage: (delta('cpu_stats', 'cpu_usage', 'usage_in_kernelmode', compute: delta, obj: metrics) / cpu_system_delta) * online_cpus,
101
+ throttling_count: delta('cpu_stats', 'throttling_data', 'periods', compute: delta, obj: metrics),
102
+ throttling_time: delta('cpu_stats', 'throttling_data', 'throttled_time', compute: delta, obj: metrics)
103
+ }
104
+ end
105
+
106
+ def network_stats(metrics)
107
+ delta = ->(old, new) { new - old }
108
+ return nil unless metrics['networks']
109
+
110
+ interfaces = metrics['networks'].keys
111
+ payload = {
112
+ rx: {
113
+ bytes: 0,
114
+ dropped: 0,
115
+ errors: 0,
116
+ packet: 0
117
+ },
118
+ tx: {
119
+ bytes: 0,
120
+ dropped: 0,
121
+ errors: 0,
122
+ packet: 0
123
+ }
124
+ }
125
+
126
+ interfaces.each do |interface|
127
+ payload[:rx][:bytes] += delta('networks', interface, 'rx_bytes', compute: delta, obj: metrics)
128
+ payload[:rx][:dropped] += delta('networks', interface, 'rx_dropped', compute: delta, obj: metrics)
129
+ payload[:rx][:errors] += delta('networks', interface, 'rx_errors', compute: delta, obj: metrics)
130
+ payload[:rx][:packet] += delta('networks', interface, 'rx_packets', compute: delta, obj: metrics)
131
+
132
+ payload[:tx][:bytes] += delta('networks', interface, 'tx_bytes', compute: delta, obj: metrics)
133
+ payload[:tx][:dropped] += delta('networks', interface, 'tx_packets', compute: delta, obj: metrics)
134
+ payload[:tx][:errors] += delta('networks', interface, 'tx_errors', compute: delta, obj: metrics)
135
+ payload[:tx][:packet] += delta('networks', interface, 'tx_dropped', compute: delta, obj: metrics)
136
+ end
137
+
138
+ payload
139
+ end
140
+
141
+ def lookup(resource)
142
+ path = @metadata_uri.path + resource
143
+ response = @client.send_request('GET', path)
144
+
145
+ raise "Unable to get `#{path}`. Got `#{response.code}`." unless response.ok?
146
+
147
+ response.json
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,88 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # Describes a Fargate container visible to the current process
7
+ # @since 1.197.0
8
+ class FargateContainer
9
+ ID = 'com.instana.plugin.aws.ecs.container'.freeze
10
+
11
+ def initialize(container, metadata_uri: ENV['ECS_CONTAINER_METADATA_URI'])
12
+ @container = container
13
+ @metadata_uri = URI(metadata_uri)
14
+ @client = Backend::RequestClient.new(@metadata_uri.host, @metadata_uri.port, use_ssl: @metadata_uri.scheme == "https")
15
+ end
16
+
17
+ def entity_id
18
+ "#{@container['Labels']['com.amazonaws.ecs.task-arn']}::#{@container['Name']}"
19
+ end
20
+
21
+ def data
22
+ payload = {
23
+ dockerId: @container['DockerId'],
24
+ dockerName: @container['DockerName'],
25
+ containerName: @container['Name'],
26
+ image: @container['Image'],
27
+ imageId: @container['ImageID'],
28
+ taskArn: @container['Labels']['com.amazonaws.ecs.task-arn'],
29
+ taskDefinition: @container['Labels']['com.amazonaws.ecs.task-definition-data.family'],
30
+ taskDefinitionVersion: @container['Labels']['com.amazonaws.ecs.task-definition-data.version'],
31
+ clusterArn: @container['Labels']['com.amazonaws.ecs.cluster'],
32
+ desiredStatus: @container['DesiredStatus'],
33
+ knownStatus: @container['KnownStatus'],
34
+ ports: @container['Ports'],
35
+ limits: {
36
+ cpu: @container['Limits']['CPU'],
37
+ memory: @container['Limits']['Memory']
38
+ },
39
+ createdAt: @container['CreatedAt'],
40
+ startedAt: @container['StartedAt']
41
+ }
42
+
43
+ if current_container?
44
+ payload[:instrumented] = true
45
+ payload[:runtime] = 'ruby'
46
+ end
47
+
48
+ payload
49
+ end
50
+
51
+ def snapshot
52
+ {
53
+ name: ID,
54
+ entityId: entity_id,
55
+ data: data
56
+ }
57
+ end
58
+
59
+ def source
60
+ return unless current_container?
61
+
62
+ {
63
+ hl: true,
64
+ cp: 'aws',
65
+ e: entity_id
66
+ }
67
+ end
68
+
69
+ private
70
+
71
+ def current_container?
72
+ return @current_container if @current_container
73
+
74
+ current_conatiner_response = current_conatiner
75
+ @current_container = @container['DockerName'] == current_conatiner_response['DockerName']
76
+ end
77
+
78
+ def current_conatiner
79
+ path = @metadata_uri.path
80
+ response = @client.send_request('GET', path)
81
+
82
+ raise "Unable to get `#{path}`. Got `#{response.code}`." unless response.ok?
83
+
84
+ response.json
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,67 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # Describes the current process in terms of its existence inside of a Fargate container
7
+ # @since 1.197.0
8
+ class FargateProcess
9
+ ID = 'com.instana.plugin.process'.freeze
10
+
11
+ def initialize(metadata_uri: ENV['ECS_CONTAINER_METADATA_URI'])
12
+ @metadata_uri = URI(metadata_uri)
13
+ @client = Backend::RequestClient.new(@metadata_uri.host, @metadata_uri.port, use_ssl: @metadata_uri.scheme == "https")
14
+ @start_time = Time.now
15
+ end
16
+
17
+ def entity_id
18
+ Process.pid.to_s
19
+ end
20
+
21
+ def data
22
+ proc_table = Sys::ProcTable.ps(pid: Process.pid)
23
+ process = Backend::ProcessInfo.new(proc_table)
24
+
25
+ {
26
+ pid: process.pid.to_i,
27
+ env: ENV.to_h,
28
+ exec: process.name,
29
+ args: process.arguments,
30
+ user: process.uid,
31
+ group: process.gid,
32
+ start: @start_time.to_i * 1000,
33
+ containerType: 'docker',
34
+ container: container_id,
35
+ "com.instana.plugin.host.name": task_id
36
+ }
37
+ end
38
+
39
+ def snapshot
40
+ {
41
+ name: ID,
42
+ entityId: entity_id,
43
+ data: data
44
+ }
45
+ end
46
+
47
+ private
48
+
49
+ def lookup(resource = nil)
50
+ path = resource ? @metadata_uri.path + resource : @metadata_uri.path
51
+ response = @client.send_request('GET', path)
52
+
53
+ raise "Unable to get `#{path}`. Got `#{response.code}`." unless response.ok?
54
+
55
+ response.json
56
+ end
57
+
58
+ def container_id
59
+ @container_id ||= lookup['DockerId']
60
+ end
61
+
62
+ def task_id
63
+ @task_id ||= lookup('/task')['TaskARN']
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,72 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # Describes the current process in terms of its existence inside of a Fargate task
7
+ # @since 1.197.0
8
+ class FargateTask
9
+ ID = 'com.instana.plugin.aws.ecs.task'.freeze
10
+
11
+ def initialize(metadata_uri: ENV['ECS_CONTAINER_METADATA_URI'])
12
+ @metadata_uri = URI(metadata_uri)
13
+ @client = Backend::RequestClient.new(@metadata_uri.host, @metadata_uri.port, use_ssl: @metadata_uri.scheme == "https")
14
+ end
15
+
16
+ def entity_id
17
+ task_metadata['TaskARN']
18
+ end
19
+ alias host_name entity_id
20
+
21
+ def data
22
+ {
23
+ taskArn: task_metadata['TaskARN'],
24
+ clusterArn: task_metadata['Cluster'],
25
+ taskDefinition: task_metadata['Family'],
26
+ taskDefinitionVersion: task_metadata['Revision'],
27
+ availabilityZone: task_metadata['AvailabilityZone'],
28
+ desiredStatus: task_metadata['DesiredStatus'],
29
+ knownStatus: task_metadata['KnownStatus'],
30
+ pullStartedAt: task_metadata['PullStartedAt'],
31
+ pullStoppedAt: task_metadata['PullStoppedAt'],
32
+ instanaZone: instana_zone,
33
+ tags: instana_tags
34
+ }.reject { |_, v| v.nil? }
35
+ end
36
+
37
+ def snapshot
38
+ {
39
+ name: ID,
40
+ entityId: entity_id,
41
+ data: data
42
+ }
43
+ end
44
+
45
+ private
46
+
47
+ def task_metadata
48
+ lookup('/task')
49
+ end
50
+
51
+ def instana_zone
52
+ ENV['INSTANA_ZONE']
53
+ end
54
+
55
+ def instana_tags
56
+ ENV.fetch('INSTANA_TAGS', '')
57
+ .split(/,/)
58
+ .map { |t| t.include?('=') ? t.split('=', 2) : [t, nil] }
59
+ .to_h
60
+ end
61
+
62
+ def lookup(resource)
63
+ path = @metadata_uri.path + resource
64
+ response = @client.send_request('GET', path)
65
+
66
+ raise "Unable to get `#{path}`. Got `#{response.code}`." unless response.ok?
67
+
68
+ response.json
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,69 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # @since 1.199
7
+ class GoogleCloudRunInstance
8
+ ID = 'com.instana.plugin.gcp.run.revision.instance'.freeze
9
+
10
+ def initialize(metadata_uri: 'http://metadata.google.internal')
11
+ @metadata_uri = URI(metadata_uri)
12
+ @client = Backend::RequestClient.new(@metadata_uri.host, @metadata_uri.port, use_ssl: @metadata_uri.scheme == "https")
13
+ end
14
+
15
+ def entity_id
16
+ lookup('/computeMetadata/v1/instance/id')
17
+ end
18
+
19
+ def data
20
+ {
21
+ runtime: 'ruby',
22
+ region: gcp_region,
23
+ service: ENV['K_SERVICE'],
24
+ configuration: ENV['K_CONFIGURATION'],
25
+ revision: ENV['K_REVISION'],
26
+ instanceId: entity_id,
27
+ port: ENV['PORT'],
28
+ numericProjectId: lookup('/computeMetadata/v1/project/numeric-project-id'),
29
+ projectId: lookup('/computeMetadata/v1/project/project-id')
30
+ }.reject { |_, v| v.nil? }
31
+ end
32
+
33
+ def snapshot
34
+ {
35
+ name: ID,
36
+ entityId: entity_id,
37
+ data: data
38
+ }
39
+ end
40
+
41
+ def source
42
+ {
43
+ hl: true,
44
+ cp: 'gcp',
45
+ e: entity_id
46
+ }
47
+ end
48
+
49
+ def host_name
50
+ "gcp:cloud-run:revision:#{ENV['K_REVISION']}"
51
+ end
52
+
53
+ private
54
+
55
+ def gcp_region
56
+ lookup('/computeMetadata/v1/instance/zone').split('/').last
57
+ end
58
+
59
+ def lookup(resource)
60
+ path = @metadata_uri.path + resource
61
+ response = @client.send_request('GET', path, nil, {'Metadata-Flavor' => 'Google'})
62
+
63
+ raise "Unable to get `#{path}`. Got `#{response.code}` `#{response['location']}`." unless response.ok?
64
+
65
+ response.body
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,58 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # @since 1.199.0
7
+ class GoogleCloudRunProcess
8
+ ID = 'com.instana.plugin.process'.freeze
9
+
10
+ def initialize(metadata_uri: 'http://metadata.google.internal')
11
+ @metadata_uri = URI(metadata_uri)
12
+ @client = Backend::RequestClient.new(@metadata_uri.host, @metadata_uri.port, use_ssl: @metadata_uri.scheme == "https")
13
+ @start_time = Time.now
14
+ end
15
+
16
+ def entity_id
17
+ Process.pid.to_s
18
+ end
19
+
20
+ def data
21
+ proc_table = Sys::ProcTable.ps(pid: Process.pid)
22
+ process = Backend::ProcessInfo.new(proc_table)
23
+
24
+ {
25
+ pid: process.pid.to_i,
26
+ env: ENV.to_h,
27
+ exec: process.name,
28
+ args: process.arguments,
29
+ user: process.uid,
30
+ group: process.gid,
31
+ start: @start_time.to_i * 1000,
32
+ containerType: 'gcpCloudRunInstance',
33
+ container: lookup('/computeMetadata/v1/instance/id'),
34
+ "com.instana.plugin.host.name": "gcp:cloud-run:revision:#{ENV['K_REVISION']}"
35
+ }
36
+ end
37
+
38
+ def snapshot
39
+ {
40
+ name: ID,
41
+ entityId: entity_id,
42
+ data: data
43
+ }
44
+ end
45
+
46
+ private
47
+
48
+ def lookup(resource)
49
+ path = @metadata_uri.path + resource
50
+ response = @client.send_request('GET', path, nil, {'Metadata-Flavor' => 'Google'})
51
+
52
+ raise "Unable to get `#{path}`. Got `#{response.code}` `#{response['location']}`." unless response.ok?
53
+
54
+ response.body
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,39 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # @since 1.198.0
7
+ class LambdaFunction
8
+ ID = "com.instana.plugin.aws.lambda".freeze
9
+
10
+ def entity_id
11
+ Thread.current[:instana_function_arn]
12
+ end
13
+
14
+ def data
15
+ {}
16
+ end
17
+
18
+ def snapshot
19
+ {
20
+ name: ID,
21
+ entityId: entity_id,
22
+ data: data
23
+ }
24
+ end
25
+
26
+ def source
27
+ {
28
+ hl: true,
29
+ cp: "aws",
30
+ e: entity_id
31
+ }
32
+ end
33
+
34
+ def host_name
35
+ entity_id
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ # (c) Copyright IBM Corp. 2021
2
+ # (c) Copyright Instana Inc. 2021
3
+
4
+ module Instana
5
+ module Snapshot
6
+ # Describes the current Ruby process
7
+ # @since 1.197.0
8
+ class RubyProcess
9
+ ID = 'com.instana.plugin.ruby'.freeze
10
+
11
+ def initialize(pid: Process.pid)
12
+ @pid = pid
13
+ end
14
+
15
+ def entity_id
16
+ @pid.to_s
17
+ end
18
+
19
+ def data
20
+ metrics_data.merge(Util.take_snapshot)
21
+ end
22
+
23
+ def snapshot
24
+ {
25
+ name: ID,
26
+ entityId: entity_id,
27
+ data: data
28
+ }
29
+ end
30
+
31
+ private
32
+
33
+ def metrics_data
34
+ proc_table = Sys::ProcTable.ps(pid: Process.pid)
35
+ process = Backend::ProcessInfo.new(proc_table)
36
+
37
+ {
38
+ pid: @pid,
39
+ name: Util.get_app_name,
40
+ exec_args: process.arguments,
41
+ gc: Backend::GCSnapshot.instance.report,
42
+ thread: {count: ::Thread.list.count},
43
+ memory: {rss_size: proc_table.rss / 1024} # Bytes to Kilobytes
44
+ }
45
+ end
46
+ end
47
+ end
48
+ end