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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/lib/ting_yun/agent/agent.rb +8 -0
- data/lib/ting_yun/agent/collector/stats_engine/base_quantile_hash.rb +20 -0
- data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +10 -0
- data/lib/ting_yun/agent/collector/stats_engine.rb +9 -0
- data/lib/ting_yun/agent/collector/transaction_sampler/class_method.rb +2 -2
- data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +16 -10
- data/lib/ting_yun/agent/datastore/metric_helper.rb +31 -7
- data/lib/ting_yun/agent/datastore.rb +6 -11
- data/lib/ting_yun/agent/dispatcher.rb +5 -1
- data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +5 -1
- data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +5 -0
- data/lib/ting_yun/agent/method_tracer_helpers.rb +8 -4
- data/lib/ting_yun/agent/transaction/attributes.rb +6 -2
- data/lib/ting_yun/agent/transaction/class_method.rb +14 -5
- data/lib/ting_yun/agent/transaction/instance_method.rb +20 -4
- data/lib/ting_yun/agent/transaction/trace.rb +2 -1
- data/lib/ting_yun/agent/transaction/trace_node.rb +10 -2
- data/lib/ting_yun/agent/transaction/traced_method_stack.rb +2 -2
- data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +2 -1
- data/lib/ting_yun/agent/transaction/transaction_state.rb +22 -1
- data/lib/ting_yun/agent/transaction/transaction_timings.rb +1 -2
- data/lib/ting_yun/agent/transaction.rb +13 -7
- data/lib/ting_yun/configuration/default_source.rb +44 -7
- data/lib/ting_yun/configuration/yaml_source.rb +1 -0
- data/lib/ting_yun/frameworks/instrumentation.rb +6 -1
- data/lib/ting_yun/frameworks/rails5.rb +10 -0
- data/lib/ting_yun/frameworks.rb +1 -1
- data/lib/ting_yun/http/http_client_request.rb +39 -0
- data/lib/ting_yun/http/net_http_request.rb +4 -0
- data/lib/ting_yun/instrumentation/active_record.rb +11 -5
- data/lib/ting_yun/instrumentation/bunny.rb +142 -0
- data/lib/ting_yun/instrumentation/data_mapper.rb +167 -0
- data/lib/ting_yun/instrumentation/grape.rb +39 -0
- data/lib/ting_yun/instrumentation/http_client.rb +70 -0
- data/lib/ting_yun/instrumentation/kafka.rb +218 -0
- data/lib/ting_yun/instrumentation/memcached.rb +135 -0
- data/lib/ting_yun/instrumentation/middleware_proxy.rb +1 -4
- data/lib/ting_yun/instrumentation/middleware_tracing.rb +5 -1
- data/lib/ting_yun/instrumentation/mongo.rb +18 -6
- data/lib/ting_yun/instrumentation/mongo2.rb +5 -1
- data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +5 -5
- data/lib/ting_yun/instrumentation/moped.rb +4 -3
- data/lib/ting_yun/instrumentation/net.rb +3 -3
- data/lib/ting_yun/instrumentation/rails3/action_controller.rb +8 -4
- data/lib/ting_yun/instrumentation/rails3/action_view.rb +8 -4
- data/lib/ting_yun/instrumentation/rails4/action_controller.rb +29 -0
- data/lib/ting_yun/instrumentation/rails4/action_view.rb +29 -0
- data/lib/ting_yun/instrumentation/rails4/active_record.rb +30 -0
- data/lib/ting_yun/instrumentation/rails5/action_cable.rb +31 -0
- data/lib/ting_yun/instrumentation/rails5/action_controller.rb +29 -0
- data/lib/ting_yun/instrumentation/rails5/action_view.rb +28 -0
- data/lib/ting_yun/instrumentation/rails5/active_record.rb +30 -0
- data/lib/ting_yun/instrumentation/rake.rb +3 -2
- data/lib/ting_yun/instrumentation/redis.rb +6 -5
- data/lib/ting_yun/instrumentation/sidekiq.rb +61 -0
- data/lib/ting_yun/instrumentation/sinatra/action.rb +95 -0
- data/lib/ting_yun/instrumentation/sinatra/view.rb +67 -0
- data/lib/ting_yun/instrumentation/support/action_cable_subscriber.rb +83 -0
- data/lib/ting_yun/instrumentation/{rails4 → support}/action_controller_subscriber.rb +5 -29
- data/lib/ting_yun/instrumentation/{rails4 → support}/action_view_subscriber.rb +2 -24
- data/lib/ting_yun/instrumentation/support/active_record_helper.rb +23 -6
- data/lib/ting_yun/instrumentation/{rails4 → support}/active_record_subscriber.rb +13 -37
- data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +204 -1
- data/lib/ting_yun/instrumentation/support/database.rb +2 -1
- data/lib/ting_yun/instrumentation/support/external_error.rb +2 -2
- data/lib/ting_yun/instrumentation/support/external_helper.rb +30 -0
- data/lib/ting_yun/instrumentation/support/method_instrumentation.rb +228 -0
- data/lib/ting_yun/instrumentation/support/metric_translator.rb +4 -1
- data/lib/ting_yun/instrumentation/support/sinatra_helper.rb +20 -0
- data/lib/ting_yun/instrumentation/support/transaction_namer.rb +3 -1
- data/lib/ting_yun/instrumentation/thrift.rb +5 -6
- data/lib/ting_yun/logger/agent_logger.rb +1 -0
- data/lib/ting_yun/logger/create_logger_helper.rb +16 -2
- data/lib/ting_yun/metrics/metric_data.rb +8 -2
- data/lib/ting_yun/metrics/metric_spec.rb +2 -1
- data/lib/ting_yun/support/helper.rb +4 -0
- data/lib/ting_yun/support/quantile_p2.rb +204 -0
- data/lib/ting_yun/ting_yun_service/upload_service.rb +38 -12
- data/lib/ting_yun/ting_yun_service.rb +4 -7
- data/lib/ting_yun/version.rb +3 -1
- data/lib/tingyun_rpm.rb +0 -4
- data/tingyun_rpm.gemspec +3 -3
- metadata +35 -13
- data/CODE_OF_CONDUCT.md +0 -13
- 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/
|
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::
|
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
|
-
|
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
|
-
|
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/
|
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
|
-
|
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(
|
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 "
|
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
|
-
"
|
24
|
+
"Rails/#{self.class.controller_path}%2F#{action}"
|
25
25
|
else
|
26
|
-
"
|
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
|