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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29a46f9e5110b810ddbb29e1b593e25bf725c831
|
4
|
+
data.tar.gz: f6b0999a21a723f30279702f07c286cfa0ad17ca
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f20f812206d86863956dc05afb7da78c2e559dc95ef9d9971e3d5d0d3210f1739ddb011e0234b634038c7c0204520fde8914f55bf2772a55070702a5e8ab9a83
|
7
|
+
data.tar.gz: b58306111cfcc24c1f88d3467da3b9a77e5e410b8c8b93e2ebdafafe5c72922828e03c9abb6a89b00ff75d8a8dfd71163b6b582363ce7139a78cb034a6aef36c
|
data/.gitignore
CHANGED
data/lib/ting_yun/agent/agent.rb
CHANGED
@@ -95,8 +95,16 @@ module TingYun
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
+
def sinatra_classic_app?
|
99
|
+
defined?(::Sinatra::Base) && ::Sinatra::Base.respond_to?(:run!)
|
100
|
+
end
|
101
|
+
|
102
|
+
def should_install_exit_handler?
|
103
|
+
!sinatra_classic_app?
|
104
|
+
end
|
98
105
|
|
99
106
|
def install_exit_handler
|
107
|
+
return unless should_install_exit_handler?
|
100
108
|
TingYun::Agent.logger.debug("Installing at_exit handler")
|
101
109
|
at_exit do
|
102
110
|
if defined?(RUBY_ENGINE) && RUBY_ENGINE == "ruby" && RUBY_VERSION.match(/^1\.9/)
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module TingYun
|
2
|
+
module Agent
|
3
|
+
module Collector
|
4
|
+
class BaseQuantileHash
|
5
|
+
attr_reader :hash
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@hash = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
def merge!(hash)
|
12
|
+
hash.each do |name, time|
|
13
|
+
@hash[name] ||= []
|
14
|
+
@hash[name] << time
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -127,6 +127,7 @@ module TingYun
|
|
127
127
|
def reset!
|
128
128
|
with_stats_lock do
|
129
129
|
@stats_hash = StatsHash.new
|
130
|
+
@base_quantile_hash = BaseQuantileHash.new
|
130
131
|
end
|
131
132
|
end
|
132
133
|
|
@@ -140,6 +141,15 @@ module TingYun
|
|
140
141
|
snapshot
|
141
142
|
end
|
142
143
|
|
144
|
+
def harvest_base_quantile_hash!
|
145
|
+
snapshot = nil
|
146
|
+
with_stats_lock do
|
147
|
+
snapshot = @base_quantile_hash
|
148
|
+
@base_quantile_hash = BaseQuantileHash.new
|
149
|
+
end
|
150
|
+
snapshot
|
151
|
+
end
|
152
|
+
|
143
153
|
# Renamed to reset!, here for backwards compatibility with 3rd-party
|
144
154
|
# gems (though this really isn't part of the public API).
|
145
155
|
# @deprecated
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'ting_yun/agent/collector/stats_engine/stats_hash'
|
4
4
|
require 'ting_yun/agent/collector/stats_engine/metric_stats'
|
5
|
+
require 'ting_yun/agent/collector/stats_engine/base_quantile_hash'
|
5
6
|
|
6
7
|
module TingYun
|
7
8
|
module Agent
|
@@ -11,10 +12,12 @@ module TingYun
|
|
11
12
|
|
12
13
|
include MetricStats
|
13
14
|
|
15
|
+
attr_reader :base_quantile_hash
|
14
16
|
|
15
17
|
def initialize
|
16
18
|
@stats_lock = Mutex.new
|
17
19
|
@stats_hash = StatsHash.new
|
20
|
+
@base_quantile_hash = BaseQuantileHash.new
|
18
21
|
end
|
19
22
|
|
20
23
|
# All access to the @stats_hash ivar should be funnelled through this
|
@@ -22,6 +25,12 @@ module TingYun
|
|
22
25
|
def with_stats_lock
|
23
26
|
@stats_lock.synchronize { yield }
|
24
27
|
end
|
28
|
+
|
29
|
+
def record_base_quantile(hash)
|
30
|
+
with_stats_lock do
|
31
|
+
@base_quantile_hash.merge!(hash)
|
32
|
+
end
|
33
|
+
end
|
25
34
|
end
|
26
35
|
end
|
27
36
|
end
|
@@ -14,10 +14,10 @@ module TingYun
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# Informs the transaction sample builder about the end of a traced frame
|
17
|
-
def notice_pop_frame(state, frame, time = Time.now)
|
17
|
+
def notice_pop_frame(state, frame, time = Time.now, klass_name=nil)
|
18
18
|
builder = state.transaction_sample_builder
|
19
19
|
return unless builder
|
20
|
-
builder.trace_exit(frame, time.to_f)
|
20
|
+
builder.trace_exit(frame, time.to_f, klass_name)
|
21
21
|
end
|
22
22
|
|
23
23
|
|
@@ -35,9 +35,9 @@ module TingYun
|
|
35
35
|
begin
|
36
36
|
node = start_trace(state, t0, request)
|
37
37
|
response = yield
|
38
|
-
capture_exception(response, request
|
38
|
+
capture_exception(response, request)
|
39
39
|
rescue => e
|
40
|
-
klass = "External/#{request.uri.to_s.gsub('/','%2F')}
|
40
|
+
klass = "External/#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{request.from}"
|
41
41
|
handle_error(e, klass)
|
42
42
|
ensure
|
43
43
|
finish_trace(state, t0, node, request, response)
|
@@ -89,7 +89,7 @@ module TingYun
|
|
89
89
|
::TingYun::Agent::Collector::TransactionSampler.add_node_info(:uri => TingYun::Agent::HTTPClients::URIUtil.filter_uri(request.uri))
|
90
90
|
if cross_app
|
91
91
|
::TingYun::Agent::Collector::TransactionSampler.tl_builder.set_txId_and_txData(state.client_transaction_id || state.request_guid,
|
92
|
-
|
92
|
+
TingYun::Support::Serialize::JSONWrapper.load(get_ty_data_header(response).gsub("'",'"')))
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
@@ -123,8 +123,8 @@ module TingYun
|
|
123
123
|
|
124
124
|
def metrics_for_regular_request( request )
|
125
125
|
metrics = []
|
126
|
-
metrics << "External/#{request.uri.to_s.gsub('/','%2F')}
|
127
|
-
metrics << "External/#{request.uri.to_s.gsub('/','%2F')}
|
126
|
+
metrics << "External/#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{request.from}"
|
127
|
+
metrics << "External/#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{request.from}"
|
128
128
|
|
129
129
|
return metrics
|
130
130
|
end
|
@@ -138,8 +138,7 @@ module TingYun
|
|
138
138
|
|
139
139
|
# Inject the X-Process header into the outgoing +request+.
|
140
140
|
def inject_request_headers(state, request)
|
141
|
-
cross_app_id = TingYun::Agent.config[:tingyunIdSecret]
|
142
|
-
raise TingYun::Agent::CrossAppTracing::Error, "no tingyunIdSecret configured"
|
141
|
+
cross_app_id = TingYun::Agent.config[:tingyunIdSecret]
|
143
142
|
|
144
143
|
request[TY_ID_HEADER] = "#{cross_app_id};c=1;x=#{state.request_guid}"
|
145
144
|
end
|
@@ -148,8 +147,8 @@ module TingYun
|
|
148
147
|
# has the appropriate headers.
|
149
148
|
def response_is_cross_app?( response )
|
150
149
|
return false unless response
|
151
|
-
return false unless response[TY_DATA_HEADER]
|
152
150
|
return false unless cross_app_enabled?
|
151
|
+
return false unless get_ty_data_header(response)
|
153
152
|
|
154
153
|
return true
|
155
154
|
end
|
@@ -157,8 +156,8 @@ module TingYun
|
|
157
156
|
# Return the set of metric objects appropriate for the given cross app
|
158
157
|
# +response+.
|
159
158
|
def metrics_for_cross_app_response(request, response )
|
160
|
-
my_data = TingYun::Support::Serialize::JSONWrapper.load response
|
161
|
-
uri = "#{request.uri.to_s.gsub('/','%2F')}
|
159
|
+
my_data = TingYun::Support::Serialize::JSONWrapper.load get_ty_data_header(response).gsub("'",'"')
|
160
|
+
uri = "#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{request.from}"
|
162
161
|
metrics = []
|
163
162
|
metrics << "cross_app;#{my_data["id"]};#{my_data["action"]};#{uri}"
|
164
163
|
metrics << "External/#{my_data["action"]}:#{uri}"
|
@@ -166,6 +165,13 @@ module TingYun
|
|
166
165
|
return metrics
|
167
166
|
end
|
168
167
|
|
168
|
+
def get_ty_data_header(response)
|
169
|
+
if defined?(::HTTP) && defined?(::HTTP::Message) && response.class == ::HTTP::Message
|
170
|
+
response.header[TY_DATA_HEADER].first rescue nil
|
171
|
+
else
|
172
|
+
response[TY_DATA_HEADER] rescue nil
|
173
|
+
end
|
174
|
+
end
|
169
175
|
end
|
170
176
|
end
|
171
177
|
end
|
@@ -9,7 +9,7 @@ module TingYun
|
|
9
9
|
ALL_WEB = "AllWeb".freeze
|
10
10
|
ALL_BACKGROUND = "AllBackground".freeze
|
11
11
|
ALL = "All".freeze
|
12
|
-
|
12
|
+
UNKNOWN = 'Unknown'.freeze
|
13
13
|
NOSQL = %w(MongoDB Redis Memcached).freeze
|
14
14
|
|
15
15
|
CACHE = %w(Redis Memcached).freeze
|
@@ -18,11 +18,21 @@ module TingYun
|
|
18
18
|
NOSQL.include?(product)
|
19
19
|
end
|
20
20
|
|
21
|
-
def self.metric_name(product, collection, operation)
|
21
|
+
def self.metric_name(product, collection, operation,host,port,dbname)
|
22
|
+
if checkNosql(product)
|
23
|
+
return "#{product}/#{host}:#{port}%2F#{dbname}%2F#{collection}/#{operation}" if product=="MongoDB"
|
24
|
+
"#{product}/#{host}:#{port}%2F#{collection}/#{operation}"
|
25
|
+
else
|
26
|
+
"Database #{product}/#{host}:#{port}%2F#{dbname}%2F#{collection}/#{operation}"
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.metric_name_others(product, collection, operation)
|
31
|
+
collection ||= 'NULL'
|
22
32
|
if checkNosql(product)
|
23
|
-
|
33
|
+
"#{product}%2F#{collection}/#{operation}"
|
24
34
|
else
|
25
|
-
"Database #{product}
|
35
|
+
"Database #{product}%2F#{collection}/#{operation}"
|
26
36
|
end
|
27
37
|
end
|
28
38
|
|
@@ -34,9 +44,16 @@ module TingYun
|
|
34
44
|
end
|
35
45
|
end
|
36
46
|
|
47
|
+
def self.metrics_for_message(product, ip_host, operation)
|
48
|
+
metrics = TingYun::Agent::Transaction.recording_web_transaction? ? [ALL_WEB, ALL] : [ALL_BACKGROUND, ALL]
|
49
|
+
metrics = metrics.map { |suffix| "Message #{product}/NULL/#{suffix}" }
|
50
|
+
metrics.unshift "Message #{product}/#{ip_host}/#{operation}"
|
51
|
+
end
|
37
52
|
|
38
|
-
|
39
|
-
|
53
|
+
def self.metrics_for(product, operation, host = UNKNOWN, port = 0, dbname = UNKNOWN, collection = nil, generic_product = nil )
|
54
|
+
dbname ||= UNKNOWN
|
55
|
+
host ||= UNKNOWN
|
56
|
+
port ||= UNKNOWN
|
40
57
|
operation = operation.to_s.upcase
|
41
58
|
if overrides = overridden_operation_and_collection # [method, model_name, product]
|
42
59
|
if should_override?(overrides, product, generic_product)
|
@@ -56,7 +73,14 @@ module TingYun
|
|
56
73
|
product_suffixed_rollup(product,suffix)
|
57
74
|
end
|
58
75
|
|
59
|
-
|
76
|
+
if checkNosql(product)
|
77
|
+
metrics << (product=="MongoDB" ? "#{product}/#{host}:#{port}%2F#{dbname}/All" : "#{product}/#{host}:#{port}/All")
|
78
|
+
else
|
79
|
+
metrics << "Database #{product}/#{host}:#{port}%2F#{dbname}/All"
|
80
|
+
end
|
81
|
+
metrics.unshift metric_name(product, collection, operation,host,port,dbname) if collection
|
82
|
+
metrics.unshift "#{product}/#{host}:#{port}/#{operation}" if product=="Memcached"
|
83
|
+
metrics.unshift metric_name_others(product, collection, operation)
|
60
84
|
metrics
|
61
85
|
end
|
62
86
|
|
@@ -1,29 +1,24 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
3
|
require 'ting_yun/agent/datastore/metric_helper'
|
4
|
-
require 'ting_yun/agent/
|
4
|
+
require 'ting_yun/agent/method_tracer_helpers'
|
5
5
|
|
6
6
|
|
7
7
|
module TingYun
|
8
8
|
module Agent
|
9
9
|
module Datastore
|
10
|
-
|
11
|
-
|
12
|
-
def self.wrap(product, operation, collection = nil, callback = nil)
|
10
|
+
def self.wrap(product, operation, collection = nil, ip_address = nil, port = nil, dbname=nil, callback = nil )
|
13
11
|
return yield unless operation
|
14
12
|
|
15
|
-
metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for(product, operation, collection)
|
16
|
-
|
17
|
-
scoped_metric = metrics.last
|
18
|
-
|
19
|
-
TingYun::Agent::MethodTracer.trace_execution_scoped(metrics) do
|
13
|
+
klass_name, *metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for(product, operation, ip_address , port, dbname,collection )
|
14
|
+
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metrics, {}, nil, klass_name) do
|
20
15
|
t0 = Time.now
|
21
16
|
begin
|
22
|
-
|
17
|
+
yield
|
23
18
|
ensure
|
24
19
|
elapsed_time = (Time.now - t0).to_f
|
25
20
|
if callback
|
26
|
-
callback.call(
|
21
|
+
callback.call(elapsed_time)
|
27
22
|
end
|
28
23
|
end
|
29
24
|
end
|
@@ -17,11 +17,15 @@ module TingYun
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def on_transaction(*_)
|
20
|
-
return unless needs_restart?
|
20
|
+
return unless restart_in_children_enabled? && needs_restart?
|
21
21
|
|
22
22
|
restart_harvest_thread
|
23
23
|
end
|
24
24
|
|
25
|
+
def restart_in_children_enabled?
|
26
|
+
TingYun::Agent.config[:restart_thread_in_children]
|
27
|
+
end
|
28
|
+
|
25
29
|
def mark_started(pid = Process.pid)
|
26
30
|
@starting_pid = pid
|
27
31
|
end
|
@@ -120,7 +120,11 @@ module TingYun
|
|
120
120
|
def send_data_to_endpoint(endpoint, items, container)
|
121
121
|
TingYun::Agent.logger.info("Sending #{items.size} items to #{endpoint}")
|
122
122
|
begin
|
123
|
-
|
123
|
+
if container.respond_to?(:harvest_base_quantile_hash!)
|
124
|
+
@service.send(endpoint, items, container.harvest_base_quantile_hash!)
|
125
|
+
else
|
126
|
+
@service.send(endpoint, items)
|
127
|
+
end
|
124
128
|
rescue => e
|
125
129
|
TingYun::Agent.logger.info("Unable to send #{endpoint} data, will try again later. Error: ", e)
|
126
130
|
# container.merge!(items)
|
@@ -43,6 +43,11 @@ module TingYun
|
|
43
43
|
end
|
44
44
|
@event_loop.fire_every(Agent.config[:data_report_period], :report_data)
|
45
45
|
|
46
|
+
@event_loop.on(:create_new_logfile) do
|
47
|
+
TingYun::Logger::CreateLoggerHelper.create_new_logfile
|
48
|
+
end
|
49
|
+
@event_loop.fire_every(TingYun::Agent.config[:agent_log_file_check_days]*60*60*24, :create_new_logfile)
|
50
|
+
|
46
51
|
@event_loop.run
|
47
52
|
end
|
48
53
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
require 'ting_yun/agent'
|
3
3
|
require 'ting_yun/agent/transaction/transaction_state'
|
4
|
+
require 'ting_yun/support/quantile_p2'
|
4
5
|
|
5
6
|
module TingYun
|
6
7
|
module Agent
|
@@ -22,12 +23,12 @@ module TingYun
|
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
def trace_execution_scoped_footer(state, t0, first_name, metric_names, expected_frame, options, t1=Time.now.to_f)
|
26
|
+
def trace_execution_scoped_footer(state, t0, first_name, metric_names, expected_frame, options, t1=Time.now.to_f, klass_name=nil)
|
26
27
|
log_errors(:trace_execution_scoped_footer) do
|
27
28
|
if expected_frame
|
28
29
|
stack = state.traced_method_stack
|
29
30
|
create_metrics = options.has_key?(:metric) ? options[:metric] : true
|
30
|
-
frame = stack.pop_frame(state, expected_frame, first_name, t1, create_metrics)
|
31
|
+
frame = stack.pop_frame(state, expected_frame, first_name, t1, create_metrics, klass_name)
|
31
32
|
|
32
33
|
if create_metrics
|
33
34
|
duration = (t1 - t0)*1000
|
@@ -41,6 +42,9 @@ module TingYun
|
|
41
42
|
"Metric #{first_name} has negative exclusive time: duration = #{duration} ms, child_time = #{frame.children_time}")
|
42
43
|
end
|
43
44
|
record_metrics(state, first_name, metric_names, duration, exclusive, options)
|
45
|
+
if first_name.start_with?('WebAction')
|
46
|
+
state.current_transaction.base_quantile_hash[first_name] = duration
|
47
|
+
end
|
44
48
|
end
|
45
49
|
end
|
46
50
|
end
|
@@ -57,7 +61,7 @@ module TingYun
|
|
57
61
|
end
|
58
62
|
end
|
59
63
|
|
60
|
-
def trace_execution_scoped(metric_names, options={}, callback = nil) #THREAD_LOCAL_ACCESS
|
64
|
+
def trace_execution_scoped(metric_names, options={}, callback = nil, klass_name=nil) #THREAD_LOCAL_ACCESS
|
61
65
|
state = TingYun::Agent::TransactionState.tl_get
|
62
66
|
|
63
67
|
metric_names = Array(metric_names)
|
@@ -74,7 +78,7 @@ module TingYun
|
|
74
78
|
if callback
|
75
79
|
callback.call(elapsed_time)
|
76
80
|
end
|
77
|
-
trace_execution_scoped_footer(state, start_time, first_name, metric_names, expected_scope, options)
|
81
|
+
trace_execution_scoped_footer(state, start_time, first_name, metric_names, expected_scope, options, Time.now.to_f, klass_name)
|
78
82
|
end
|
79
83
|
end
|
80
84
|
|
@@ -5,10 +5,11 @@ module TingYun
|
|
5
5
|
class Transaction
|
6
6
|
class Attributes
|
7
7
|
|
8
|
-
attr_accessor :agent_attributes, :request_params
|
8
|
+
attr_accessor :agent_attributes, :request_params, :custom_params
|
9
9
|
def initialize
|
10
|
-
@agent_attributes = {}
|
10
|
+
@agent_attributes = {:httpStatus => 0} #defaul value
|
11
11
|
@request_params = {}
|
12
|
+
@custom_params = {}
|
12
13
|
end
|
13
14
|
|
14
15
|
# no longer to care about the value if nil or not
|
@@ -20,6 +21,9 @@ module TingYun
|
|
20
21
|
@request_params.merge!(hash) if hash
|
21
22
|
end
|
22
23
|
|
24
|
+
def add_custom_params(key, value)
|
25
|
+
@custom_params[key] = value
|
26
|
+
end
|
23
27
|
end
|
24
28
|
end
|
25
29
|
end
|
@@ -33,7 +33,7 @@ module TingYun
|
|
33
33
|
end
|
34
34
|
|
35
35
|
|
36
|
-
def stop(state, end_time = Time.now)
|
36
|
+
def stop(state, end_time = Time.now, summary_metric_names=[])
|
37
37
|
|
38
38
|
txn = state.current_transaction
|
39
39
|
|
@@ -45,7 +45,7 @@ module TingYun
|
|
45
45
|
nested_frame = txn.frame_stack.pop
|
46
46
|
|
47
47
|
if txn.frame_stack.empty?
|
48
|
-
txn.stop(state, end_time, nested_frame)
|
48
|
+
txn.stop(state, end_time, nested_frame, summary_metric_names)
|
49
49
|
state.reset
|
50
50
|
else
|
51
51
|
nested_name = nested_transaction_name(nested_frame.name)
|
@@ -55,6 +55,7 @@ module TingYun
|
|
55
55
|
else
|
56
56
|
summary_metrics = EMPTY_SUMMARY_METRICS
|
57
57
|
end
|
58
|
+
summary_metrics = summary_metric_names unless summary_metric_names.empty?
|
58
59
|
|
59
60
|
TingYun::Agent::MethodTracerHelpers.trace_execution_scoped_footer(
|
60
61
|
state,
|
@@ -74,7 +75,7 @@ module TingYun
|
|
74
75
|
nil
|
75
76
|
end
|
76
77
|
|
77
|
-
def wrap(state, name, category, options = {})
|
78
|
+
def wrap(state, name, category, options = {}, summary_metrics=[])
|
78
79
|
Transaction.start(state, category, options.merge(:transaction_name => name))
|
79
80
|
|
80
81
|
begin
|
@@ -85,7 +86,8 @@ module TingYun
|
|
85
86
|
Transaction.notice_error(e)
|
86
87
|
raise e
|
87
88
|
ensure
|
88
|
-
|
89
|
+
# when kafka consumer in task, drop original web_action
|
90
|
+
Transaction.stop(state, Time.now, summary_metrics) if state.current_transaction
|
89
91
|
end
|
90
92
|
end
|
91
93
|
|
@@ -115,12 +117,19 @@ module TingYun
|
|
115
117
|
end
|
116
118
|
|
117
119
|
def nested_transaction_name(name)
|
118
|
-
if name.start_with?(CONTROLLER_PREFIX) || name.start_with?(
|
120
|
+
if name.start_with?(CONTROLLER_PREFIX) || name.start_with?(BACKGROUND_PREFIX)
|
119
121
|
"#{SUBTRANSACTION_PREFIX}#{name}"
|
120
122
|
else
|
121
123
|
name
|
122
124
|
end
|
123
125
|
end
|
126
|
+
|
127
|
+
def set_default_transaction_name(name, category = nil, node_name = nil) #THREAD_LOCAL_ACCESS
|
128
|
+
txn = tl_current
|
129
|
+
name = txn.make_transaction_name(name, category)
|
130
|
+
txn.name_last_frame(node_name || name)
|
131
|
+
txn.set_default_transaction_name(name, category)
|
132
|
+
end
|
124
133
|
end
|
125
134
|
end
|
126
135
|
end
|
@@ -1,10 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
-
|
2
|
+
require 'ting_yun/support/quantile_p2'
|
3
3
|
module TingYun
|
4
4
|
module Agent
|
5
5
|
class Transaction
|
6
6
|
module InstanceMethod
|
7
7
|
|
8
|
+
def ignore!
|
9
|
+
@ignore_this_transaction = true
|
10
|
+
end
|
11
|
+
|
12
|
+
def ignore?
|
13
|
+
@ignore_this_transaction
|
14
|
+
end
|
15
|
+
|
8
16
|
def create_nested_frame(state, category, options)
|
9
17
|
@has_children = true
|
10
18
|
frame_stack.push TingYun::Agent::MethodTracerHelpers.trace_execution_scoped_header(state, Time.now.to_f)
|
@@ -25,6 +33,10 @@ module TingYun
|
|
25
33
|
end
|
26
34
|
end
|
27
35
|
|
36
|
+
def make_transaction_name(name, category=nil)
|
37
|
+
namer = TingYun::Instrumentation::Support::TransactionNamer
|
38
|
+
"#{namer.prefix_for_category(self, category)}#{name}"
|
39
|
+
end
|
28
40
|
|
29
41
|
def name_last_frame(name)
|
30
42
|
frame_stack.last.name = name
|
@@ -40,7 +52,7 @@ module TingYun
|
|
40
52
|
!category || frame_stack.size == 1 || similar_category?(category)
|
41
53
|
end
|
42
54
|
|
43
|
-
WEB_TRANSACTION_CATEGORIES = [:controller, :uri, :rack, :sinatra, :grape, :middleware, :thrift].freeze
|
55
|
+
WEB_TRANSACTION_CATEGORIES = [:controller, :uri, :rack, :sinatra, :grape, :middleware, :thrift, :action_cable, :message].freeze
|
44
56
|
|
45
57
|
def web_category?(category)
|
46
58
|
WEB_TRANSACTION_CATEGORIES.include?(category)
|
@@ -57,9 +69,13 @@ module TingYun
|
|
57
69
|
|
58
70
|
alias_method :ignore, :needs_middleware_summary_metrics?
|
59
71
|
|
60
|
-
def record_summary_metrics(outermost_node_name,end_time)
|
72
|
+
def record_summary_metrics(state, outermost_node_name,end_time)
|
61
73
|
unless @frozen_name == outermost_node_name
|
62
|
-
|
74
|
+
time = (end_time.to_f - start_time.to_f) * 1000
|
75
|
+
@metrics.record_unscoped(@frozen_name, time)
|
76
|
+
if @frozen_name.start_with?('WebAction')
|
77
|
+
state.current_transaction.base_quantile_hash[@frozen_name] = time
|
78
|
+
end
|
63
79
|
end
|
64
80
|
end
|
65
81
|
|
@@ -100,7 +100,8 @@ module TingYun
|
|
100
100
|
:referer => string(attributes.agent_attributes[:referer]) || EMPTY_STRING
|
101
101
|
}
|
102
102
|
custom_param[:httpStatus] = int(attributes.agent_attributes[:httpStatus]) if attributes.agent_attributes[:httpStatus]
|
103
|
-
|
103
|
+
custom_param[:entryTrace] = attributes.agent_attributes[:entryTrace] if attributes.agent_attributes[:entryTrace]
|
104
|
+
custom_param.merge! attributes.custom_params
|
104
105
|
custom_param
|
105
106
|
end
|
106
107
|
|
@@ -10,7 +10,7 @@ module TingYun
|
|
10
10
|
class TraceNode
|
11
11
|
|
12
12
|
attr_reader :entry_timestamp, :parent_node, :called_nodes
|
13
|
-
attr_accessor :metric_name, :exit_timestamp, :uri, :count, :klass, :method
|
13
|
+
attr_accessor :metric_name, :exit_timestamp, :uri, :count, :klass, :method, :name
|
14
14
|
|
15
15
|
|
16
16
|
|
@@ -40,13 +40,21 @@ module TingYun
|
|
40
40
|
end
|
41
41
|
|
42
42
|
|
43
|
+
def pre_metric_name(metric_name)
|
44
|
+
@name ||= if metric_name.start_with?('Database ')
|
45
|
+
"#{metric_name.split('/')[0]}%2F#{metric_name.split('%2F')[-1]}"
|
46
|
+
else
|
47
|
+
metric_name
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
43
51
|
def to_array
|
44
52
|
[TingYun::Helper.time_to_millis(entry_timestamp),
|
45
53
|
TingYun::Helper.time_to_millis(exit_timestamp),
|
46
54
|
TingYun::Support::Coerce.string(metric_name),
|
47
55
|
TingYun::Support::Coerce.string(uri)||'',
|
48
56
|
TingYun::Support::Coerce.int(count),
|
49
|
-
TingYun::Support::Coerce.string(klass)||TingYun::Support::Coerce.string(metric_name),
|
57
|
+
TingYun::Support::Coerce.string(klass)||TingYun::Support::Coerce.string(pre_metric_name(metric_name)),
|
50
58
|
TingYun::Support::Coerce.string(method)||'',
|
51
59
|
params] +
|
52
60
|
[(@called_nodes ? @called_nodes.map{|s| s.to_array} : [])]
|
@@ -25,10 +25,10 @@ module TingYun
|
|
25
25
|
frame
|
26
26
|
end
|
27
27
|
|
28
|
-
def pop_frame(state, expected_frame, name, time, deduct_call_time_from_parent=true)
|
28
|
+
def pop_frame(state, expected_frame, name, time, deduct_call_time_from_parent=true, klass_name=nil)
|
29
29
|
frame = fetch_matching_frame(expected_frame)
|
30
30
|
note_children_time(frame, time, deduct_call_time_from_parent)
|
31
|
-
transaction_sampler.notice_pop_frame(state, name, time) if sampler_enabled?
|
31
|
+
transaction_sampler.notice_pop_frame(state, name, time, klass_name) if sampler_enabled?
|
32
32
|
frame.name = name
|
33
33
|
frame
|
34
34
|
end
|
@@ -59,7 +59,7 @@ module TingYun
|
|
59
59
|
@current_node
|
60
60
|
end
|
61
61
|
|
62
|
-
def trace_exit(metric_name, time)
|
62
|
+
def trace_exit(metric_name, time, klass_name)
|
63
63
|
if @current_node.is_a?(PlaceholderNode)
|
64
64
|
@current_node.depth -= 1
|
65
65
|
if @current_node.depth == 0
|
@@ -67,6 +67,7 @@ module TingYun
|
|
67
67
|
end
|
68
68
|
else
|
69
69
|
@current_node.metric_name = metric_name
|
70
|
+
@current_node.klass = klass_name
|
70
71
|
@current_node.end_trace(time.to_f - @trace_start)
|
71
72
|
@current_node = @current_node.parent_node
|
72
73
|
end
|
@@ -17,7 +17,9 @@ module TingYun
|
|
17
17
|
:client_transaction_id,
|
18
18
|
:client_tingyun_id_secret,
|
19
19
|
:client_req_id,
|
20
|
-
:thrift_return_data
|
20
|
+
:thrift_return_data,
|
21
|
+
:extenel_req_id,
|
22
|
+
:externel_time
|
21
23
|
|
22
24
|
|
23
25
|
|
@@ -114,6 +116,10 @@ module TingYun
|
|
114
116
|
@client_transaction_id = m.post_match
|
115
117
|
elsif m = e.match(/r=/)
|
116
118
|
@client_req_id = m.post_match
|
119
|
+
elsif m = e.match(/e=/)
|
120
|
+
@extenel_req_id = m.post_match
|
121
|
+
elsif m = e.match(/s=/)
|
122
|
+
@externel_time = m.post_match
|
117
123
|
end
|
118
124
|
end
|
119
125
|
end
|
@@ -148,6 +154,21 @@ module TingYun
|
|
148
154
|
end
|
149
155
|
end
|
150
156
|
|
157
|
+
# if you wanna call the method, you must make sure current_transaction is not nil at first
|
158
|
+
# if current_transaction
|
159
|
+
# add_custom_params(:key1,:value1)
|
160
|
+
# add_custom_params(:key2,:value2)
|
161
|
+
# end
|
162
|
+
# public api
|
163
|
+
def add_custom_params(key, value)
|
164
|
+
current_transaction.attributes.add_custom_params(key, value)
|
165
|
+
end
|
166
|
+
|
167
|
+
# same to add_custom_params
|
168
|
+
def merge_request_parameters(hash)
|
169
|
+
current_transaction.attributes.merge_request_parameters(hash)
|
170
|
+
end
|
171
|
+
|
151
172
|
end
|
152
173
|
end
|
153
174
|
end
|