tingyun_rpm 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/lib/ting_yun/agent/agent.rb +8 -0
  4. data/lib/ting_yun/agent/collector/stats_engine/base_quantile_hash.rb +20 -0
  5. data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +10 -0
  6. data/lib/ting_yun/agent/collector/stats_engine.rb +9 -0
  7. data/lib/ting_yun/agent/collector/transaction_sampler/class_method.rb +2 -2
  8. data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +16 -10
  9. data/lib/ting_yun/agent/datastore/metric_helper.rb +31 -7
  10. data/lib/ting_yun/agent/datastore.rb +6 -11
  11. data/lib/ting_yun/agent/dispatcher.rb +5 -1
  12. data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +5 -1
  13. data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +5 -0
  14. data/lib/ting_yun/agent/method_tracer_helpers.rb +8 -4
  15. data/lib/ting_yun/agent/transaction/attributes.rb +6 -2
  16. data/lib/ting_yun/agent/transaction/class_method.rb +14 -5
  17. data/lib/ting_yun/agent/transaction/instance_method.rb +20 -4
  18. data/lib/ting_yun/agent/transaction/trace.rb +2 -1
  19. data/lib/ting_yun/agent/transaction/trace_node.rb +10 -2
  20. data/lib/ting_yun/agent/transaction/traced_method_stack.rb +2 -2
  21. data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +2 -1
  22. data/lib/ting_yun/agent/transaction/transaction_state.rb +22 -1
  23. data/lib/ting_yun/agent/transaction/transaction_timings.rb +1 -2
  24. data/lib/ting_yun/agent/transaction.rb +13 -7
  25. data/lib/ting_yun/configuration/default_source.rb +44 -7
  26. data/lib/ting_yun/configuration/yaml_source.rb +1 -0
  27. data/lib/ting_yun/frameworks/instrumentation.rb +6 -1
  28. data/lib/ting_yun/frameworks/rails5.rb +10 -0
  29. data/lib/ting_yun/frameworks.rb +1 -1
  30. data/lib/ting_yun/http/http_client_request.rb +39 -0
  31. data/lib/ting_yun/http/net_http_request.rb +4 -0
  32. data/lib/ting_yun/instrumentation/active_record.rb +11 -5
  33. data/lib/ting_yun/instrumentation/bunny.rb +142 -0
  34. data/lib/ting_yun/instrumentation/data_mapper.rb +167 -0
  35. data/lib/ting_yun/instrumentation/grape.rb +39 -0
  36. data/lib/ting_yun/instrumentation/http_client.rb +70 -0
  37. data/lib/ting_yun/instrumentation/kafka.rb +218 -0
  38. data/lib/ting_yun/instrumentation/memcached.rb +135 -0
  39. data/lib/ting_yun/instrumentation/middleware_proxy.rb +1 -4
  40. data/lib/ting_yun/instrumentation/middleware_tracing.rb +5 -1
  41. data/lib/ting_yun/instrumentation/mongo.rb +18 -6
  42. data/lib/ting_yun/instrumentation/mongo2.rb +5 -1
  43. data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +5 -5
  44. data/lib/ting_yun/instrumentation/moped.rb +4 -3
  45. data/lib/ting_yun/instrumentation/net.rb +3 -3
  46. data/lib/ting_yun/instrumentation/rails3/action_controller.rb +8 -4
  47. data/lib/ting_yun/instrumentation/rails3/action_view.rb +8 -4
  48. data/lib/ting_yun/instrumentation/rails4/action_controller.rb +29 -0
  49. data/lib/ting_yun/instrumentation/rails4/action_view.rb +29 -0
  50. data/lib/ting_yun/instrumentation/rails4/active_record.rb +30 -0
  51. data/lib/ting_yun/instrumentation/rails5/action_cable.rb +31 -0
  52. data/lib/ting_yun/instrumentation/rails5/action_controller.rb +29 -0
  53. data/lib/ting_yun/instrumentation/rails5/action_view.rb +28 -0
  54. data/lib/ting_yun/instrumentation/rails5/active_record.rb +30 -0
  55. data/lib/ting_yun/instrumentation/rake.rb +3 -2
  56. data/lib/ting_yun/instrumentation/redis.rb +6 -5
  57. data/lib/ting_yun/instrumentation/sidekiq.rb +61 -0
  58. data/lib/ting_yun/instrumentation/sinatra/action.rb +95 -0
  59. data/lib/ting_yun/instrumentation/sinatra/view.rb +67 -0
  60. data/lib/ting_yun/instrumentation/support/action_cable_subscriber.rb +83 -0
  61. data/lib/ting_yun/instrumentation/{rails4 → support}/action_controller_subscriber.rb +5 -29
  62. data/lib/ting_yun/instrumentation/{rails4 → support}/action_view_subscriber.rb +2 -24
  63. data/lib/ting_yun/instrumentation/support/active_record_helper.rb +23 -6
  64. data/lib/ting_yun/instrumentation/{rails4 → support}/active_record_subscriber.rb +13 -37
  65. data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +204 -1
  66. data/lib/ting_yun/instrumentation/support/database.rb +2 -1
  67. data/lib/ting_yun/instrumentation/support/external_error.rb +2 -2
  68. data/lib/ting_yun/instrumentation/support/external_helper.rb +30 -0
  69. data/lib/ting_yun/instrumentation/support/method_instrumentation.rb +228 -0
  70. data/lib/ting_yun/instrumentation/support/metric_translator.rb +4 -1
  71. data/lib/ting_yun/instrumentation/support/sinatra_helper.rb +20 -0
  72. data/lib/ting_yun/instrumentation/support/transaction_namer.rb +3 -1
  73. data/lib/ting_yun/instrumentation/thrift.rb +5 -6
  74. data/lib/ting_yun/logger/agent_logger.rb +1 -0
  75. data/lib/ting_yun/logger/create_logger_helper.rb +16 -2
  76. data/lib/ting_yun/metrics/metric_data.rb +8 -2
  77. data/lib/ting_yun/metrics/metric_spec.rb +2 -1
  78. data/lib/ting_yun/support/helper.rb +4 -0
  79. data/lib/ting_yun/support/quantile_p2.rb +204 -0
  80. data/lib/ting_yun/ting_yun_service/upload_service.rb +38 -12
  81. data/lib/ting_yun/ting_yun_service.rb +4 -7
  82. data/lib/ting_yun/version.rb +3 -1
  83. data/lib/tingyun_rpm.rb +0 -4
  84. data/tingyun_rpm.gemspec +3 -3
  85. metadata +35 -13
  86. data/CODE_OF_CONDUCT.md +0 -13
  87. data/lib/ting_yun/agent/method_tracer.rb +0 -256
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+ module TingYun::Instrumentation::HttpClient
3
+
4
+ HTTPCLIENT_MIN_VERSION = '2.1.5'.freeze
5
+
6
+ def self.version_support?
7
+ TingYun::Support::VersionNumber.new(HTTPClient::VERSION) >= TingYun::Support::VersionNumber.new(HTTPCLIENT_MIN_VERSION)
8
+ end
9
+ end
10
+
11
+ TingYun::Support::LibraryDetection.defer do
12
+
13
+ named :http_client
14
+
15
+ depends_on do
16
+ defined?(::HTTPClient) && TingYun::Instrumentation::HttpClient.version_support?
17
+ end
18
+
19
+ depends_on do
20
+ !::TingYun::Agent.config[:disable_http_client]
21
+ end
22
+
23
+ executes do
24
+ ::TingYun::Agent.logger.info 'Installing HTTPClient instrumentation'
25
+ require 'ting_yun/agent/cross_app/cross_app_tracing'
26
+ require 'ting_yun/http/http_client_request'
27
+ require 'ting_yun/instrumentation/support/external_error'
28
+ end
29
+
30
+ executes do
31
+ ::HTTPClient.class_eval do
32
+
33
+ if private_method_defined? :follow_redirect
34
+ private
35
+ alias_method :follow_redirect_without_tingyun_trace, :follow_redirect
36
+
37
+ def follow_redirect(*args, &block)
38
+ begin
39
+ follow_redirect_without_tingyun_trace(*args, &block)
40
+ rescue => e
41
+ args[1] = (::Module.private_method_defined? :to_resource_url) ? to_resource_url(args[1]) : urify(args[1])
42
+ proxy = no_proxy?(args[1]) ? nil : @proxy
43
+ tingyun_request = TingYun::Http::HttpClientRequest.new(proxy, *args, &block)
44
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{tingyun_request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/http_client%2Fhttp")
45
+ raise e
46
+ end
47
+ end
48
+ end
49
+
50
+ private
51
+ alias :do_request_without_tingyun_trace :do_request
52
+
53
+ def do_request(*args, &block)
54
+ proxy = no_proxy?(args[1]) ? nil : @proxy
55
+ tingyun_request = TingYun::Http::HttpClientRequest.new(proxy, *args, &block)
56
+ TingYun::Agent::CrossAppTracing.tl_trace_http_request(tingyun_request) do
57
+ TingYun::Agent.disable_all_tracing do
58
+ do_request_without_tingyun_trace(*tingyun_request.args, &block)
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ ::HTTP::Message.class_eval do
65
+ def message
66
+ header.reason_phrase
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,218 @@
1
+ # encoding: utf-8
2
+
3
+ module TingYun::Instrumentation::Kafka
4
+
5
+ KAFKA_MIN_VERSION = '0.2.0'.freeze
6
+ KAFKA_MAX_VERSION = '0.3.16'.freeze
7
+ UNKNOWN = 'Unknown:Unknown'.freeze
8
+
9
+ def self.version_support?
10
+ if defined? RUBY_VERSION
11
+ kafka_version = TingYun::Support::VersionNumber.new(Kafka::VERSION)
12
+ kafka_version >= TingYun::Support::VersionNumber.new(KAFKA_MIN_VERSION) &&
13
+ kafka_version <= TingYun::Support::VersionNumber.new(KAFKA_MAX_VERSION)
14
+ else
15
+ false
16
+ end
17
+ end
18
+ end
19
+
20
+ TingYun::Support::LibraryDetection.defer do
21
+ named :ruby_kafka
22
+
23
+ depends_on do
24
+ begin
25
+ require 'kafka'
26
+ defined?(::Kafka) &&
27
+ TingYun::Instrumentation::Kafka.version_support? && false
28
+ rescue LoadError
29
+ false
30
+ end
31
+ end
32
+
33
+ executes do
34
+ TingYun::Agent.logger.info 'Installing Ruby-Kafka Instrumentation'
35
+ end
36
+
37
+ executes do
38
+ Kafka::Producer.class_eval do
39
+ attr_reader :cluster
40
+ end
41
+
42
+ if defined? (Kafka::Consumer)
43
+ Kafka::Consumer.class_eval do
44
+ attr_reader :cluster
45
+ end
46
+ end
47
+
48
+ if defined? (Kafka::Cluster)
49
+ Kafka::Cluster.class_eval do
50
+ attr_reader :seed_brokers
51
+ end
52
+ end
53
+
54
+ if defined?(Kafka::AsyncProducer) && defined?(Kafka::AsyncProducer::Worker)
55
+ Kafka::AsyncProducer::Worker.class_eval do
56
+ attr_reader :producer
57
+ end
58
+ end
59
+
60
+ Kafka::Client.class_eval do
61
+ if public_method_defined? :deliver_message
62
+ alias_method :deliver_message_without_tingyun, :deliver_message
63
+
64
+ def deliver_message(*args, **options, &block)
65
+ begin
66
+ state = TingYun::Agent::TransactionState.tl_get
67
+ ip_and_hosts = @seed_brokers.map{|a| [a.host, a.port].join(':')}.join(',') rescue TingYun::Instrumentation::Kafka::UNKNOWN
68
+ metric_name = "Message Kafka/#{ip_and_hosts}%2FTopic%2F#{options[:topic]}/Produce"
69
+ summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('Kafka', ip_and_hosts, 'Produce')
70
+ TingYun::Agent::Transaction.wrap(state, metric_name, :Kafka, {}, summary_metrics) do
71
+ TingYun::Agent.record_metric("#{metric_name}%2FByte", args[0].bytesize) if args[0]
72
+ deliver_message_without_tingyun(*args, **options, &block)
73
+ end
74
+ rescue => e
75
+ TingYun::Agent.logger.error("Failed to kafka deliver_message : ", e)
76
+ deliver_message_without_tingyun(*args, **options, &block)
77
+ end
78
+ end
79
+ end
80
+
81
+ if public_method_defined?(:each_message)&& TingYun::Agent.config[:'nbs.mq.conume']
82
+ alias_method :each_message_without_tingyun, :each_message
83
+
84
+ def each_message(*args, **options, &block)
85
+ wrap_block = Proc.new do |message|
86
+ begin
87
+ state = TingYun::Agent::TransactionState.tl_get
88
+ state.reset
89
+ ip_and_hosts = @seed_brokers.map{|a| [a.host, a.port].join(':')}.join(',') rescue TingYun::Instrumentation::Kafka::UNKNOWN
90
+ metric_name = "#{ip_and_hosts}%2FTopic%2F#{message.topic}/Consume"
91
+ summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('Kafka', ip_and_hosts, 'Consume')
92
+ TingYun::Agent::Transaction.start(state,:message, {:transaction_name => "WebAction/Kafka/Topic%2F#{message.topic}/Consume"})
93
+ TingYun::Agent::Transaction.wrap(state, "Message Kafka/#{metric_name}" , :Kafka, {}, summary_metrics) do
94
+ TingYun::Agent.record_metric("Message Kafka/#{metric_name}%2FByte",message.value.bytesize) if message.value
95
+ block.call(message)
96
+ end
97
+ rescue => e
98
+ TingYun::Agent.logger.error("Failed to kafka each_message in client : ", e)
99
+ block.call(message)
100
+ ensure
101
+ TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
102
+ end
103
+ end
104
+ each_message_without_tingyun(*args, **options, &wrap_block)
105
+ end
106
+ end
107
+ end
108
+
109
+ if defined?(::Kafka::Consumer)
110
+ Kafka::Consumer.class_eval do
111
+ if public_method_defined?(:each_message) && TingYun::Agent.config[:'nbs.mq.conume']
112
+ alias_method :each_message_without_tingyun, :each_message
113
+ def each_message(*args, **options, &block)
114
+ wrap_block = Proc.new do |message|
115
+ begin
116
+ state = TingYun::Agent::TransactionState.tl_get
117
+ state.reset
118
+ ip_and_hosts = self.cluster.seed_brokers.map{|a| [a.host, a.port].join(':')}.join(',') rescue TingYun::Instrumentation::Kafka::UNKNOWN
119
+ metric_name = "#{ip_and_hosts}%2FTopic%2F#{message.topic}/Consume"
120
+ summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('Kafka', ip_and_hosts, 'Consume')
121
+ TingYun::Agent::Transaction.start(state,:message, {:transaction_name => "WebAction/Kafka/Topic%2F#{message.topic}/Consume"})
122
+ TingYun::Agent::Transaction.wrap(state, "Message Kafka/#{metric_name}" , :Kafka, {}, summary_metrics) do
123
+ TingYun::Agent.record_metric("Message Kafka/#{metric_name}%2FByte", message.value.bytesize) if message.value
124
+ block.call(message)
125
+ end
126
+ rescue => e
127
+ TingYun::Agent.logger.error("Failed to Bunny call_with_tingyun : ", e)
128
+ block.call(message)
129
+ ensure
130
+ TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
131
+ end
132
+ end
133
+ if options.empty? && args.empty?
134
+ each_message_without_tingyun(&wrap_block)
135
+ else
136
+ each_message_without_tingyun(*args, **options, &wrap_block)
137
+ end
138
+ end
139
+ end
140
+
141
+ if public_method_defined?(:each_batch) && TingYun::Agent.config[:'nbs.mq.conume']
142
+ alias_method :each_batch_without_tingyun, :each_batch
143
+ def each_batch(*args, **options, &block)
144
+ wrap_block = Proc.new do |batch|
145
+ begin
146
+ state = TingYun::Agent::TransactionState.tl_get
147
+ state.reset
148
+ ip_and_hosts = self.cluster.seed_brokers.map{|a| [a.host, a.port].join(':')}.join(',') rescue TingYun::Instrumentation::Kafka::UNKNOWN
149
+ metric_name = "#{ip_and_hosts}%2FTopic%2F#{batch.topic}/Consume"
150
+ summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('Kafka', ip_and_hosts, 'Consume')
151
+ TingYun::Agent::Transaction.start(state,:message, {:transaction_name => "WebAction/Kafka/Topic%2F#{message.topic}/Consume"})
152
+ TingYun::Agent::Transaction.wrap(state, "Message Kafka/#{metric_name}" , :Kafka, {}, summary_metrics) do
153
+ bytesize = batch.messages.reduce(0){ |res, msg| res += (msg.value ? msg.value.bytesize : 0)}
154
+ TingYun::Agent.record_metric("Message Kafka/#{metric_name}%2FByte", bytesize) if bytesize.to_i > 0
155
+ block.call(batch)
156
+ end
157
+ rescue => e
158
+ TingYun::Agent.logger.error("Failed to Bunny call_with_tingyun : ", e)
159
+ block.call(batch)
160
+ ensure
161
+ TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
162
+ end
163
+ end
164
+ if options.empty? && args.empty?
165
+ each_batch_without_tingyun(&wrap_block)
166
+ else
167
+ each_batch_without_tingyun(*args, **options, &wrap_block)
168
+ end
169
+ end
170
+ end
171
+ end
172
+ end
173
+
174
+ Kafka::Producer.class_eval do
175
+ alias_method :produce_without_tingyun, :produce
176
+ def produce(*args, **options, &block)
177
+ begin
178
+ state = TingYun::Agent::TransactionState.tl_get
179
+ return produce_without_tingyun(*args, **options, &block) unless state.current_transaction
180
+ ip_and_hosts = @cluster.seed_brokers.map{|a| [a.host, a.port].join(':')}.join(',') rescue TingYun::Instrumentation::Kafka::UNKNOWN
181
+ metric_name = "Message Kafka/#{ip_and_hosts}%2FTopic%2F#{options[:topic]}/Produce"
182
+ summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('Kafka', ip_and_hosts, 'Produce')
183
+ TingYun::Agent::Transaction.wrap(state, metric_name, :Kafka, {}, summary_metrics) do
184
+ TingYun::Agent.record_metric("#{metric_name}%2FByte",args[0].bytesize) if args[0]
185
+ produce_without_tingyun(*args, **options, &block)
186
+ end
187
+ rescue => e
188
+ TingYun::Agent.logger.error("Failed to kafka produce sync : ", e)
189
+ produce_without_tingyun(*args, **options, &block)
190
+ end
191
+ end
192
+ end
193
+
194
+ if defined?(Kafka::AsyncProducer)
195
+ Kafka::AsyncProducer.class_eval do
196
+ if public_method_defined? :produce
197
+ alias_method :produce_without_tingyun, :produce
198
+
199
+ def produce(*args, **options, &block)
200
+ begin
201
+ state = TingYun::Agent::TransactionState.tl_get
202
+ ip_and_hosts = @worker.producer.cluster.seed_brokers.map{|a| [a.host, a.port].join(':')}.join(',') rescue TingYun::Instrumentation::Kafka::UNKNOWN
203
+ metric_name = "Message Kafka/#{ip_and_hosts}%2FTopic%2F#{options[:topic]}/Produce"
204
+ summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('Kafka', ip_and_hosts, 'Produce')
205
+ TingYun::Agent::Transaction.wrap(state, metric_name, :Kafka, {}, summary_metrics) do
206
+ TingYun::Agent.record_metric("#{metric_name}%2FByte",args[0].bytesize) if args[0]
207
+ produce_without_tingyun(*args, **options, &block)
208
+ end
209
+ rescue => e
210
+ TingYun::Agent.logger.error("Failed to kafka produce async : ", e)
211
+ produce_without_tingyun(*args, **options, &block)
212
+ end
213
+ end
214
+ end
215
+ end
216
+ end
217
+ end
218
+ end
@@ -0,0 +1,135 @@
1
+ # encoding: utf-8
2
+ module TingYun
3
+ module Instrumentation
4
+ module Timings
5
+ def record_memcached_duration(duration)
6
+ state = TingYun::Agent::TransactionState.tl_get
7
+ if state
8
+ state.timings.mc_duration = state.timings.mc_duration + duration * 1000
9
+ end
10
+ end
11
+ end
12
+
13
+ module VersionSupport
14
+ require 'ting_yun/support/version_number'
15
+ module_function
16
+
17
+ VERSION1 = '2.6.4'.freeze
18
+
19
+ def new_version_support?
20
+ ::TingYun::Support::VersionNumber.new(Dalli::VERSION) >= ::TingYun::Support::VersionNumber.new(VERSION1)
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+
27
+ TingYun::Support::LibraryDetection.defer do
28
+ named :memcached
29
+
30
+ depends_on do
31
+ defined?(::Memcached) || (defined?(::Dalli) && defined?(::Dalli::Client)) && false
32
+ end
33
+
34
+ depends_on do
35
+ !::TingYun::Agent.config[:disable_memcache]
36
+ end
37
+
38
+
39
+ executes do
40
+ TingYun::Agent.logger.info "Installing Memcached Instrumentation" if defined?(::Memcached)
41
+ TingYun::Agent.logger.info "Installing Dalli Instrumentation" if defined?(::Dalli::Client)
42
+ require 'ting_yun/agent/transaction/transaction_state'
43
+ end
44
+
45
+ executes do
46
+ require 'ting_yun/agent/datastore'
47
+
48
+ if defined?(::Memcached)
49
+ ::Memcached.class_eval do
50
+
51
+ include TingYun::Instrumentation::Timings
52
+
53
+ methods = [:set, :add, :increment, :decrement, :replace, :append, :prepend, :cas, :delete, :flush, :get, :exist,
54
+ :get_from_last, :server_by_key, :stats, :set_servers]
55
+
56
+ methods.each do |method|
57
+ next unless public_method_defined? method
58
+
59
+ alias_method "#{method}_without_tingyun_trace".to_sym, method.to_sym
60
+
61
+ define_method method do |*args, &block|
62
+ TingYun::Agent::Datastore.wrap('Memcached', method.to_s, nil, nil, nil, nil, method(:record_memcached_duration)) do
63
+ send "#{method}_without_tingyun_trace", *args, &block
64
+ end
65
+ end
66
+ end
67
+
68
+ alias :incr :increment
69
+ alias :decr :decrement
70
+ alias :compare_and_swap :cas if public_method_defined? :compare_and_swap
71
+ end
72
+ end
73
+
74
+ if defined?(::Dalli::Server)
75
+ ::Dalli::Server.class_eval do
76
+
77
+ include TingYun::Instrumentation::Timings
78
+
79
+ connect_method = (private_method_defined? :connect) ? :connect : :connection
80
+ private
81
+ alias_method :connect_without_tingyun_trace, connect_method
82
+
83
+ define_method connect_method do |*args, &block|
84
+ if @sock
85
+ connect_without_tingyun_trace *args, &block
86
+ else
87
+ TingYun::Agent::Datastore.wrap('Memcached', 'connect', nil, hostname, port, nil, method(:record_memcached_duration)) do
88
+ connect_without_tingyun_trace *args, &block
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ if defined?(::Dalli::Client)
96
+ ::Dalli::Client.class_eval do
97
+
98
+ include TingYun::Instrumentation::Timings
99
+
100
+ private
101
+ alias_method :perform_without_tingyun_trace, :perform
102
+ def perform(*args, &block)
103
+ return block.call if block
104
+ op, key = args[0..1]
105
+ current_ring = self.class.private_method_defined?(:ring) ? ring : @ring
106
+ server = current_ring.server_for_key(validate_key(key.to_s)) rescue nil
107
+ if server
108
+ host = server.hostname
109
+ port = server.port
110
+ end
111
+ TingYun::Agent::Datastore.wrap('Memcached', op.to_s, nil, host, port, nil, method(:record_memcached_duration)) do
112
+ perform_without_tingyun_trace(*args, &block)
113
+ end
114
+ end
115
+
116
+ methods = [:flush, :stats, :reset_stats, :close]
117
+ methods += [:get_multi, :get_multi_cas] if TingYun::Instrumentation::VersionSupport.new_version_support?
118
+
119
+ methods.each do |method|
120
+ next unless public_method_defined? method
121
+ alias_method "#{method}_without_tingyun_trace".to_sym, method.to_sym
122
+
123
+ define_method method do |*args, &block|
124
+ TingYun::Agent::Datastore.wrap('Memcached', method.to_s, nil, nil, nil, nil, method(:record_memcached_duration)) do
125
+ send "#{method}_without_tingyun_trace", *args, &block
126
+ end
127
+ end
128
+ end
129
+
130
+ alias :flush_all :flush
131
+ alias :reset :close if public_method_defined? :reset
132
+ end
133
+ end
134
+ end
135
+ end
@@ -14,10 +14,7 @@ module TingYun
14
14
  end
15
15
 
16
16
  def self.needs_wrapping?(target)
17
- (
18
- !target.respond_to?(:_nr_has_middleware_tracing) &&
19
- !is_sinatra_app?(target)
20
- )
17
+ !target.respond_to?(:_nr_has_middleware_tracing)
21
18
  end
22
19
 
23
20
  def self.wrap(target, is_app=false)
@@ -45,8 +45,13 @@ module TingYun
45
45
  end
46
46
  end
47
47
 
48
+ def sinatra_static?(env)
49
+ defined?(::Sinatra) && defined?(::Sinatra::Base) && env['REQUEST_URI'] && env['REQUEST_URI'] =~ /\.(css|js|html|png|jpg|jpeg|gif|bmp)\Z/i
50
+ end
48
51
 
49
52
  def call(env)
53
+ return target.call(env) if sinatra_static?(env)
54
+
50
55
  first_middleware = note_transaction_started(env)
51
56
  state = TingYun::Agent::TransactionState.tl_get
52
57
  begin
@@ -66,7 +71,6 @@ module TingYun
66
71
 
67
72
  result
68
73
  rescue Exception => e
69
-
70
74
  TingYun::Agent.notice_error(e)
71
75
  raise e
72
76
  ensure
@@ -23,7 +23,7 @@ module TingYun
23
23
 
24
24
  def hook_instrument_method(target_class)
25
25
  target_class.class_eval do
26
- require 'ting_yun/agent/method_tracer'
26
+ require 'ting_yun/agent/method_tracer_helpers'
27
27
 
28
28
  def record_mongo_duration(duration)
29
29
  state = TingYun::Agent::TransactionState.tl_get
@@ -32,15 +32,21 @@ module TingYun
32
32
  end
33
33
  end
34
34
 
35
+ def tingyun_host_port
36
+ return @db.connection.host_port if self.instance_variable_defined? :@db
37
+ return @host_to_try if self.instance_variable_defined? :@host_to_try
38
+ return ['Unknown', 'Unknown']
39
+ end
40
+
35
41
  def tingyun_generate_metrics(operation, payload = nil)
36
42
  payload ||= { :collection => self.name, :database => self.db.name }
37
- TingYun::Instrumentation::Support::MetricTranslator.metrics_for(operation, payload)
43
+ TingYun::Instrumentation::Support::MetricTranslator.metrics_for(operation, payload, tingyun_host_port)
38
44
  end
39
45
 
40
46
  def instrument_with_tingyun(name, payload = {}, &block)
41
- metrics = tingyun_generate_metrics(name, payload)
47
+ klass_name, *metrics = tingyun_generate_metrics(name, payload)
42
48
 
43
- TingYun::Agent::MethodTracer.trace_execution_scoped(metrics, payload, method(:record_mongo_duration)) do
49
+ TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, payload, method(:record_mongo_duration), klass_name) do
44
50
  instrument_without_tingyun(name, payload, &block)
45
51
  end
46
52
  end
@@ -53,7 +59,8 @@ module TingYun
53
59
  def instrument
54
60
  ::Mongo::Collection.class_eval do
55
61
  def save_with_tingyun(doc, opts = {}, &block)
56
- TingYun::Agent::MethodTracer.trace_execution_scoped(tingyun_generate_metrics(:save), opts, method(:record_mongo_duration)) do
62
+ klass_name, *metrics = tingyun_generate_metrics(:save)
63
+ TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, opts, method(:record_mongo_duration), klass_name) do
57
64
  save_without_tingyun(doc, opts, &block)
58
65
  end
59
66
  end
@@ -62,7 +69,8 @@ module TingYun
62
69
  alias_method :save, :save_with_tingyun
63
70
 
64
71
  def ensure_index_with_tingyun(spec, opts = {}, &block)
65
- TingYun::Agent::MethodTracer.trace_execution_scoped(tingyun_generate_metrics(:ensureIndex), opts, method(:record_mongo_duration)) do
72
+ klass_name, *metrics = tingyun_generate_metrics(:ensureIndex)
73
+ TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, opts, method(:record_mongo_duration), klass_name) do
66
74
  ensure_index_without_tingyun(spec, opts, &block)
67
75
  end
68
76
  end
@@ -79,6 +87,10 @@ end
79
87
  TingYun::Support::LibraryDetection.defer do
80
88
  named :mongo
81
89
 
90
+ depends_on do
91
+ !::TingYun::Agent.config[:disable_mongo]
92
+ end
93
+
82
94
  depends_on do
83
95
  defined?(::Mongo)
84
96
  end
@@ -1,7 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'ting_yun/agent'
4
- require 'ting_yun/agent/method_tracer'
4
+ require 'ting_yun/instrumentation/support/method_instrumentation'
5
5
 
6
6
  module TingYun
7
7
  module Instrumentation
@@ -22,6 +22,10 @@ end
22
22
  TingYun::Support::LibraryDetection.defer do
23
23
  named :mongo2
24
24
 
25
+ depends_on do
26
+ !::TingYun::Agent.config[:disable_mongo]
27
+ end
28
+
25
29
  depends_on do
26
30
  require 'ting_yun/agent/datastore/mongo'
27
31
  defined?(::Mongo) && TingYun::Agent::Datastore::Mongo.unsupported_2x? && defined?(::Mongo::Monitoring::Global)
@@ -30,12 +30,12 @@ module TingYun
30
30
  state.timings.mon_duration = state.timings.mon_duration + event.duration * 1000
31
31
  started_event = operations.delete(event.operation_id)
32
32
 
33
- base, *other_metrics = metrics(started_event)
33
+ klass_name, base, *other_metrics = metrics(started_event)
34
34
 
35
35
  TingYun::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
36
36
  base, other_metrics, event.duration*1000
37
37
  )
38
- notice_nosql_statement(state, started_event, base, event.duration)
38
+ notice_nosql_statement(state, started_event, base, event.duration, klass_name)
39
39
  rescue Exception => e
40
40
  log_notification_error('completed', e)
41
41
  end
@@ -68,7 +68,7 @@ module TingYun
68
68
  end
69
69
 
70
70
  def metrics(event)
71
- TingYun::Agent::Datastore::MetricHelper.metrics_for(MONGODB, TingYun::Agent::Datastore::Mongo.transform_operation(event.command_name), collection(event))
71
+ TingYun::Agent::Datastore::MetricHelper.metrics_for(MONGODB, TingYun::Agent::Datastore::Mongo.transform_operation(event.command_name), event.address.host, event.address.port, event.database_name, collection(event))
72
72
  end
73
73
 
74
74
  def generate_statement(event)
@@ -79,7 +79,7 @@ module TingYun
79
79
  )
80
80
  end
81
81
 
82
- def notice_nosql_statement(state, event, metric, duration)
82
+ def notice_nosql_statement(state, event, metric, duration, klass_name)
83
83
  end_time = Time.now.to_f
84
84
 
85
85
  stack = state.traced_method_stack
@@ -90,7 +90,7 @@ module TingYun
90
90
  transaction_sampler.notice_nosql_statement(generate_statement(event),duration*1000)
91
91
 
92
92
  # exit transaction trace node
93
- stack.pop_frame(state, frame, metric, end_time)
93
+ stack.pop_frame(state, frame, metric, end_time, true, klass_name)
94
94
  end
95
95
 
96
96
  def transaction_sampler
@@ -32,7 +32,8 @@ module TingYun
32
32
  operation = TingYun::Agent::Datastore::Mongo.transform_operation(operation_name)
33
33
 
34
34
  res = nil
35
- TingYun::Agent::Datastore.wrap(MONGODB, operation, collection, method(:record_mongo_duration)) do
35
+ database = options["database"] || options[:database]
36
+ TingYun::Agent::Datastore.wrap(MONGODB, operation, collection, ip_address, port, database, method(:record_mongo_duration)) do
36
37
  res = log_without_tingyun_instrumentation(operations, &blk)
37
38
  end
38
39
 
@@ -61,7 +62,7 @@ module TingYun
61
62
  return operation_name, collection
62
63
  end
63
64
 
64
- def record_mongo_duration(_1, _2, duration)
65
+ def record_mongo_duration(duration)
65
66
  state = TingYun::Agent::TransactionState.tl_get
66
67
  if state
67
68
  state.timings.mon_duration = state.timings.mon_duration + duration * 1000
@@ -81,7 +82,7 @@ end
81
82
  TingYun::Support::LibraryDetection.defer do
82
83
  named :mongo_moped
83
84
  depends_on do
84
- defined?(::Moped)
85
+ defined?(::Moped) && !::TingYun::Agent.config[:disable_mongo]
85
86
  end
86
87
 
87
88
  executes do
@@ -5,7 +5,7 @@ TingYun::Support::LibraryDetection.defer do
5
5
  named :net_http
6
6
 
7
7
  depends_on do
8
- defined?(Net) && defined?(Net::HTTP)
8
+ defined?(Net) && defined?(Net::HTTP) && !::TingYun::Agent.config[:disable_net_http]
9
9
  end
10
10
 
11
11
  executes do
@@ -36,7 +36,7 @@ TingYun::Support::LibraryDetection.defer do
36
36
  begin
37
37
  get_response_without_tingyun(uri_or_host, path , port , &block)
38
38
  rescue => e
39
- ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{uri_or_host.to_s.gsub('/','%2F')}/net%2Fhttp")
39
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{uri_or_host.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/net%2Fhttp")
40
40
  raise e
41
41
  end
42
42
  end
@@ -47,7 +47,7 @@ TingYun::Support::LibraryDetection.defer do
47
47
  begin
48
48
  start_without_tingyun(address, *arg, &block)
49
49
  rescue => e
50
- ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{address.to_s.gsub('/','%2F')}/net%2Fhttp")
50
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{address.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/net%2Fhttp")
51
51
  raise e
52
52
  end
53
53
  end
@@ -15,15 +15,15 @@ module TingYun
15
15
 
16
16
  def tingyun_metric_path(action_name_override = nil)
17
17
  if find_rule(request.request_method.upcase, request.path, request.env, request.filtered_parameters)
18
- return "Rails3/#{namespace}/#{name(request.path.slice(1..-1), request.env, request.filtered_parameters, request.cookies)}"
18
+ return "Rails/#{namespace}/#{name(request.path.slice(1..-1), request.env, request.filtered_parameters, request.cookies)}"
19
19
  else
20
- return self.env["PATH_INFO"] unless TingYun::Agent.config[:'nbs.auto_action_naming']
20
+ return "URL/#{self.env["PATH_INFO"][1..-1].gsub(/\//,'%2F')}" unless TingYun::Agent.config[:'nbs.auto_action_naming']
21
21
 
22
22
  action = action_name_override || action_name
23
23
  if action_name_override || self.class.action_methods.include?(action)
24
- "Rails3/#{self.class.controller_path}%2F#{action}"
24
+ "Rails/#{self.class.controller_path}%2F#{action}"
25
25
  else
26
- "Rails3/#{self.class.controller_path}%2F(other)"
26
+ "Rails/#{self.class.controller_path}%2F(other)"
27
27
  end
28
28
  end
29
29
  end
@@ -48,6 +48,10 @@ end
48
48
  TingYun::Support::LibraryDetection.defer do
49
49
  @name = :rails3_controller
50
50
 
51
+ depends_on do
52
+ !::TingYun::Agent.config[:disable_action_controller]
53
+ end
54
+
51
55
  depends_on do
52
56
  defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
53
57
  end