solarwinds_apm 5.1.9 → 6.0.0.preV1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +0 -1
  3. data/ext/oboe_metal/extconf.rb +19 -23
  4. data/ext/oboe_metal/lib/liboboe-1.0-aarch64.so.sha256 +1 -1
  5. data/ext/oboe_metal/lib/liboboe-1.0-alpine-aarch64.so.sha256 +1 -1
  6. data/ext/oboe_metal/lib/liboboe-1.0-alpine-x86_64.so.sha256 +1 -1
  7. data/ext/oboe_metal/lib/liboboe-1.0-x86_64.so.sha256 +1 -1
  8. data/ext/oboe_metal/src/VERSION +1 -1
  9. data/ext/oboe_metal/src/oboe_debug.h +1 -0
  10. data/lib/oboe_metal.rb +116 -80
  11. data/lib/rails/generators/solarwinds_apm/install_generator.rb +1 -2
  12. data/lib/rails/generators/solarwinds_apm/templates/solarwinds_apm_initializer.rb +44 -260
  13. data/lib/solarwinds_apm/api/current_trace_info.rb +148 -0
  14. data/lib/solarwinds_apm/api/tracing.rb +30 -0
  15. data/lib/solarwinds_apm/api/transaction_name.rb +57 -0
  16. data/lib/solarwinds_apm/api.rb +8 -15
  17. data/lib/solarwinds_apm/base.rb +4 -131
  18. data/lib/solarwinds_apm/config.rb +128 -175
  19. data/lib/solarwinds_apm/constants.rb +32 -0
  20. data/lib/solarwinds_apm/logger.rb +1 -1
  21. data/lib/solarwinds_apm/noop/context.rb +2 -5
  22. data/lib/solarwinds_apm/noop/metadata.rb +1 -2
  23. data/lib/solarwinds_apm/noop/profiling.rb +3 -7
  24. data/lib/solarwinds_apm/oboe_init_options.rb +71 -33
  25. data/lib/solarwinds_apm/opentelemetry/solarwinds_exporter.rb +204 -0
  26. data/lib/solarwinds_apm/opentelemetry/solarwinds_processor.rb +163 -0
  27. data/lib/solarwinds_apm/opentelemetry/solarwinds_propagator.rb +92 -0
  28. data/lib/solarwinds_apm/opentelemetry/solarwinds_response_propagator.rb +72 -0
  29. data/lib/solarwinds_apm/opentelemetry/solarwinds_sampler.rb +330 -0
  30. data/lib/solarwinds_apm/opentelemetry.rb +8 -0
  31. data/lib/solarwinds_apm/otel_config.rb +161 -0
  32. data/lib/solarwinds_apm/{inst → support}/logger_formatter.rb +5 -6
  33. data/lib/solarwinds_apm/{inst → support}/logging_log_event.rb +3 -6
  34. data/lib/solarwinds_apm/{inst → support}/lumberjack_formatter.rb +1 -4
  35. data/lib/solarwinds_apm/support/oboe_tracing_mode.rb +27 -0
  36. data/lib/solarwinds_apm/support/swomarginalia/LICENSE +20 -0
  37. data/lib/solarwinds_apm/support/swomarginalia/README.md +41 -0
  38. data/lib/solarwinds_apm/support/swomarginalia/comment.rb +205 -0
  39. data/lib/solarwinds_apm/support/swomarginalia/load_swomarginalia.rb +48 -0
  40. data/lib/solarwinds_apm/support/swomarginalia/railtie.rb +22 -0
  41. data/lib/solarwinds_apm/support/swomarginalia/swomarginalia.rb +86 -0
  42. data/lib/solarwinds_apm/support/transaction_cache.rb +24 -0
  43. data/lib/solarwinds_apm/support/transaction_settings.rb +26 -209
  44. data/lib/solarwinds_apm/support/transformer.rb +56 -0
  45. data/lib/solarwinds_apm/support/txn_name_manager.rb +25 -0
  46. data/lib/solarwinds_apm/support/x_trace_options.rb +42 -26
  47. data/lib/solarwinds_apm/support.rb +33 -10
  48. data/lib/solarwinds_apm/support_report.rb +10 -32
  49. data/lib/solarwinds_apm/thread_local.rb +1 -1
  50. data/lib/solarwinds_apm/version.rb +4 -4
  51. data/lib/solarwinds_apm.rb +31 -26
  52. metadata +76 -121
  53. data/.dockerignore +0 -5
  54. data/.gitignore +0 -58
  55. data/.rubocop.yml +0 -29
  56. data/.whitesource +0 -22
  57. data/.yardopts +0 -7
  58. data/CHANGELOG-appoptics.md +0 -766
  59. data/CHANGELOG.md +0 -82
  60. data/CONFIG.md +0 -31
  61. data/Gemfile +0 -15
  62. data/README.md +0 -385
  63. data/bin/solarwinds_apm_config +0 -15
  64. data/examples/prepend.rb +0 -13
  65. data/examples/sdk_examples.rb +0 -158
  66. data/ext/oboe_metal/README.md +0 -69
  67. data/ext/oboe_metal/extconf_local.rb +0 -75
  68. data/ext/oboe_metal/lib/.keep +0 -0
  69. data/ext/oboe_metal/noop/noop.c +0 -8
  70. data/ext/oboe_metal/src/README.md +0 -6
  71. data/ext/oboe_metal/src/frames.cc +0 -247
  72. data/ext/oboe_metal/src/frames.h +0 -40
  73. data/ext/oboe_metal/src/logging.cc +0 -97
  74. data/ext/oboe_metal/src/logging.h +0 -34
  75. data/ext/oboe_metal/src/profiling.cc +0 -435
  76. data/ext/oboe_metal/src/profiling.h +0 -78
  77. data/ext/oboe_metal/test/CMakeLists.txt +0 -53
  78. data/ext/oboe_metal/test/FindGMock.cmake +0 -43
  79. data/ext/oboe_metal/test/README.md +0 -56
  80. data/ext/oboe_metal/test/frames_test.cc +0 -164
  81. data/ext/oboe_metal/test/profiling_test.cc +0 -93
  82. data/ext/oboe_metal/test/ruby_inc_dir.rb +0 -8
  83. data/ext/oboe_metal/test/ruby_prefix.rb +0 -8
  84. data/ext/oboe_metal/test/ruby_test_helper.rb +0 -67
  85. data/ext/oboe_metal/test/test.h +0 -11
  86. data/ext/oboe_metal/test/test_main.cc +0 -32
  87. data/init.rb +0 -4
  88. data/lib/solarwinds_apm/api/layerinit.rb +0 -41
  89. data/lib/solarwinds_apm/api/logging.rb +0 -356
  90. data/lib/solarwinds_apm/api/memcache.rb +0 -37
  91. data/lib/solarwinds_apm/api/metrics.rb +0 -63
  92. data/lib/solarwinds_apm/api/util.rb +0 -98
  93. data/lib/solarwinds_apm/frameworks/grape.rb +0 -96
  94. data/lib/solarwinds_apm/frameworks/padrino.rb +0 -78
  95. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller.rb +0 -100
  96. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller5.rb +0 -50
  97. data/lib/solarwinds_apm/frameworks/rails/inst/action_controller_api.rb +0 -50
  98. data/lib/solarwinds_apm/frameworks/rails/inst/action_view.rb +0 -88
  99. data/lib/solarwinds_apm/frameworks/rails/inst/active_record.rb +0 -26
  100. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/mysql2.rb +0 -29
  101. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/postgresql.rb +0 -22
  102. data/lib/solarwinds_apm/frameworks/rails/inst/connection_adapters/utils5x.rb +0 -103
  103. data/lib/solarwinds_apm/frameworks/rails/inst/logger_formatters.rb +0 -14
  104. data/lib/solarwinds_apm/frameworks/rails.rb +0 -100
  105. data/lib/solarwinds_apm/frameworks/sinatra.rb +0 -96
  106. data/lib/solarwinds_apm/inst/bunny-client.rb +0 -157
  107. data/lib/solarwinds_apm/inst/bunny-consumer.rb +0 -102
  108. data/lib/solarwinds_apm/inst/curb.rb +0 -289
  109. data/lib/solarwinds_apm/inst/dalli.rb +0 -89
  110. data/lib/solarwinds_apm/inst/delayed_job.rb +0 -100
  111. data/lib/solarwinds_apm/inst/excon.rb +0 -113
  112. data/lib/solarwinds_apm/inst/faraday.rb +0 -96
  113. data/lib/solarwinds_apm/inst/graphql.rb +0 -206
  114. data/lib/solarwinds_apm/inst/grpc_client.rb +0 -147
  115. data/lib/solarwinds_apm/inst/grpc_server.rb +0 -119
  116. data/lib/solarwinds_apm/inst/httpclient.rb +0 -182
  117. data/lib/solarwinds_apm/inst/memcached.rb +0 -86
  118. data/lib/solarwinds_apm/inst/mongo.rb +0 -246
  119. data/lib/solarwinds_apm/inst/mongo2.rb +0 -225
  120. data/lib/solarwinds_apm/inst/moped.rb +0 -466
  121. data/lib/solarwinds_apm/inst/net_http.rb +0 -60
  122. data/lib/solarwinds_apm/inst/rack.rb +0 -223
  123. data/lib/solarwinds_apm/inst/rack_cache.rb +0 -35
  124. data/lib/solarwinds_apm/inst/redis.rb +0 -280
  125. data/lib/solarwinds_apm/inst/redis_v4.rb +0 -273
  126. data/lib/solarwinds_apm/inst/resque.rb +0 -129
  127. data/lib/solarwinds_apm/inst/rest-client.rb +0 -43
  128. data/lib/solarwinds_apm/inst/sequel.rb +0 -241
  129. data/lib/solarwinds_apm/inst/sidekiq-client.rb +0 -63
  130. data/lib/solarwinds_apm/inst/sidekiq-worker.rb +0 -64
  131. data/lib/solarwinds_apm/inst/typhoeus.rb +0 -90
  132. data/lib/solarwinds_apm/instrumentation.rb +0 -22
  133. data/lib/solarwinds_apm/loading.rb +0 -65
  134. data/lib/solarwinds_apm/ruby.rb +0 -35
  135. data/lib/solarwinds_apm/sdk/current_trace_info.rb +0 -123
  136. data/lib/solarwinds_apm/sdk/custom_metrics.rb +0 -94
  137. data/lib/solarwinds_apm/sdk/logging.rb +0 -37
  138. data/lib/solarwinds_apm/sdk/trace_context_headers.rb +0 -69
  139. data/lib/solarwinds_apm/sdk/tracing.rb +0 -432
  140. data/lib/solarwinds_apm/support/profiling.rb +0 -25
  141. data/lib/solarwinds_apm/support/trace_context.rb +0 -53
  142. data/lib/solarwinds_apm/support/trace_state.rb +0 -69
  143. data/lib/solarwinds_apm/support/trace_string.rb +0 -89
  144. data/lib/solarwinds_apm/support/transaction_metrics.rb +0 -67
  145. data/lib/solarwinds_apm/test.rb +0 -165
  146. data/lib/solarwinds_apm/util.rb +0 -426
  147. data/log/.keep +0 -0
  148. data/log/postgresql/.keep +0 -0
  149. data/solarwinds_apm.gemspec +0 -55
  150. data/yardoc_frontpage.md +0 -24
@@ -1,147 +0,0 @@
1
- # Copyright (c) 2018 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module GRPC
6
-
7
- module ActiveCall
8
- include SolarWindsAPM::SDK::TraceContextHeaders
9
-
10
- if defined? ::GRPC
11
- StatusCodes = {}
12
- ::GRPC::Core::StatusCodes.constants.each { |code| StatusCodes[::GRPC::Core::StatusCodes.const_get(code)] = code }
13
- end
14
-
15
- def self.included(klass)
16
- SolarWindsAPM::Util.method_alias(klass, :request_response, ::GRPC::ActiveCall)
17
- SolarWindsAPM::Util.method_alias(klass, :client_streamer, ::GRPC::ActiveCall)
18
- SolarWindsAPM::Util.method_alias(klass, :server_streamer, ::GRPC::ActiveCall)
19
- SolarWindsAPM::Util.method_alias(klass, :bidi_streamer, ::GRPC::ActiveCall)
20
- end
21
-
22
- def grpc_tags(method_type, method)
23
- tags = { 'Spec' => 'rsc',
24
- 'RemoteURL' => "grpc://#{peer}#{method}",
25
- 'GRPCMethodType' => method_type,
26
- 'IsService' => 'True'
27
- }
28
- tags
29
- end
30
-
31
- def request_response_with_sw_apm(req, metadata: {})
32
- unary_response(req, type: 'UNARY', metadata: metadata, without: :request_response_without_sw_apm)
33
- end
34
-
35
- def client_streamer_with_sw_apm(req, metadata: {})
36
- unary_response(req, type: 'CLIENT_STREAMING', metadata: metadata, without: :client_streamer_without_sw_apm)
37
- end
38
-
39
- def server_streamer_with_sw_apm(req, metadata: {}, &blk)
40
- @tags = grpc_tags('SERVER_STREAMING', metadata['method'] || metadata_to_send['method'])
41
- SolarWindsAPM::API.log_entry('grpc-client', @tags)
42
- add_tracecontext_headers(metadata)
43
-
44
- patch_receive_and_check_status # need to patch this so that log_exit can be called after the enum is consumed
45
-
46
- response = server_streamer_without_sw_apm(req, metadata: metadata)
47
- block_given? ? response.each { |r| yield r } : response
48
- rescue => e
49
- # this check is needed because the exception may have been logged in patch_receive_and_check_status
50
- unless e.instance_variable_get(:@exn_logged)
51
- SolarWindsAPM::API.log_exception('grpc-client', e)
52
- SolarWindsAPM::API.log_exit('grpc-client', exit_tags(@tags))
53
- end
54
- raise e
55
- end
56
-
57
- def bidi_streamer_with_sw_apm(req, metadata: {}, &blk)
58
- @tags = grpc_tags('BIDI_STREAMING', metadata['method'] || metadata_to_send['method'])
59
- SolarWindsAPM::API.log_entry('grpc-client', @tags)
60
- add_tracecontext_headers(metadata)
61
-
62
- patch_set_input_stream_done
63
-
64
- response = bidi_streamer_without_sw_apm(req, metadata: metadata)
65
- block_given? ? response.each { |r| yield r } : response
66
- rescue => e
67
- unless e.instance_variable_get(:@exn_logged)
68
- SolarWindsAPM::API.log_exception('grpc-client', e)
69
- SolarWindsAPM::API.log_exit('grpc-client', exit_tags(@tags))
70
- end
71
- raise e
72
- end
73
-
74
- private
75
-
76
- def unary_response(req, type:, metadata:, without:)
77
- tags = grpc_tags(type, metadata['method'] || metadata_to_send['method'])
78
- SolarWindsAPM::SDK.trace('grpc-client', kvs: tags) do
79
- add_tracecontext_headers(metadata)
80
- begin
81
- send(without, req, metadata: metadata)
82
- ensure
83
- exit_tags(tags)
84
- end
85
- end
86
- end
87
-
88
- def patch_receive_and_check_status
89
- def self.receive_and_check_status # need to patch this so that log_exit can be called after the enum is consumed
90
- super
91
- rescue => e
92
- SolarWindsAPM::API.log_exception('grpc-client', e)
93
- raise e
94
- ensure
95
- SolarWindsAPM::API.log_exit('grpc-client', exit_tags(@tags))
96
- end
97
- end
98
-
99
- def patch_set_input_stream_done
100
- # need to patch this instance method so that log_exit can be called after the enum is consumed
101
- def self.set_input_stream_done
102
- return if status.nil?
103
- if status.code > 0
104
- SolarWindsAPM::API.log_exception('grpc-client', $!)
105
- end
106
- SolarWindsAPM::API.log_exit('grpc-client', exit_tags(@tags))
107
- super
108
- end
109
- end
110
-
111
- def exit_tags(tags)
112
- # we need to translate the status.code, it is not the status.details we want, they are not matching 1:1
113
- tags['GRPCStatus'] ||= @call.status ? StatusCodes[@call.status.code].to_s : 'UNKNOWN'
114
- tags['Backtrace'] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:grpc_client][:collect_backtraces]
115
- tags
116
- end
117
- end
118
-
119
- end
120
- end
121
-
122
- if defined?(GRPC) && SolarWindsAPM::Config[:grpc_client][:enabled]
123
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting GRPC' if SolarWindsAPM::Config[:verbose]
124
-
125
- # Client side is instrumented in ActiveCall and ClientStub
126
- SolarWindsAPM::Util.send_include(GRPC::ActiveCall, SolarWindsAPM::GRPC::ActiveCall)
127
-
128
- GRPC_ClientStub_ops = [:request_response, :client_streamer, :server_streamer, :bidi_streamer]
129
- module GRPC
130
- class ClientStub
131
- GRPC_ClientStub_ops.reject { |m| !method_defined?(m) }.each do |m|
132
- define_method("#{m}_with_sw_apm") do |method, req, marshal, unmarshal, deadline: nil,
133
- return_op: false, parent: nil,
134
- credentials: nil, metadata: {}, &blk|
135
-
136
- metadata['method'] = method
137
- return send("#{m}_without_sw_apm", method, req, marshal, unmarshal, deadline: deadline,
138
- return_op: return_op, parent: parent,
139
- credentials: credentials, metadata: metadata, &blk)
140
- end
141
-
142
- SolarWindsAPM::Util.method_alias(GRPC::ClientStub, m)
143
- end
144
-
145
- end
146
- end
147
- end
@@ -1,119 +0,0 @@
1
- # Copyright (c) 2018 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module GRPC
6
-
7
- if defined? ::GRPC
8
- STATUSCODES = {}
9
- ::GRPC::Core::StatusCodes.constants.each { |code| STATUSCODES[::GRPC::Core::StatusCodes.const_get(code)] = code }
10
- end
11
-
12
- module RpcDesc
13
-
14
- def self.included(klass)
15
- ::SolarWindsAPM::Util.method_alias(klass, :handle_request_response, ::GRPC::RpcDesc)
16
- ::SolarWindsAPM::Util.method_alias(klass, :handle_client_streamer, ::GRPC::RpcDesc)
17
- ::SolarWindsAPM::Util.method_alias(klass, :handle_server_streamer, ::GRPC::RpcDesc)
18
- ::SolarWindsAPM::Util.method_alias(klass, :handle_bidi_streamer, ::GRPC::RpcDesc)
19
- ::SolarWindsAPM::Util.method_alias(klass, :run_server_method, ::GRPC::RpcDesc)
20
- end
21
-
22
- def grpc_tags(active_call, mth)
23
- tags = {
24
- 'Spec' => 'grpc_server',
25
- 'URL' => active_call.metadata['method'],
26
- 'Controller' => mth.owner.to_s,
27
- 'Action' => mth.name.to_s,
28
- 'HTTP-Host' => active_call.peer
29
- }
30
-
31
- if request_response?
32
- tags['GRPCMethodType'] = 'UNARY'
33
- elsif client_streamer?
34
- tags['GRPCMethodType'] = 'CLIENT_STREAMING'
35
- elsif server_streamer?
36
- tags['GRPCMethodType'] = 'SERVER_STREAMING'
37
- else
38
- # is a bidi_stream
39
- tags['GRPCMethodType'] = 'BIDI_STREAMING'
40
- end
41
-
42
- tags
43
- end
44
-
45
- def handle_request_response_with_sw_apm(active_call, mth, inter_ctx)
46
- handle_call('handle_request_response_without_sw_apm', active_call, mth, inter_ctx)
47
- end
48
-
49
- def handle_client_streamer_with_sw_apm(active_call, mth, inter_ctx)
50
- handle_call('handle_client_streamer_without_sw_apm', active_call, mth, inter_ctx)
51
- end
52
-
53
- def handle_server_streamer_with_sw_apm(active_call, mth, inter_ctx)
54
- handle_call('handle_server_streamer_without_sw_apm', active_call, mth, inter_ctx)
55
- end
56
-
57
- def handle_bidi_streamer_with_sw_apm(active_call, mth, inter_ctx)
58
- handle_call('handle_bidi_streamer_without_sw_apm', active_call, mth, inter_ctx)
59
- end
60
-
61
- # status codes need to be determined in this lower method, because they may not get raised to the
62
- # next instrumented method
63
- def handle_call(without, active_call, mth, inter_ctx)
64
- begin
65
- send(without, active_call, mth, inter_ctx)
66
- rescue ::GRPC::Core::CallError, ::GRPC::BadStatus, ::GRPC::Core::OutOfTime, StandardError, NotImplementedError => e
67
- log_grpc_exception(active_call, e)
68
- raise e
69
- end
70
- end
71
-
72
- def run_server_method_with_sw_apm(active_call, mth, inter_ctx)
73
- tags = grpc_tags(active_call, mth)
74
-
75
- SolarWindsAPM::API.log_start('grpc-server', tags, active_call.metadata)
76
-
77
- begin
78
- SolarWindsAPM::API.send_metrics('grpc-server', tags) do
79
- run_server_method_without_sw_apm(active_call, mth, inter_ctx)
80
- end
81
- rescue => e
82
- log_grpc_exception(active_call, e)
83
- raise e
84
- ensure
85
- tags['GRPCStatus'] = active_call.metadata_to_send.delete('grpc_status')
86
- tags['GRPCStatus'] ||= active_call.status ? SolarWindsAPM::GRPC::STATUSCODES[active_call.status.code].to_s : 'OK'
87
- tags['Backtrace'] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:grpc_server][:collect_backtraces]
88
-
89
- SolarWindsAPM::API.log_end('grpc-server', tags)
90
- end
91
- end
92
-
93
- private
94
-
95
- def log_grpc_exception(active_call, e)
96
- unless e.instance_variable_get(:@exn_logged)
97
- SolarWindsAPM::API.log_exception('grpc-server', e)
98
-
99
- unless active_call.metadata_sent
100
- if e.class == ::GRPC::Core::OutOfTime
101
- active_call.merge_metadata_to_send({ 'grpc_status' => 'DEADLINE_EXCEEDED' })
102
- elsif e.respond_to?(:code)
103
- active_call.merge_metadata_to_send({ 'grpc_status' => SolarWindsAPM::GRPC::STATUSCODES[e.code].to_s })
104
- else
105
- active_call.merge_metadata_to_send({ 'grpc_status' => 'UNKNOWN' })
106
- end
107
- end
108
- end
109
- end
110
-
111
- end
112
-
113
- end
114
- end
115
-
116
- if defined?(GRPC) && SolarWindsAPM::Config['grpc_server'][:enabled]
117
- # server side is instrumented in RpcDesc
118
- SolarWindsAPM::Util.send_include(GRPC::RpcDesc, SolarWindsAPM::GRPC::RpcDesc)
119
- end
@@ -1,182 +0,0 @@
1
- # Copyright (c) 2016 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module Inst
6
- module HTTPClient
7
-
8
- def sw_apm_collect(method, uri, query = nil)
9
- kvs = {}
10
- kvs[:Spec] = 'rsc'
11
- kvs[:IsService] = 1
12
-
13
- # Conditionally log URL query params
14
- # Because of the hook points, the query arg can come in under <tt>query</tt>
15
- # or as a part of <tt>uri</tt> (not both). Here we handle both cases.
16
- if SolarWindsAPM::Config[:httpclient][:log_args]
17
- if query
18
- kvs[:RemoteURL] = uri.to_s + '?' + SolarWindsAPM::Util.to_query(query)
19
- else
20
- kvs[:RemoteURL] = uri.to_s
21
- end
22
- else
23
- kvs[:RemoteURL] = uri.to_s.split('?').first
24
- end
25
-
26
- kvs[:RemoteURL] = SolarWindsAPM::Util.sanitize_uri(kvs[:RemoteURL])
27
- kvs[:HTTPMethod] = SolarWindsAPM::Util.upcase(method)
28
- kvs
29
- rescue => e
30
- SolarWindsAPM.logger.debug "[solarwinds_apm/debug] Error capturing httpclient KVs: #{e.message}"
31
- SolarWindsAPM.logger.debug e.backtrace.join('\n') if SolarWindsAPM::Config[:verbose]
32
- ensure
33
- return kvs
34
- end
35
-
36
- def do_request(method, uri, query, body, header, &block)
37
- # If we're not tracing, just do a fast return.
38
- unless SolarWindsAPM.tracing?
39
- add_trace_header(header)
40
- return super(method, uri, query, body, header, &block)
41
- end
42
-
43
- begin
44
- kvs = sw_apm_collect(method, uri, query)
45
-
46
- SolarWindsAPM::API.log_entry(:httpclient, kvs)
47
- kvs.clear
48
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:httpclient][:collect_backtraces]
49
-
50
- add_trace_header(header)
51
-
52
- # The core httpclient call
53
- response = super(method, uri, query, body, header, &block)
54
- kvs[:HTTPStatus] = response.status_code
55
-
56
- # If we get a redirect, report the location header
57
- if ((300..308).to_a.include? response.status.to_i) && response.headers.key?('Location')
58
- kvs[:Location] = response.headers['Location']
59
- end
60
-
61
- response
62
- rescue => e
63
- SolarWindsAPM::API.log_exception(:httpclient, e)
64
- raise e
65
- ensure
66
- SolarWindsAPM::API.log_exit(:httpclient, kvs)
67
- end
68
- end
69
-
70
- def do_request_async(method, uri, query, body, header)
71
- add_trace_header(header)
72
- # added headers because this calls `do_get_stream` in a new thread
73
- # threads do not inherit thread local variables like SolarWindsAPM.trace_context
74
- super(method, uri, query, body, header)
75
- end
76
-
77
- def do_get_stream(req, proxy, conn)
78
- # called from `do_request_async` in a new thread
79
- # threads do not inherit thread local variables
80
- # therefore we use headers to continue context
81
- w3c_headers = get_trace_headers(req.headers)
82
- SolarWindsAPM.trace_context = TraceContext.new(w3c_headers)
83
- unless SolarWindsAPM::TraceString.sampled?(SolarWindsAPM.trace_context.tracestring)
84
- # trace headers already included
85
- return super(req, proxy, conn)
86
- end
87
-
88
- begin
89
- method = req.http_header.request_method
90
-
91
- uri = req.http_header.request_uri
92
- kvs = sw_apm_collect(method, uri)
93
- kvs[:Async] = 1
94
-
95
- SolarWindsAPM::Context.fromString(SolarWindsAPM.trace_context.tracestring)
96
- SolarWindsAPM::API.log_entry(:httpclient, kvs)
97
- kvs.clear
98
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:httpclient][:collect_backtraces]
99
-
100
- add_trace_header(req.header)
101
-
102
- # The core httpclient call
103
- result = super(req, proxy, conn)
104
-
105
- # Older HTTPClient < 2.6.0 returns HTTPClient::Connection
106
- if result.is_a?(::HTTP::Message)
107
- response = result
108
- else
109
- response = conn.pop
110
- end
111
-
112
- kvs[:HTTPStatus] = response.status_code
113
-
114
- # If we get a redirect, report the location header
115
- if ((300..308).to_a.include? response.status.to_i) && response.headers.key?('Location')
116
- kvs[:Location] = response.headers['Location']
117
- end
118
-
119
- # Older HTTPClient < 2.6.0 returns HTTPClient::Connection
120
- conn.push response if result.is_a?(::HTTPClient::Connection)
121
- result
122
- rescue => e
123
- SolarWindsAPM::API.log_exception(:httpclient, e)
124
- raise e
125
- ensure
126
- SolarWindsAPM::API.log_exit(:httpclient, kvs)
127
- end
128
- end
129
-
130
- private
131
-
132
- def get_trace_headers(headers)
133
- if headers.is_a?(Array)
134
- traceparent = headers.find { |ele| ele.first =~ /[Tt]raceparent/ }
135
- tracestate = headers.find { |ele| ele.first =~ /[Tt]racestate/ }
136
- return { traceparent: traceparent, tracestate: tracestate }
137
- elsif headers.is_a?(Hash)
138
- return { traceparent: headers['traceparent'], tracestate: headers['tracestate'] }
139
- elsif headers.is_a? HTTP::Message::Headers
140
- return { traceparent: headers['traceparent'].first,
141
- tracestate: headers['tracestate'].first }
142
- end
143
- {}
144
- end
145
-
146
- def add_trace_header(headers)
147
- tracestring, tracestate = w3c_context
148
- # Be aware of various ways to call/use httpclient
149
- if headers.is_a?(Array)
150
- headers.delete_if { |kv| kv[0] =~ /^([Tt]raceparent|[Tt]racestate)$/ }
151
- headers.push ['traceparent', tracestring] if tracestring
152
- headers.push ['tracestate', tracestate] if tracestate
153
- elsif headers.is_a?(Hash)
154
- headers['traceparent'] = tracestring if tracestring
155
- headers['tracestate'] = tracestate if tracestate
156
- elsif headers.is_a? HTTP::Message::Headers
157
- headers.set('traceparent', tracestring) if tracestring
158
- headers.set('tracestate', tracestate) if tracestate
159
- end
160
- end
161
-
162
- # !! this is a private method, only used in add_trace_header above
163
- def w3c_context
164
- tracestring = SolarWindsAPM::Context.toString
165
-
166
- unless SolarWindsAPM::TraceString.valid?(tracestring)
167
- return [SolarWindsAPM.trace_context&.traceparent, SolarWindsAPM.trace_context&.tracestate]
168
- end
169
-
170
- parent_id_flags = SolarWindsAPM::TraceString.span_id_flags(tracestring)
171
- tracestate = SolarWindsAPM::TraceState.add_sw_member(SolarWindsAPM.trace_context&.tracestate, parent_id_flags)
172
- [tracestring, tracestate]
173
- end
174
-
175
- end
176
- end
177
- end
178
-
179
- if SolarWindsAPM::Config[:httpclient][:enabled] && defined?(HTTPClient)
180
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting httpclient' if SolarWindsAPM::Config[:verbose]
181
- HTTPClient.prepend(SolarWindsAPM::Inst::HTTPClient)
182
- end
@@ -1,86 +0,0 @@
1
- # Copyright (c) 2016 SolarWinds, LLC.
2
- # All rights reserved.
3
-
4
- module SolarWindsAPM
5
- module Inst
6
- module Memcached
7
- include SolarWindsAPM::API::Memcache
8
-
9
- def self.included(cls)
10
- SolarWindsAPM.logger.info '[solarwinds_apm/loading] Instrumenting memcached' if SolarWindsAPM::Config[:verbose]
11
-
12
- cls.class_eval do
13
- MEMCACHE_OPS.reject { |m| !method_defined?(m) }.each do |m|
14
- define_method("#{m}_with_sw_apm") do |*args|
15
- kvs = { :KVOp => m }
16
-
17
- if args.length && !args[0].is_a?(Array)
18
- kvs[:KVKey] = args[0].to_s
19
- rhost = remote_host(args[0].to_s)
20
- kvs[:RemoteHost] = rhost if rhost
21
- end
22
-
23
- SolarWindsAPM::SDK.trace(:memcache, kvs: kvs) do
24
- result = send("#{m}_without_sw_apm", *args)
25
-
26
- kvs[:KVHit] = memcache_hit?(result) if m == :get && args.length && args[0].class == String
27
- kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:memcached][:collect_backtraces]
28
-
29
- result
30
- end
31
- end
32
-
33
- class_eval "alias #{m}_without_sw_apm #{m}"
34
- class_eval "alias #{m} #{m}_with_sw_apm"
35
- end
36
- end
37
- end
38
-
39
- end # module Memcached
40
-
41
- module MemcachedRails
42
- def self.included(cls)
43
- cls.class_eval do
44
- if ::Memcached::Rails.method_defined? :get_multi
45
- alias get_multi_without_sw_apm get_multi
46
- alias get_multi get_multi_with_sw_apm
47
- elsif SolarWindsAPM::Config[:verbose]
48
- SolarWindsAPM.logger.warn '[solarwinds_apm/loading] Couldn\'t properly instrument Memcached. Partial traces may occur.'
49
- end
50
- end
51
- end
52
-
53
- def get_multi_with_sw_apm(keys, raw = false)
54
- if SolarWindsAPM.tracing?
55
- layer_kvs = {}
56
- layer_kvs[:KVOp] = :get_multi
57
-
58
- SolarWindsAPM::SDK.trace(:memcache, kvs: layer_kvs, protect_op: :get_multi) do
59
- layer_kvs[:KVKeyCount] = keys.flatten.length
60
-
61
- values = get_multi_without_sw_apm(keys, raw)
62
-
63
- layer_kvs[:KVHitCount] = values.length
64
- layer_kvs[:Backtrace] = SolarWindsAPM::API.backtrace if SolarWindsAPM::Config[:memcached][:collect_backtraces]
65
-
66
- values
67
- end
68
- else
69
- get_multi_without_sw_apm(keys, raw)
70
- end
71
- end
72
- end # module MemcachedRails
73
- end # module Inst
74
- end # module SolarWindsAPM
75
-
76
- if defined?(Memcached) && SolarWindsAPM::Config[:memcached][:enabled]
77
- Memcached.class_eval do
78
- include SolarWindsAPM::Inst::Memcached
79
- end
80
-
81
- if defined?(Memcached::Rails)
82
- Memcached::Rails.class_eval do
83
- include SolarWindsAPM::Inst::MemcachedRails
84
- end
85
- end
86
- end