tingyun_rpm 1.3.1 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 50bb695bb83ad9675c4a47086f7f2a5e326207a9
4
- data.tar.gz: 112c143fc64d673606db5703acf36f3c622beaf2
3
+ metadata.gz: 1312053248f2f8ee7864297cbd3b53e7c72f8c24
4
+ data.tar.gz: 209f00934dcbd9b67152afbf30bba4a9daa87f1e
5
5
  SHA512:
6
- metadata.gz: ffd6c131b719fd67ce6738b7c100966bff3fc11b71af209288497461d913601e8f0f7c21f12361564263226eec68c1b72f29dfed0be94bbe0ad054eaf1389ed9
7
- data.tar.gz: bcc3e5c521ce1207d6c9b6d37ba4fd3f7d11dd0f3d7efefea03553724db8d075aad32dc4f307a2343e8a44acbc995630cdb9a456c2144414131ac481ad5e2ac7
6
+ metadata.gz: f030da33af531d464405b2f5842d4914273640b22af31cfb796c2b69027cb9c719f263c3fb7645d9ada5198716d469083529ad2ef5cc520784ac4cb50573a836
7
+ data.tar.gz: c13ba652fdf33e0cbbe29fabcef3f2cdb348e8c76ab47bfbaa1f904c3e47aea587f90a8137794cef801b6ce5da5323a1167fd26f8dde8eb5e025f66d88cfd314
@@ -63,10 +63,14 @@ module TingYun
63
63
  # This method is safe to use from any thread.
64
64
  #
65
65
  # @api public
66
- def record_metric(metric_name, value) #THREAD_LOCAL_ACCESS
66
+ def record_metric(metric_name, value, is_scoped=false ) #THREAD_LOCAL_ACCESS
67
67
  return unless agent
68
68
  stats = TingYun::Metrics::Stats.create_from_hash(value) if value.is_a?(Hash)
69
- agent.stats_engine.tl_record_unscoped_metrics(metric_name, stats || value)
69
+ if is_scoped
70
+ agent.stats_engine.tl_record_scoped_metrics(metric_name, stats || value)
71
+ else
72
+ agent.stats_engine.tl_record_unscoped_metrics(metric_name, stats || value)
73
+ end
70
74
  end
71
75
 
72
76
  # Manual agent configuration and startup/shutdown
@@ -185,5 +189,16 @@ module TingYun
185
189
  agent.shutdown if agent
186
190
  end
187
191
 
192
+ # if you wanna call the method, you must make sure current_transaction is not nil at first
193
+ # if current_transaction
194
+ # add_custom_params(:key1,:value1)
195
+ # add_custom_params(:key2,:value2)
196
+ # end
197
+ # public api
198
+ def add_custom_params(key, value)
199
+ txn = TingYun::Agent::TransactionState.tl_get.current_transaction
200
+ txn.attributes.add_custom_params(key, value) if txn
201
+ end
202
+
188
203
  end
189
204
  end
@@ -66,6 +66,24 @@ module TingYun
66
66
  end
67
67
  end
68
68
 
69
+ def tl_record_scoped_metrics(metric_names, value=nil, aux=nil, &blk)
70
+ state = TingYun::Agent::TransactionState.tl_get
71
+ record_scoped_metrics(state, metric_names, value, aux, &blk)
72
+ end
73
+
74
+ def record_scoped_metrics(state, metric_names, value=nil, aux=nil, &blk)
75
+ txn = state.current_transaction
76
+
77
+ if txn
78
+ txn.metrics.record_scoped(metric_names, value, aux, &blk)
79
+ else
80
+ specs = coerce_to_metric_spec_array(metric_names, nil)
81
+ with_stats_lock do
82
+ @stats_hash.record(specs, value, aux, &blk)
83
+ end
84
+ end
85
+ end
86
+
69
87
  # Like tl_record_unscoped_metrics, but records a scoped metric as well.
70
88
  #
71
89
  # This is an internal method, subject to change at any time. Client apps
@@ -62,15 +62,23 @@ module TingYun
62
62
  if request
63
63
  cross_app = response_is_cross_app?(response)
64
64
 
65
- metrics = metrics_for(request, response, cross_app)
65
+ metrics = metrics_for(request)
66
66
  node_name = metrics.pop
67
- scoped_metric = metrics.pop
68
-
69
- ::TingYun::Agent.instance.stats_engine.record_scoped_and_unscoped_metrics(state, scoped_metric, metrics, duration)
67
+ tx_data = TingYun::Support::Serialize::JSONWrapper.load(get_ty_data_header(response).gsub("'",'"')) || {}
68
+ # net_block_duration = tx_data["time"]? duration - tx_data["time"]["duration"]- tx_data["time"]["qu"] : duration
69
+ # net_block_duration = duration if net_block_duration < 0
70
+ ::TingYun::Agent.instance.stats_engine.record_scoped_and_unscoped_metrics(state, node_name, metrics, duration)
71
+ if cross_app
72
+ _duration = tx_data["time"]["duration"] + tx_data["time"]["qu"] + 0.1
73
+ metrics_cross_app = metrics_for_cross_app(request, response)
74
+ txn = state.current_transaction
75
+ txn.metrics.record_scoped(metrics_cross_app.pop, duration, _duration)
76
+ txn.metrics.record_unscoped(metrics_cross_app, _duration)
77
+ end
70
78
 
71
79
  if node
72
80
  node.name = node_name
73
- add_transaction_trace_info(request, response, cross_app)
81
+ add_transaction_trace_info(request, response, cross_app, tx_data)
74
82
  end
75
83
  end
76
84
  rescue => err
@@ -84,52 +92,35 @@ module TingYun
84
92
  end
85
93
 
86
94
 
87
- def add_transaction_trace_info(request, response, cross_app)
95
+ def add_transaction_trace_info(request, response, cross_app, tx_data)
88
96
  state = TingYun::Agent::TransactionState.tl_get
89
97
  ::TingYun::Agent::Collector::TransactionSampler.add_node_info(:uri => TingYun::Agent::HTTPClients::URIUtil.filter_uri(request.uri))
90
98
  if cross_app
91
- ::TingYun::Agent::Collector::TransactionSampler.tl_builder.set_txId_and_txData(state.client_transaction_id || state.request_guid,
92
- TingYun::Support::Serialize::JSONWrapper.load(get_ty_data_header(response).gsub("'",'"')))
99
+ ::TingYun::Agent::Collector::TransactionSampler.tl_builder.set_txId_and_txData(state.client_transaction_id || state.request_guid, tx_data)
93
100
  end
94
101
  end
95
102
 
96
103
 
97
- def metrics_for(request, response, cross_app)
104
+ def metrics_for_cross_app(request, response)
105
+ my_data = TingYun::Support::Serialize::JSONWrapper.load get_ty_data_header(response).gsub("'",'"')
106
+ metrics = ["ExternalTransaction/NULL/#{my_data["id"]}",
107
+ "ExternalTransaction/http/#{my_data["id"]}"]
108
+ metrics << "ExternalTransaction/#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{my_data["id"]}%2F#{my_data["action"].to_s.gsub(/\/\z/,'')}"
109
+ end
98
110
 
111
+ def metrics_for(request)
99
112
  metrics = [ "External/NULL/ALL" ]
100
-
101
113
  if TingYun::Agent::Transaction.recording_web_transaction?
102
114
  metrics << "External/NULL/AllWeb"
103
115
  else
104
116
  metrics << "External/NULL/AllBackground"
105
117
  end
106
-
107
- if cross_app
108
- begin
109
- metrics.concat metrics_for_cross_app_response( request, response )
110
- rescue => err
111
- # Fall back to regular metrics if there's a problem with x-process metrics
112
- TingYun::Agent.logger.debug "%p while fetching x-process metrics: %s" %
113
- [ err.class, err.message ]
114
- metrics.concat metrics_for_regular_request( request )
115
- end
116
- else
117
- metrics.concat metrics_for_regular_request( request )
118
- end
119
-
120
- return metrics
121
- end
122
-
123
-
124
- def metrics_for_regular_request( request )
125
- metrics = []
126
- metrics << "External/#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{request.from}"
127
118
  metrics << "External/#{request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{request.from}"
128
-
129
119
  return metrics
130
120
  end
131
121
 
132
122
 
123
+
133
124
  def cross_app_enabled?
134
125
  TingYun::Agent.config[:tingyunIdSecret] && TingYun::Agent.config[:tingyunIdSecret].size > 0 &&
135
126
  TingYun::Agent.config[:'nbs.action_tracer.enabled'] &&
@@ -148,28 +139,18 @@ module TingYun
148
139
  def response_is_cross_app?( response )
149
140
  return false unless response
150
141
  return false unless cross_app_enabled?
151
- return false unless get_ty_data_header(response)
142
+ return false if get_ty_data_header(response).empty?
152
143
 
153
144
  return true
154
145
  end
155
146
 
156
- # Return the set of metric objects appropriate for the given cross app
157
- # +response+.
158
- def metrics_for_cross_app_response(request, response )
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}"
161
- metrics = []
162
- metrics << "cross_app;#{my_data["id"]};#{my_data["action"]};#{uri}"
163
- metrics << "External/#{my_data["action"]}:#{uri}"
164
147
 
165
- return metrics
166
- end
167
148
 
168
149
  def get_ty_data_header(response)
169
150
  if defined?(::HTTP) && defined?(::HTTP::Message) && response.class == ::HTTP::Message
170
- response.header[TY_DATA_HEADER].first rescue nil
151
+ response.header[TY_DATA_HEADER].first.to_s rescue ""
171
152
  else
172
- response[TY_DATA_HEADER] rescue nil
153
+ response[TY_DATA_HEADER].to_s rescue ""
173
154
  end
174
155
  end
175
156
  end
@@ -75,6 +75,7 @@ module TingYun
75
75
 
76
76
  @has_children = false
77
77
  @category = category
78
+ @is_mq = options[:mq] || false
78
79
 
79
80
  @guid = client_transaction_id || generate_guid
80
81
  @frame_stack = []
@@ -97,6 +98,9 @@ module TingYun
97
98
  @request_attributes && @request_attributes.port
98
99
  end
99
100
 
101
+ def frozen_name=(name)
102
+ @frozen_name = name
103
+ end
100
104
 
101
105
  def start(state)
102
106
  return if !state.execution_traced?
@@ -117,7 +121,7 @@ module TingYun
117
121
 
118
122
  freeze_name_and_execute
119
123
 
120
- if @has_children
124
+ if @has_children or @is_mq
121
125
  name = Transaction.nested_transaction_name(outermost_frame.name)
122
126
  trace_options = TRACE_OPTIONS_SCOPED
123
127
  else
@@ -141,7 +145,7 @@ module TingYun
141
145
  trace_options,
142
146
  end_time.to_f)
143
147
 
144
- commit(state, end_time, name) unless ignore(best_name)
148
+ commit(state, end_time, name)
145
149
  end
146
150
 
147
151
 
@@ -130,6 +130,11 @@ module TingYun
130
130
  txn.name_last_frame(node_name || name)
131
131
  txn.set_default_transaction_name(name, category)
132
132
  end
133
+
134
+ def set_frozen_transaction_name!(name) #THREAD_LOCAL_ACCESS
135
+ txn = tl_current
136
+ txn.frozen_name = name
137
+ end
133
138
  end
134
139
  end
135
140
  end
@@ -6,6 +6,7 @@ module TingYun
6
6
  class TransactionMetrics
7
7
  DEFAULT_PROC = Proc.new { |hash, name| hash[name] = TingYun::Metrics::Stats.new }
8
8
 
9
+
9
10
  def initialize
10
11
  @unscoped = Hash.new(&DEFAULT_PROC)
11
12
  @scoped = Hash.new(&DEFAULT_PROC)
@@ -27,6 +27,7 @@ module TingYun
27
27
 
28
28
 
29
29
 
30
+
30
31
  def self.tl_get
31
32
  tl_state_for(Thread.current)
32
33
  end
@@ -160,12 +161,12 @@ module TingYun
160
161
  # end
161
162
  # public api
162
163
  def add_custom_params(key, value)
163
- current_transaction.attributes.add_custom_params(key, value)
164
+ current_transaction.attributes.add_custom_params(key, value) if current_transaction
164
165
  end
165
166
 
166
167
  # same to add_custom_params
167
168
  def merge_request_parameters(hash)
168
- current_transaction.attributes.merge_request_parameters(hash)
169
+ current_transaction.attributes.merge_request_parameters(hash) if current_transaction
169
170
  end
170
171
 
171
172
  def add_current_node_params(hash)
@@ -88,27 +88,25 @@ TingYun::Support::LibraryDetection.defer do
88
88
  end
89
89
 
90
90
  state.save_referring_transaction_info(tingyun_id_secret.split(';')) if cross_app_enabled?(tingyun_id_secret)
91
- TingYun::Agent::Transaction.start(state,:message, { :transaction_name => transaction_name})
91
+
92
92
  summary_metrics = TingYun::Agent::Datastore::MetricHelper.metrics_for_message('RabbitMQ', "#{@channel.connection.host}:#{@channel.connection.port}", 'Consume')
93
- TingYun::Agent::Transaction.wrap(state, "Message RabbitMQ/#{metric_name}" , :RabbitMq, {}, summary_metrics) do
94
- TingYun::Agent.record_metric("MessageRabbitMQ/#{metric_name}%2FByte",args[2].bytesize) if args[2]
93
+
94
+ TingYun::Agent::Transaction.wrap(state, "Message RabbitMQ/#{metric_name}" , :RabbitMq, {:mq=> true}, summary_metrics) do
95
+ TingYun::Agent::Transaction.set_frozen_transaction_name!(transaction_name)
96
+ TingYun::Agent.record_metric("Message RabbitMQ/#{metric_name}%2FByte",args[2].bytesize) if args[2]
95
97
  TingYun::Agent.record_metric("Message RabbitMQ/#{metric_name}%2FWait", TingYun::Helper.time_to_millis(Time.now)-state.externel_time.to_i) rescue 0
96
- if state.current_transaction
97
- state.add_custom_params("message.byte",args[2].bytesize)
98
- state.add_custom_params("message.wait",TingYun::Helper.time_to_millis(Time.now)-state.externel_time.to_i)
99
- state.add_custom_params("message.routingkey",queue_name)
100
- state.current_transaction.attributes.add_agent_attribute(:tx_id, state.client_transaction_id)
101
- headers.delete("TingyunID")
102
- state.merge_request_parameters(headers)
103
- end
98
+ state.add_custom_params("message.byte",args[2].bytesize)
99
+ state.add_custom_params("message.wait",TingYun::Helper.time_to_millis(Time.now)-state.externel_time.to_i)
100
+ state.add_custom_params("message.routingkey",queue_name)
101
+ state.current_transaction.attributes.add_agent_attribute(:tx_id, state.client_transaction_id)
102
+ headers.delete("TingyunID")
103
+ state.merge_request_parameters(headers)
104
104
  call_without_tingyun(*args)
105
+ state.current_transaction.attributes.add_agent_attribute(:entryTrace, build_payload(state)) if state.same_account? && TingYun::Agent.config[:'nbs.transaction_tracer.enabled']
105
106
  end
106
- state.current_transaction.attributes.add_agent_attribute(:entryTrace, build_payload(state)) if state.same_account? && TingYun::Agent.config[:'nbs.transaction_tracer.enabled']
107
107
  rescue => e
108
108
  TingYun::Agent.logger.error("Failed to Bunny call_with_tingyun : ", e)
109
109
  call_without_tingyun(*args)
110
- ensure
111
- TingYun::Agent::Transaction.stop(state, Time.now, summary_metrics)
112
110
  end
113
111
 
114
112
  end
@@ -41,7 +41,7 @@ TingYun::Support::LibraryDetection.defer do
41
41
  args[1] = (::Module.private_method_defined? :to_resource_url) ? to_resource_url(args[1]) : urify(args[1])
42
42
  proxy = no_proxy?(args[1]) ? nil : @proxy
43
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")
44
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{tingyun_request.uri.to_s.gsub(/\/\z/,'').gsub('/','%2F')}/#{tingyun_request.from}")
45
45
  raise e
46
46
  end
47
47
  end
@@ -25,6 +25,7 @@ TingYun::Support::LibraryDetection.defer do
25
25
  self.class.default_trace_args(msg)
26
26
  end
27
27
  perform_action_with_tingyun_trace(trace_args) do
28
+ TingYun::Agent.add_custom_params(:job_arguments, msg['args'])
28
29
  yield
29
30
  end
30
31
  end
@@ -11,27 +11,18 @@ module TingYun
11
11
  module_function
12
12
 
13
13
  def browser_timing_header #THREAD_LOCAL_ACCESS
14
- return '' unless rum_enable? # unsupport insert script
15
-
16
14
  state = TingYun::Agent::TransactionState.tl_get
17
15
  return '' unless insert_js?(state)
18
-
19
- bt_config = browser_timing_config(state)
20
-
16
+ bt_config = TingYun::Support::Serialize::JSONWrapper.dump(browser_timing_config(state))
21
17
  return '' if bt_config.empty?
22
-
23
- if TingYun::Agent.config[:'nbs.rum.mix_enabled']
24
- html_safe_if_needed("<script>(function(w){(w._ty_rum || (w._ty_rum = {})).agent = #{bt_config};})(window);</script>")
25
- else
26
- html_safe_if_needed("<script>#{browser_instrument("ty_rum.agent=#{bt_config}")}</script>")
27
- end
18
+ html_safe_if_needed("<script>#{browser_instrument("ty_rum.agent=#{bt_config}")}</script>")
28
19
  rescue => e
29
20
  ::TingYun::Agent.logger.debug "Failure during RUM browser_timing_header construction", e
30
21
  ''
31
22
  end
32
23
 
33
24
  def rum_enable?
34
- TingYun::Agent.config[:'nbs.rum.enabled']
25
+ TingYun::Agent.config[:'nbs.rum.enabled']
35
26
  end
36
27
 
37
28
  def insert_js?(state)
@@ -59,8 +50,8 @@ module TingYun
59
50
  :q => timings.queue_time_in_millis,
60
51
  :tid => state.trace_id
61
52
  }
62
- TingYun::Support::Serialize::JSONWrapper.dump(data)
63
- end
53
+ data
54
+ end
64
55
 
65
56
  def html_safe_if_needed(string)
66
57
  string = string.html_safe if string.respond_to?(:html_safe)
@@ -8,6 +8,7 @@ module TingYun
8
8
  unless defined?(REQUEST_START_HEADER)
9
9
  REQUEST_START_HEADER = 'HTTP_X_REQUEST_START'.freeze
10
10
  QUEUE_START_HEADER = 'HTTP_X_QUEUE_START'.freeze
11
+ X_QUEUE_START = 'X-QUEUE-START'.freeze
11
12
  MIDDLEWARE_START_HEADER = 'HTTP_X_MIDDLEWARE_START'.freeze
12
13
  ALL_QUEUE_METRIC = 'WebFrontend/QueueTime'.freeze
13
14
  # any timestamps before this are thrown out and the parser
@@ -17,6 +18,7 @@ module TingYun
17
18
  CANDIDATE_HEADERS = [
18
19
  REQUEST_START_HEADER,
19
20
  QUEUE_START_HEADER,
21
+ X_QUEUE_START,
20
22
  MIDDLEWARE_START_HEADER
21
23
  ].freeze
22
24
 
@@ -43,11 +43,10 @@ module TingYun
43
43
  end
44
44
 
45
45
  def metrics operate
46
- state = TingYun::Agent::TransactionState.tl_get
47
46
  metrics = if tingyun_host.nil?
48
- ["External/thrift:%2F%2F#{operate}/#{operate}"]
47
+ ["External/thrift:%2F%2F#{operate}/thrift"]
49
48
  else
50
- ["External/thrift:%2F%2F#{tingyun_host}:#{tingyun_port}%2F#{operate}/#{operate}"]
49
+ ["External/thrift:%2F%2F#{tingyun_host}:#{tingyun_port}%2F#{operate}/thrift"]
51
50
  end
52
51
  metrics << "External/NULL/ALL"
53
52
 
@@ -56,18 +55,16 @@ module TingYun
56
55
  else
57
56
  metrics << "External/NULL/AllBackground"
58
57
  end
59
-
60
-
61
- my_data = state.thrift_return_data
62
-
63
-
64
- if my_data && TingYun::Agent.config[:'nbs.transaction_tracer.thrift'] && TingYun::Agent.config[:'nbs.transaction_tracer.enabled']
65
- uri = "thrift:%2F%2F#{tingyun_host}:#{tingyun_port}%2F#{operate}/#{operate}"
66
- metrics << "cross_app;#{my_data["id"]};#{my_data["action"]};#{uri}"
67
- end
68
58
  return metrics
59
+ end
69
60
 
61
+ def metrics_for_cross_app(operate,my_data)
62
+ metrics = ["ExternalTransaction/NULL/#{my_data["id"]}",
63
+ "ExternalTransaction/thrift/#{my_data["id"]}",
64
+ "ExternalTransaction/thrift:%2F%2F#{tingyun_host}:#{tingyun_port}%2F#{operate}/#{my_data["id"]}%2F#{my_data["action"].to_s.gsub(/\/\z/,'')}"]
65
+ return metrics
70
66
  end
67
+
71
68
  end
72
69
  end
73
70
  end
@@ -28,11 +28,13 @@ TingYun::Support::LibraryDetection.defer do
28
28
  if data.include?("TingyunTxData")
29
29
  my_data = TingYun::Support::Serialize::JSONWrapper.load data.gsub("'",'"')
30
30
  TingYun::Agent::TransactionState.process_thrift_data(my_data["TingyunTxData"])
31
+
31
32
  end
32
33
  end
33
34
  end
34
35
  end
35
36
 
37
+
36
38
  alias :skip_without_tingyun :skip
37
39
  alias :skip :skip_with_tingyun
38
40
  end
@@ -123,10 +125,18 @@ TingYun::Support::LibraryDetection.defer do
123
125
  t1 = Time.now.to_f
124
126
  node_name, *other_metrics = metrics(operate)
125
127
  duration = TingYun::Helper.time_to_millis(t1 - t0)
126
-
128
+ my_data = state.thrift_return_data || {}
129
+ # net_block_duration = my_data["time"]? duration - my_data["time"]["duration"]- my_data["time"]["qu"] : duration
130
+ # net_block_duration = duration if net_block_duration < 0
127
131
  TingYun::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
128
- other_metrics.pop, other_metrics, duration
132
+ node_name, other_metrics, duration
129
133
  )
134
+
135
+ if my_data["time"]
136
+ metrics_cross_app = metrics_for_cross_app(operate, my_data)
137
+ _duration = my_data["time"]["duration"] + my_data["time"]["qu"] + 0.1
138
+ ::TingYun::Agent.instance.stats_engine.record_scoped_and_unscoped_metrics(state, metrics_cross_app.pop, metrics_cross_app, duration, _duration)
139
+ end
130
140
  if node
131
141
  node.name = node_name
132
142
  ::TingYun::Agent::Collector::TransactionSampler.add_node_info(:uri => "thrift:#{tingyun_host}:#{tingyun_port}/#{operate}")
@@ -8,7 +8,7 @@
8
8
  module TingYun
9
9
  module Metrics
10
10
  class MetricSpec
11
- attr_accessor :name, :scope, :calleeId, :calleeName, :full_name
11
+ attr_accessor :name, :scope, :full_name
12
12
 
13
13
  # the maximum length of a metric name or metric scope
14
14
  MAX_LENGTH = 255
@@ -85,8 +85,6 @@ module TingYun
85
85
 
86
86
  def to_hash
87
87
  hash = { 'name' => name }
88
- hash['calleeId'] = calleeId if calleeId
89
- hash['calleeName'] = calleeName if calleeName
90
88
  unless scope.empty?
91
89
  hash['parent'] = scope
92
90
  end
@@ -119,11 +119,11 @@ module TingYun
119
119
  def record_data_point(value, exclusive_time = value)
120
120
  @call_count += 1
121
121
  @total_call_time += value
122
- @min_call_time = value if value < @min_call_time || @call_count == 1
123
- @max_call_time = value if value > @max_call_time
122
+ @min_call_time = exclusive_time if exclusive_time < @min_call_time || @call_count == 1
123
+ @max_call_time = exclusive_time if exclusive_time > @max_call_time
124
124
  @total_exclusive_time += exclusive_time
125
125
 
126
- @sum_of_squares += (value * value)
126
+ @sum_of_squares += (exclusive_time * exclusive_time)
127
127
  self
128
128
  end
129
129
 
@@ -1,11 +1,13 @@
1
1
  # encoding: utf-8
2
2
  require 'ting_yun/middleware/agent_middleware'
3
3
  require 'ting_yun/instrumentation/support/javascript_instrumentor'
4
-
4
+ require 'ting_yun/support/coerce'
5
5
 
6
6
  module TingYun
7
7
  class BrowserMonitoring < AgentMiddleware
8
8
 
9
+ include TingYun::Support::Coerce
10
+
9
11
  CONTENT_TYPE = 'Content-Type'.freeze
10
12
  TEXT_HTML = 'text/html'.freeze
11
13
  CONTENT_DISPOSITION = 'Content-Disposition'.freeze
@@ -26,15 +28,28 @@ module TingYun
26
28
  def traced_call(env)
27
29
  result = @app.call(env) # [status, headers, response]
28
30
 
29
- js_to_inject = TingYun::Instrumentation::Support::JavascriptInstrument.browser_timing_header
30
-
31
- if (js_to_inject != '') && should_instrument?(env, result[0], result[1])
32
- response_string = auto_instrument_source(result[2], js_to_inject)
33
-
34
- env[ALREADY_INSTRUMENTED_KEY] = true
35
- if response_string
36
- response = Rack::Response.new(response_string, result[0], result[1])
37
- response.finish
31
+ if should_instrument?(env, result[0], result[1])
32
+ if rum_enable? # unsupport insert script
33
+ if TingYun::Agent.config[:'nbs.rum.mix_enabled']
34
+ result[1]["Set-Cookie"] = "TINGYUN_DATA=#{manufacture_cookie}"
35
+ env[ALREADY_INSTRUMENTED_KEY] = true
36
+ result
37
+ else
38
+ js_to_inject = TingYun::Instrumentation::Support::JavascriptInstrument.browser_timing_header
39
+ if (js_to_inject != '')
40
+ response_string = auto_instrument_source(result[2], js_to_inject)
41
+
42
+ env[ALREADY_INSTRUMENTED_KEY] = true
43
+ if response_string
44
+ response = Rack::Response.new(response_string, result[0], result[1])
45
+ response.finish
46
+ else
47
+ result
48
+ end
49
+ else
50
+ result
51
+ end
52
+ end
38
53
  else
39
54
  result
40
55
  end
@@ -65,6 +80,29 @@ module TingYun
65
80
  headers[CONTENT_DISPOSITION] && headers[CONTENT_DISPOSITION].include?(ATTACHMENT)
66
81
  end
67
82
 
83
+ def rum_enable?
84
+ TingYun::Agent.config[:'nbs.rum.enabled']
85
+ end
86
+
87
+ def manufacture_cookie
88
+ state = TingYun::Agent::TransactionState.tl_get
89
+ timings = state.timings
90
+ "%7B%22id%22%3A%22#{TingYun::Support::Coerce.url_encode(TingYun::Agent.config[:tingyunIdSecret].to_s)}%22%2C%22n%22%3A%22#{TingYun::Support::Coerce.url_encode(state.transaction_name.to_s)}%22%2C%22tid%22%3A%22#{state.trace_id}%22%2C%22q%22%3A#{timings.queue_time_in_millis}%2C%22a%22%3A#{timings.app_time_in_millis}%7D"
91
+ end
92
+ def browser_timing_config(state)
93
+ timings = state.timings
94
+
95
+ data = {
96
+ :id => TingYun::Agent.config[:tingyunIdSecret],
97
+ :n => state.transaction_name ,
98
+ :a => timings.app_time_in_millis,
99
+ :q => timings.queue_time_in_millis,
100
+ :tid => state.trace_id
101
+ }
102
+ data
103
+ end
104
+
105
+
68
106
  def auto_instrument_source(response, js_to_inject)
69
107
  source = gather_source(response)
70
108
  close_old_response(response)
@@ -45,6 +45,11 @@ module TingYun
45
45
  ""
46
46
  end
47
47
 
48
+ def url_encode(s)
49
+ s.to_s.b.gsub(/[^a-zA-Z0-9_\-.]/n) { |m|
50
+ sprintf("%%%02X", m.unpack("C")[0])
51
+ }
52
+ end
48
53
  # Convert a hash into a format acceptable to be included with Transaction
49
54
  # event data.
50
55
  #
@@ -68,22 +68,11 @@ module TingYun
68
68
  adpex_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
69
69
  elsif metric_spec.name.start_with?('Errors') && metric_spec.scope.empty?
70
70
  errors_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
71
- elsif metric_spec.name.start_with?('cross_app')
72
- external = metric_spec.name.split(';')
73
- if metric_spec.scope.empty?
74
- metric_spec.name = "ExternalTransaction/NULL/#{external[1]}"
75
- general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
76
- else
77
- metric_spec.name = "External/#{external[3]}"
78
- metric_spec.calleeId = external[1]
79
- metric_spec.calleeName = external[2]
80
- components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
81
- end
82
71
  else
83
72
  if metric_spec.scope.empty?
84
- general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
73
+ general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id) unless metric_spec.name.start_with?("View","Middleware","Nested","Rack")
85
74
  else
86
- components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id) unless metric_spec.name.start_with?('External/NULL')
75
+ components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id) unless metric_spec.name.start_with?("Nested")
87
76
  end
88
77
  end
89
78
 
@@ -6,7 +6,10 @@ module TingYun
6
6
 
7
7
  MAJOR = 1
8
8
 
9
- MINOR = 3
9
+ MINOR = 4
10
+
11
+
12
+
10
13
 
11
14
  TINY = 1
12
15
 
@@ -14,6 +17,7 @@ module TingYun
14
17
 
15
18
 
16
19
 
20
+
17
21
  STRING = [MAJOR, MINOR, TINY].compact.join('.')
18
22
  end
19
23
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tingyun_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - tingyun
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-03 00:00:00.000000000 Z
11
+ date: 2017-07-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake