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
@@ -12,7 +12,7 @@ module TingYun
|
|
12
12
|
@queue_time_in_seconds = clamp_to_positive(queue_time_in_seconds.to_f)
|
13
13
|
@start_time_in_seconds = clamp_to_positive(start_time_in_seconds.to_f)
|
14
14
|
|
15
|
-
@timings = TingYun::Agent::TransactionTimings::Timings.new(0.0,0.0,0.0,0.0,0.0)
|
15
|
+
@timings = TingYun::Agent::TransactionTimings::Timings.new(0.0, 0.0, 0.0, 0.0, 0.0)
|
16
16
|
end
|
17
17
|
|
18
18
|
|
@@ -27,7 +27,6 @@ module TingYun
|
|
27
27
|
:mon_duration, :mon_duration=
|
28
28
|
|
29
29
|
|
30
|
-
|
31
30
|
def start_time_as_time
|
32
31
|
Time.at(@start_time_in_seconds)
|
33
32
|
end
|
@@ -26,13 +26,16 @@ module TingYun
|
|
26
26
|
|
27
27
|
SUBTRANSACTION_PREFIX = 'Nested/'.freeze
|
28
28
|
CONTROLLER_PREFIX = 'WebAction/'.freeze
|
29
|
+
BACKGROUND_PREFIX = 'BackgroundAction/'.freeze
|
29
30
|
RAKE_TRANSACTION_PREFIX = 'BackgroundAction/Rake'.freeze
|
30
31
|
TASK_PREFIX = 'OtherTransaction/Background/'.freeze
|
31
32
|
RACK_PREFIX = 'Rack/'.freeze
|
32
|
-
SINATRA_PREFIX = 'Sinatra/'.freeze
|
33
|
+
SINATRA_PREFIX = 'WebAction/Sinatra/'.freeze
|
33
34
|
MIDDLEWARE_PREFIX = 'Middleware/Rack/'.freeze
|
34
|
-
GRAPE_PREFIX = 'Grape/'.freeze
|
35
|
-
RAKE_PREFIX = 'Rake'.freeze
|
35
|
+
GRAPE_PREFIX = 'WebAction/Grape/'.freeze
|
36
|
+
RAKE_PREFIX = 'WebAction/Rake'.freeze
|
37
|
+
CABLE_PREFIX = 'WebAction/ActionCable'.freeze
|
38
|
+
|
36
39
|
|
37
40
|
EMPTY_SUMMARY_METRICS = [].freeze
|
38
41
|
MIDDLEWARE_SUMMARY_METRICS = ['Middleware/all'.freeze].freeze
|
@@ -57,7 +60,8 @@ module TingYun
|
|
57
60
|
:guid,
|
58
61
|
:category,
|
59
62
|
:default_name,
|
60
|
-
:start_time
|
63
|
+
:start_time,
|
64
|
+
:base_quantile_hash
|
61
65
|
|
62
66
|
|
63
67
|
|
@@ -75,6 +79,7 @@ module TingYun
|
|
75
79
|
@guid = client_transaction_id || generate_guid
|
76
80
|
@frame_stack = []
|
77
81
|
@frozen_name = nil
|
82
|
+
@base_quantile_hash = {}
|
78
83
|
@default_name = TingYun::Helper.correctly_encoded(options[:transaction_name])
|
79
84
|
|
80
85
|
if request = options[:request]
|
@@ -108,7 +113,7 @@ module TingYun
|
|
108
113
|
|
109
114
|
|
110
115
|
|
111
|
-
def stop(state, end_time, outermost_frame)
|
116
|
+
def stop(state, end_time, outermost_frame, summary_metrics = [])
|
112
117
|
|
113
118
|
freeze_name_and_execute
|
114
119
|
|
@@ -125,7 +130,7 @@ module TingYun
|
|
125
130
|
else
|
126
131
|
summary_metrics_with_exclusive_time = EMPTY_SUMMARY_METRICS
|
127
132
|
end
|
128
|
-
|
133
|
+
summary_metrics_with_exclusive_time = summary_metrics unless summary_metrics.empty?
|
129
134
|
|
130
135
|
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped_footer(
|
131
136
|
state,
|
@@ -149,12 +154,13 @@ module TingYun
|
|
149
154
|
|
150
155
|
TingYun::Agent.instance.sql_sampler.on_finishing_transaction(state, @frozen_name)
|
151
156
|
|
152
|
-
record_summary_metrics(outermost_node_name, end_time)
|
157
|
+
record_summary_metrics(state, outermost_node_name, end_time)
|
153
158
|
@apdex.record_apdex(@frozen_name, end_time, @exceptions.had_error?)
|
154
159
|
@exceptions.record_exceptions(@attributes)
|
155
160
|
|
156
161
|
|
157
162
|
TingYun::Agent.instance.stats_engine.merge_transaction_metrics!(@metrics, best_name)
|
163
|
+
TingYun::Agent.instance.stats_engine.record_base_quantile(@base_quantile_hash) if @exceptions.exceptions.empty?
|
158
164
|
end
|
159
165
|
|
160
166
|
end
|
@@ -46,6 +46,8 @@ module TingYun
|
|
46
46
|
:rails3
|
47
47
|
when 4
|
48
48
|
:rails4
|
49
|
+
when 5
|
50
|
+
:rails5
|
49
51
|
else
|
50
52
|
::TingYun::Agent.logger.error "Detected unsupported Rails version #{Rails::VERSION::STRING}"
|
51
53
|
end
|
@@ -85,13 +87,6 @@ module TingYun
|
|
85
87
|
Proc.new { ::TingYun::Frameworks.framework.local_env.discovered_dispatcher }
|
86
88
|
end
|
87
89
|
|
88
|
-
|
89
|
-
def self.audit_log_path
|
90
|
-
Proc.new {
|
91
|
-
File.join(TingYun::Agent.config[:log_file_path], 'newrelic_audit.log')
|
92
|
-
}
|
93
|
-
end
|
94
|
-
|
95
90
|
# On Rubies with string encodings support (1.9.x+), default to always
|
96
91
|
# normalize encodings since it's safest and fast. Without that support
|
97
92
|
# the conversions are too expensive, so only enable if overridden to.
|
@@ -348,6 +343,27 @@ module TingYun
|
|
348
343
|
:allowed_from_server => false,
|
349
344
|
:description => 'log filename.'
|
350
345
|
},
|
346
|
+
:agent_log_file_size => {
|
347
|
+
:default => 500,
|
348
|
+
:public => true,
|
349
|
+
:type => Fixnum,
|
350
|
+
:allowed_from_server => false,
|
351
|
+
:description => "Create a new logfile once it reaches this value. and this value's unit is MB."
|
352
|
+
},
|
353
|
+
:agent_log_file_number => {
|
354
|
+
:default => 10,
|
355
|
+
:public => true,
|
356
|
+
:type => Fixnum,
|
357
|
+
:allowed_from_server => false,
|
358
|
+
:description => "The remaining number of log file, delete the earliest when more than this value."
|
359
|
+
},
|
360
|
+
:agent_log_file_check_days => {
|
361
|
+
:default => 7,
|
362
|
+
:public => true,
|
363
|
+
:type => Fixnum,
|
364
|
+
:allowed_from_server => false,
|
365
|
+
:description => "Check for create new logfile when reach days of this value."
|
366
|
+
},
|
351
367
|
:config_search_paths => {
|
352
368
|
:default => DefaultSource.config_search_paths,
|
353
369
|
:public => false,
|
@@ -645,6 +661,27 @@ module TingYun
|
|
645
661
|
:type => Boolean,
|
646
662
|
:allowed_from_server => true,
|
647
663
|
:description => 'Enable or disable the thrift cross application feature'
|
664
|
+
},
|
665
|
+
:restart_thread_in_children => {
|
666
|
+
:default => true,
|
667
|
+
:public => false,
|
668
|
+
:type => Boolean,
|
669
|
+
:allowed_from_server => false,
|
670
|
+
:description => 'Controls whether to check on running a transaction whether to respawn the harvest thread.'
|
671
|
+
},
|
672
|
+
:'nbs.quantile' => {
|
673
|
+
:default => nil,
|
674
|
+
:public => true,
|
675
|
+
:type => String,
|
676
|
+
:allowed_from_server => true,
|
677
|
+
:description => 'Quantile'
|
678
|
+
},
|
679
|
+
:'nbs.mq.conume' => {
|
680
|
+
:default => false,
|
681
|
+
:public => true,
|
682
|
+
:type => Boolean,
|
683
|
+
:allowed_from_server => true,
|
684
|
+
:description => 'Enable or disable the mq feature'
|
648
685
|
}
|
649
686
|
}.freeze
|
650
687
|
end
|
@@ -32,7 +32,12 @@ module TingYun
|
|
32
32
|
def load_instrumentation_files(pattern)
|
33
33
|
Dir.glob(pattern) do |file|
|
34
34
|
begin
|
35
|
-
|
35
|
+
if file.to_s.include?('instrumentation/kafka.rb')
|
36
|
+
# (**options) will report syntax error when ruby version under 2.0.0
|
37
|
+
require file.to_s if (defined? RUBY_VERSION) && (TingYun::Support::VersionNumber.new(RUBY_VERSION) >= TingYun::Support::VersionNumber.new('2.0.0'.freeze))
|
38
|
+
else
|
39
|
+
require file.to_s
|
40
|
+
end
|
36
41
|
rescue LoadError => e
|
37
42
|
TingYun::Agent.logger.warn "Error loading instrumentation file '#{file}':", e
|
38
43
|
end
|
data/lib/ting_yun/frameworks.rb
CHANGED
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'ting_yun/http/generic_request'
|
2
|
+
module TingYun
|
3
|
+
module Http
|
4
|
+
class HttpClientRequest < GenericRequest
|
5
|
+
attr_reader :method, :header
|
6
|
+
|
7
|
+
def initialize(proxy, *args, &block)
|
8
|
+
@method, @uri, @query, @body, @header = args
|
9
|
+
@proxy = proxy
|
10
|
+
@block = block
|
11
|
+
end
|
12
|
+
|
13
|
+
def type
|
14
|
+
'HTTPClient'
|
15
|
+
end
|
16
|
+
|
17
|
+
def from
|
18
|
+
"http_client%2Fhttp"
|
19
|
+
end
|
20
|
+
|
21
|
+
def [](key)
|
22
|
+
@header[key]
|
23
|
+
end
|
24
|
+
|
25
|
+
def []=(key, value)
|
26
|
+
@header[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def uri
|
30
|
+
return @uri if @uri.scheme && @uri.host && @uri.port
|
31
|
+
URI("#{@proxy.scheme.downcase}://#{@proxy.host}:#{@proxy.port}#{@uri}")
|
32
|
+
end
|
33
|
+
|
34
|
+
def args
|
35
|
+
return @method, @uri, @query, @body, @header
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -2,10 +2,11 @@
|
|
2
2
|
require 'ting_yun/agent/transaction/transaction_state'
|
3
3
|
require 'ting_yun/instrumentation/support/active_record_helper'
|
4
4
|
require 'ting_yun/support/helper'
|
5
|
-
require 'ting_yun/agent/
|
5
|
+
require 'ting_yun/agent/method_tracer_helpers'
|
6
6
|
require 'ting_yun/agent/collector/transaction_sampler'
|
7
7
|
require 'ting_yun/agent/collector/sql_sampler'
|
8
8
|
require 'ting_yun/agent/database'
|
9
|
+
require 'ting_yun/instrumentation/support/sinatra_helper'
|
9
10
|
|
10
11
|
module TingYun
|
11
12
|
module Instrumentation
|
@@ -43,14 +44,14 @@ module TingYun
|
|
43
44
|
|
44
45
|
state = TingYun::Agent::TransactionState.tl_get
|
45
46
|
sql, name, _ = args
|
46
|
-
metrics = ::TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for(
|
47
|
+
klass_name, *metrics = ::TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for(
|
47
48
|
TingYun::Helper.correctly_encoded(name),
|
48
49
|
TingYun::Helper.correctly_encoded(sql),
|
49
|
-
@config
|
50
|
+
@config)
|
50
51
|
|
51
52
|
scoped_metric = metrics.first
|
52
53
|
|
53
|
-
TingYun::Agent::
|
54
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, {}, nil, klass_name) do
|
54
55
|
t0 = Time.now
|
55
56
|
begin
|
56
57
|
log_without_tingyun_instrumentation(*args, &block)
|
@@ -72,10 +73,15 @@ end
|
|
72
73
|
TingYun::Support::LibraryDetection.defer do
|
73
74
|
named :active_record
|
74
75
|
|
76
|
+
depends_on do
|
77
|
+
!::TingYun::Agent.config[:disable_active_record]
|
78
|
+
end
|
79
|
+
|
75
80
|
depends_on do
|
76
81
|
defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) &&
|
77
82
|
(!defined?(::ActiveRecord::VERSION) ||
|
78
|
-
::ActiveRecord::VERSION::MAJOR.to_i <= 3
|
83
|
+
::ActiveRecord::VERSION::MAJOR.to_i <= 3 ||
|
84
|
+
(defined?(::Sinatra) && defined?(::Sinatra::Base) && TingYun::Instrumentation::Support::SinatraHelper.version_supported?))
|
79
85
|
end
|
80
86
|
|
81
87
|
executes do
|
@@ -0,0 +1,142 @@
|
|
1
|
+
TingYun::Support::LibraryDetection.defer do
|
2
|
+
named :bunny
|
3
|
+
|
4
|
+
depends_on do
|
5
|
+
defined?(::Bunny::VERSION) && false
|
6
|
+
end
|
7
|
+
|
8
|
+
|
9
|
+
executes do
|
10
|
+
TingYun::Agent.logger.info 'Installing bunny(for rabbitmq) Instrumentation'
|
11
|
+
require 'ting_yun/support/helper'
|
12
|
+
require 'ting_yun/instrumentation/support/external_helper'
|
13
|
+
end
|
14
|
+
|
15
|
+
executes do
|
16
|
+
::Bunny::Exchange.class_eval do
|
17
|
+
|
18
|
+
if public_method_defined? :publish
|
19
|
+
include TingYun::Instrumentation::Support::ExternalHelper
|
20
|
+
def publish_with_tingyun(payload, opts = {})
|
21
|
+
begin
|
22
|
+
state = TingYun::Agent::TransactionState.tl_get
|
23
|
+
return publish_without_tingyun(payload, opts) unless state.execution_traced?
|
24
|
+
queue_name = opts[:routing_key]
|
25
|
+
opts[:headers] = {} unless opts[:headers]
|
26
|
+
opts[:headers][:TingyunID] = create_tingyun_id("mq")
|
27
|
+
metric_name = "Message RabbitMQ/#{@channel.connection.host}:#{@channel.connection.port}%2F"
|
28
|
+
if name.empty?
|
29
|
+
metric_name << "Queue%2F#{queue_name}/Produce"
|
30
|
+
else
|
31
|
+
metric_name << "Exchange%2F#{name}/Produce"
|
32
|
+
end
|
33
|
+
|
34
|
+
summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('RabbitMQ', "#{@channel.connection.host}:#{@channel.connection.port}", 'Produce')
|
35
|
+
TingYun::Agent::Transaction.wrap(state, metric_name , :RabbitMq, {}, summary_metrics) do
|
36
|
+
TingYun::Agent.record_metric("#{metric_name}%2FByte",payload.bytesize) if payload
|
37
|
+
publish_without_tingyun(payload, opts)
|
38
|
+
end
|
39
|
+
rescue => e
|
40
|
+
TingYun::Agent.logger.error("Failed to Bunny publish_with_tingyun : ", e)
|
41
|
+
publish_without_tingyun(payload, opts)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
|
47
|
+
|
48
|
+
alias_method :publish_without_tingyun, :publish
|
49
|
+
alias_method :publish, :publish_with_tingyun
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
::Bunny::Consumer.class_eval do
|
55
|
+
|
56
|
+
if public_method_defined?(:call) && TingYun::Agent.config[:'nbs.mq.conume']
|
57
|
+
|
58
|
+
def call_with_tingyun(*args)
|
59
|
+
begin
|
60
|
+
headers = args[1]&&args[1][:headers].clone
|
61
|
+
tingyun_id_secret = headers["TingyunID"]
|
62
|
+
state = TingYun::Agent::TransactionState.tl_get
|
63
|
+
metric_name = "#{@channel.connection.host}:#{@channel.connection.port}%2FQueue%2F#{queue_name}/Consume"
|
64
|
+
summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('RabbitMQ', "#{@channel.connection.host}:#{@channel.connection.port}", 'Consume')
|
65
|
+
TingYun::Agent::Transaction.start(state,:message, { :transaction_name => "WebAction/RabbitMQ/Queue%2F#{queue_name}/Consume"})
|
66
|
+
state.save_referring_transaction_info(tingyun_id_secret.split(';')) if cross_app_enabled?(tingyun_id_secret)
|
67
|
+
TingYun::Agent::Transaction.wrap(state, "Message RabbitMQ/#{metric_name}" , :RabbitMq, {}, summary_metrics) do
|
68
|
+
TingYun::Agent.record_metric("Message RabbitMQ/#{metric_name}%2FByte",args[2].bytesize) if args[2]
|
69
|
+
TingYun::Agent.record_metric("Message RabbitMQ/#{metric_name}%2FWait", TingYun::Helper.time_to_millis(Time.now)-state.externel_time.to_i) rescue nil
|
70
|
+
if state.current_transaction
|
71
|
+
state.add_custom_params("message.byte",args[2].bytesize)
|
72
|
+
state.add_custom_params("message.wait",TingYun::Helper.time_to_millis(Time.now)-state.externel_time.to_i)
|
73
|
+
state.add_custom_params("message.routingkey",queue_name)
|
74
|
+
headers.delete("TingyunID")
|
75
|
+
state.merge_request_parameters(headers)
|
76
|
+
end
|
77
|
+
call_without_tingyun(*args)
|
78
|
+
state.current_transaction.attributes.add_agent_attribute(:entryTrace, build_payload(state)) if state.same_account?
|
79
|
+
end
|
80
|
+
rescue => e
|
81
|
+
TingYun::Agent.logger.error("Failed to Bunny call_with_tingyun : ", e)
|
82
|
+
call_without_tingyun(*args)
|
83
|
+
ensure
|
84
|
+
TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
alias_method :call_without_tingyun, :call
|
89
|
+
alias_method :call, :call_with_tingyun
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
def cross_app_enabled?(tingyun_id_secret)
|
94
|
+
tingyun_id_secret && ::TingYun::Agent.config[:tingyunIdSecret]
|
95
|
+
end
|
96
|
+
|
97
|
+
def build_payload(state)
|
98
|
+
timings = state.timings
|
99
|
+
payload = {
|
100
|
+
:applicationId => TingYun::Agent.config[:tingyunIdSecret].split('|')[1],
|
101
|
+
:transactionId => state.client_transaction_id,
|
102
|
+
:externalId => state.extenel_req_id,
|
103
|
+
:time => {
|
104
|
+
:duration => timings.app_time_in_millis,
|
105
|
+
:qu => timings.queue_time_in_millis,
|
106
|
+
:db => timings.sql_duration,
|
107
|
+
:ex => timings.external_duration,
|
108
|
+
:rds => timings.rds_duration,
|
109
|
+
:mc => timings.mc_duration,
|
110
|
+
:mon => timings.mon_duration,
|
111
|
+
:code => timings.app_execute_duration
|
112
|
+
}
|
113
|
+
}
|
114
|
+
payload
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
::Bunny::Channel.class_eval do
|
119
|
+
if public_method_defined?(:basic_get)&& TingYun::Agent.config[:'nbs.mq.conume']
|
120
|
+
def basic_get_with_tingyun(*args)
|
121
|
+
begin
|
122
|
+
state = TingYun::Agent::TransactionState.tl_get
|
123
|
+
metric_name = "#{@connection.host}:#{@connection.port}%2FQueue%2F#{args[0]}/Consume"
|
124
|
+
summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('RabbitMQ', "#{connection.host}:#{connection.port}", 'Consume')
|
125
|
+
TingYun::Agent::Transaction.wrap(state, "Message RabbitMQ/#{metric_name}" , :RabbitMq, {}, summary_metrics) do
|
126
|
+
basic_get_without_tingyun(*args)
|
127
|
+
end
|
128
|
+
rescue =>e
|
129
|
+
TingYun::Agent.logger.error("Failed to Bunny basic_get_with_tingyun : ", e)
|
130
|
+
basic_get_without_tingyun(*args)
|
131
|
+
ensure
|
132
|
+
TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
alias_method :basic_get_without_tingyun, :basic_get
|
137
|
+
alias_method :basic_get, :basic_get_with_tingyun
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ting_yun/agent/transaction/transaction_state'
|
3
|
+
require 'ting_yun/instrumentation/support/active_record_helper'
|
4
|
+
require 'ting_yun/agent/method_tracer_helpers'
|
5
|
+
|
6
|
+
module TingYun::Instrumentation::DataMapper
|
7
|
+
|
8
|
+
MIN_SUPPORT_VERSION = '1.1.0.rc1'.freeze
|
9
|
+
|
10
|
+
def self.supported_version?
|
11
|
+
::TingYun::Support::VersionNumber.new(::DataMapper::VERSION) >= ::TingYun::Support::VersionNumber.new(MIN_SUPPORT_VERSION)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.support_data_mapper?
|
15
|
+
defined?(::DataMapper) &&
|
16
|
+
((defined?(::DataMapper::Adapters) && defined?(::DataMapper::Adapters::DataObjectsAdapter)) ||
|
17
|
+
(defined?(::DataMapper::Aggregates) && defined?(::DataMapper::Aggregates::DataObjectsAdapter))) &&
|
18
|
+
supported_version?
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
TingYun::Support::LibraryDetection.defer do
|
24
|
+
named :data_mapper
|
25
|
+
|
26
|
+
depends_on do
|
27
|
+
!::TingYun::Agent.config[:disable_data_mapper]
|
28
|
+
end
|
29
|
+
|
30
|
+
depends_on do
|
31
|
+
begin
|
32
|
+
require 'dm-do-adapter'
|
33
|
+
TingYun::Instrumentation::DataMapper.support_data_mapper?
|
34
|
+
rescue LoadError
|
35
|
+
false
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
executes do
|
40
|
+
::TingYun::Agent.logger.info 'Installing DataMapper instrumentation'
|
41
|
+
end
|
42
|
+
|
43
|
+
executes do
|
44
|
+
|
45
|
+
if defined?(::DataMapper::Adapters) && defined?(::DataMapper::Adapters::DataObjectsAdapter)
|
46
|
+
::DataMapper::Adapters::DataObjectsAdapter.class_eval do
|
47
|
+
|
48
|
+
def create(resources)
|
49
|
+
name = self.name
|
50
|
+
|
51
|
+
resources.each do |resource|
|
52
|
+
model = resource.model
|
53
|
+
state = TingYun::Agent::TransactionState.tl_get
|
54
|
+
*params = get_metrics_params(:create, model)
|
55
|
+
klass_name, *metrics = ::TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for_data_mapper(*params)
|
56
|
+
|
57
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, {}, nil, klass_name) do
|
58
|
+
t0 = Time.now
|
59
|
+
begin
|
60
|
+
serial = model.serial(name)
|
61
|
+
attributes = resource.dirty_attributes
|
62
|
+
|
63
|
+
properties = []
|
64
|
+
bind_values = []
|
65
|
+
|
66
|
+
# make the order of the properties consistent
|
67
|
+
model.properties(name).each do |property|
|
68
|
+
next unless attributes.key?(property)
|
69
|
+
|
70
|
+
bind_value = attributes[property]
|
71
|
+
|
72
|
+
# skip insering NULL for columns that are serial or without a default
|
73
|
+
next if bind_value.nil? && (property.serial? || !property.default?)
|
74
|
+
|
75
|
+
# if serial is being set explicitly, do not set it again
|
76
|
+
if property.equal?(serial)
|
77
|
+
serial = nil
|
78
|
+
end
|
79
|
+
|
80
|
+
properties << property
|
81
|
+
bind_values << bind_value
|
82
|
+
end
|
83
|
+
|
84
|
+
statement = insert_statement(model, properties, serial)
|
85
|
+
|
86
|
+
result = with_connection do |connection|
|
87
|
+
connection.create_command(statement).execute_non_query(*bind_values)
|
88
|
+
end
|
89
|
+
|
90
|
+
if result.affected_rows == 1 && serial
|
91
|
+
serial.set!(resource, result.insert_id)
|
92
|
+
end
|
93
|
+
ensure
|
94
|
+
elapsed_time = (Time.now - t0).to_f
|
95
|
+
state.timings.sql_duration = state.timings.sql_duration + elapsed_time * 1000
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
[:read, :update, :delete, :select, :execute].each do |method|
|
102
|
+
next unless public_method_defined? method
|
103
|
+
alias_method "#{method}_without_tingyun_trace".to_sym, method.to_sym
|
104
|
+
|
105
|
+
define_method method do |*args, &block|
|
106
|
+
state = TingYun::Agent::TransactionState.tl_get
|
107
|
+
*params = get_metrics_params(method, *args, &block)
|
108
|
+
klass_name, *metrics = ::TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for_data_mapper(*params)
|
109
|
+
|
110
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, {}, nil, klass_name) do
|
111
|
+
t0 = Time.now
|
112
|
+
begin
|
113
|
+
send "#{method}_without_tingyun_trace", *args, &block
|
114
|
+
ensure
|
115
|
+
elapsed_time = (Time.now - t0).to_f
|
116
|
+
state.timings.sql_duration = state.timings.sql_duration + elapsed_time * 1000
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def get_metrics_params(method, *args, &block)
|
123
|
+
case method
|
124
|
+
when :read
|
125
|
+
query = args[0]
|
126
|
+
return TingYun::Helper.correctly_encoded('SELECT'), nil, self.normalized_uri, DataMapper::Inflector.classify(query.model.storage_name(name))
|
127
|
+
when :update
|
128
|
+
collection = args[1]
|
129
|
+
return TingYun::Helper.correctly_encoded('UPDATE'), nil, self.normalized_uri, DataMapper::Inflector.classify(collection.query.model.storage_name(name))
|
130
|
+
when :delete
|
131
|
+
collection = args[0]
|
132
|
+
return TingYun::Helper.correctly_encoded('DELETE'), nil, self.normalized_uri, DataMapper::Inflector.classify(collection.query.model.storage_name(name))
|
133
|
+
when :create
|
134
|
+
model = args[0]
|
135
|
+
return TingYun::Helper.correctly_encoded('INSERT'), nil, self.normalized_uri, DataMapper::Inflector.classify(model.storage_name(name))
|
136
|
+
when :select, :execute
|
137
|
+
sql = args[0]
|
138
|
+
return nil, sql, self.normalized_uri
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
if defined?(::DataMapper::Aggregates) && defined?(::DataMapper::Aggregates::DataObjectsAdapter)
|
145
|
+
::DataMapper::Aggregates::DataObjectsAdapter.class_eval do
|
146
|
+
|
147
|
+
alias_method :aggregate_without_tingyun_trace, :aggregate
|
148
|
+
|
149
|
+
def aggregate(*args, &block)
|
150
|
+
state = TingYun::Agent::TransactionState.tl_get
|
151
|
+
*params = get_metrics_params(:read, *args, &block)
|
152
|
+
klass_name, *metrics = ::TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for_data_mapper(*params)
|
153
|
+
|
154
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, {}, nil, klass_name) do
|
155
|
+
t0 = Time.now
|
156
|
+
begin
|
157
|
+
aggregate_without_tingyun_trace(*args, &block)
|
158
|
+
ensure
|
159
|
+
elapsed_time = (Time.now - t0).to_f
|
160
|
+
state.timings.sql_duration = state.timings.sql_duration + elapsed_time * 1000
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'ting_yun/agent/transaction'
|
3
|
+
require 'ting_yun/agent/transaction/transaction_state'
|
4
|
+
|
5
|
+
TingYun::Support::LibraryDetection.defer do
|
6
|
+
named :grape
|
7
|
+
|
8
|
+
depends_on do
|
9
|
+
defined?(::Grape) && defined?(::Grape::Endpoint)
|
10
|
+
end
|
11
|
+
|
12
|
+
executes do
|
13
|
+
TingYun::Agent.logger.info 'Installing grape instrumentation'
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
executes do
|
18
|
+
::Grape::Endpoint.class_eval do
|
19
|
+
def run_with_tingyun(*args)
|
20
|
+
begin
|
21
|
+
name = ["Grape",
|
22
|
+
self.options[:method].first,
|
23
|
+
self.options[:for].to_s,
|
24
|
+
self.namespace.sub(%r{\A/}, ''), # removing leading slashes
|
25
|
+
self.options[:path].first.sub(%r{\A/}, ''),
|
26
|
+
].compact.select{ |n| n.to_s unless n.to_s.empty? }.join("/")
|
27
|
+
TingYun::Agent::Transaction.set_default_transaction_name(name, :controller)
|
28
|
+
run_without_tingyun(*args)
|
29
|
+
rescue => e
|
30
|
+
TingYun::Agent.logger.info("Error getting Grape Endpoint Name. Error: #{e.message}. Options: #{self.options.inspect}")
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
alias run_without_tingyun run
|
35
|
+
alias run run_with_tingyun
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|