tingyun_rpm 1.2.0 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/lib/ting_yun/agent/agent.rb +8 -0
  4. data/lib/ting_yun/agent/collector/stats_engine/base_quantile_hash.rb +20 -0
  5. data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +10 -0
  6. data/lib/ting_yun/agent/collector/stats_engine.rb +9 -0
  7. data/lib/ting_yun/agent/collector/transaction_sampler/class_method.rb +2 -2
  8. data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +16 -10
  9. data/lib/ting_yun/agent/datastore/metric_helper.rb +31 -7
  10. data/lib/ting_yun/agent/datastore.rb +6 -11
  11. data/lib/ting_yun/agent/dispatcher.rb +5 -1
  12. data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +5 -1
  13. data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +5 -0
  14. data/lib/ting_yun/agent/method_tracer_helpers.rb +8 -4
  15. data/lib/ting_yun/agent/transaction/attributes.rb +6 -2
  16. data/lib/ting_yun/agent/transaction/class_method.rb +14 -5
  17. data/lib/ting_yun/agent/transaction/instance_method.rb +20 -4
  18. data/lib/ting_yun/agent/transaction/trace.rb +2 -1
  19. data/lib/ting_yun/agent/transaction/trace_node.rb +10 -2
  20. data/lib/ting_yun/agent/transaction/traced_method_stack.rb +2 -2
  21. data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +2 -1
  22. data/lib/ting_yun/agent/transaction/transaction_state.rb +22 -1
  23. data/lib/ting_yun/agent/transaction/transaction_timings.rb +1 -2
  24. data/lib/ting_yun/agent/transaction.rb +13 -7
  25. data/lib/ting_yun/configuration/default_source.rb +44 -7
  26. data/lib/ting_yun/configuration/yaml_source.rb +1 -0
  27. data/lib/ting_yun/frameworks/instrumentation.rb +6 -1
  28. data/lib/ting_yun/frameworks/rails5.rb +10 -0
  29. data/lib/ting_yun/frameworks.rb +1 -1
  30. data/lib/ting_yun/http/http_client_request.rb +39 -0
  31. data/lib/ting_yun/http/net_http_request.rb +4 -0
  32. data/lib/ting_yun/instrumentation/active_record.rb +11 -5
  33. data/lib/ting_yun/instrumentation/bunny.rb +142 -0
  34. data/lib/ting_yun/instrumentation/data_mapper.rb +167 -0
  35. data/lib/ting_yun/instrumentation/grape.rb +39 -0
  36. data/lib/ting_yun/instrumentation/http_client.rb +70 -0
  37. data/lib/ting_yun/instrumentation/kafka.rb +218 -0
  38. data/lib/ting_yun/instrumentation/memcached.rb +135 -0
  39. data/lib/ting_yun/instrumentation/middleware_proxy.rb +1 -4
  40. data/lib/ting_yun/instrumentation/middleware_tracing.rb +5 -1
  41. data/lib/ting_yun/instrumentation/mongo.rb +18 -6
  42. data/lib/ting_yun/instrumentation/mongo2.rb +5 -1
  43. data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +5 -5
  44. data/lib/ting_yun/instrumentation/moped.rb +4 -3
  45. data/lib/ting_yun/instrumentation/net.rb +3 -3
  46. data/lib/ting_yun/instrumentation/rails3/action_controller.rb +8 -4
  47. data/lib/ting_yun/instrumentation/rails3/action_view.rb +8 -4
  48. data/lib/ting_yun/instrumentation/rails4/action_controller.rb +29 -0
  49. data/lib/ting_yun/instrumentation/rails4/action_view.rb +29 -0
  50. data/lib/ting_yun/instrumentation/rails4/active_record.rb +30 -0
  51. data/lib/ting_yun/instrumentation/rails5/action_cable.rb +31 -0
  52. data/lib/ting_yun/instrumentation/rails5/action_controller.rb +29 -0
  53. data/lib/ting_yun/instrumentation/rails5/action_view.rb +28 -0
  54. data/lib/ting_yun/instrumentation/rails5/active_record.rb +30 -0
  55. data/lib/ting_yun/instrumentation/rake.rb +3 -2
  56. data/lib/ting_yun/instrumentation/redis.rb +6 -5
  57. data/lib/ting_yun/instrumentation/sidekiq.rb +61 -0
  58. data/lib/ting_yun/instrumentation/sinatra/action.rb +95 -0
  59. data/lib/ting_yun/instrumentation/sinatra/view.rb +67 -0
  60. data/lib/ting_yun/instrumentation/support/action_cable_subscriber.rb +83 -0
  61. data/lib/ting_yun/instrumentation/{rails4 → support}/action_controller_subscriber.rb +5 -29
  62. data/lib/ting_yun/instrumentation/{rails4 → support}/action_view_subscriber.rb +2 -24
  63. data/lib/ting_yun/instrumentation/support/active_record_helper.rb +23 -6
  64. data/lib/ting_yun/instrumentation/{rails4 → support}/active_record_subscriber.rb +13 -37
  65. data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +204 -1
  66. data/lib/ting_yun/instrumentation/support/database.rb +2 -1
  67. data/lib/ting_yun/instrumentation/support/external_error.rb +2 -2
  68. data/lib/ting_yun/instrumentation/support/external_helper.rb +30 -0
  69. data/lib/ting_yun/instrumentation/support/method_instrumentation.rb +228 -0
  70. data/lib/ting_yun/instrumentation/support/metric_translator.rb +4 -1
  71. data/lib/ting_yun/instrumentation/support/sinatra_helper.rb +20 -0
  72. data/lib/ting_yun/instrumentation/support/transaction_namer.rb +3 -1
  73. data/lib/ting_yun/instrumentation/thrift.rb +5 -6
  74. data/lib/ting_yun/logger/agent_logger.rb +1 -0
  75. data/lib/ting_yun/logger/create_logger_helper.rb +16 -2
  76. data/lib/ting_yun/metrics/metric_data.rb +8 -2
  77. data/lib/ting_yun/metrics/metric_spec.rb +2 -1
  78. data/lib/ting_yun/support/helper.rb +4 -0
  79. data/lib/ting_yun/support/quantile_p2.rb +204 -0
  80. data/lib/ting_yun/ting_yun_service/upload_service.rb +38 -12
  81. data/lib/ting_yun/ting_yun_service.rb +4 -7
  82. data/lib/ting_yun/version.rb +3 -1
  83. data/lib/tingyun_rpm.rb +0 -4
  84. data/tingyun_rpm.gemspec +3 -3
  85. metadata +35 -13
  86. data/CODE_OF_CONDUCT.md +0 -13
  87. data/lib/ting_yun/agent/method_tracer.rb +0 -256
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1e1698a0cac85df291567637e7d8905c7dd5d30b
4
- data.tar.gz: 504578a77dac8308f1f43d6cec9933da44778a57
3
+ metadata.gz: 29a46f9e5110b810ddbb29e1b593e25bf725c831
4
+ data.tar.gz: f6b0999a21a723f30279702f07c286cfa0ad17ca
5
5
  SHA512:
6
- metadata.gz: e067d0a87a03f9428e811cea75288256ad09cc992ead66d89337ca6966d7428acaa6c2a781a67bf91b77ef62a20057c1d65445dbe6640bc686f43b0ceb52c0ff
7
- data.tar.gz: 9246032c6e6841630838a20713a86355a4f73b5085ff3ce1f066988646409dc4b688f2fde31b3fa4d2e4f0e72ea8f6cbb54bf8f070d42ab8f1feae63c33cece7
6
+ metadata.gz: f20f812206d86863956dc05afb7da78c2e559dc95ef9d9971e3d5d0d3210f1739ddb011e0234b634038c7c0204520fde8914f55bf2772a55070702a5e8ab9a83
7
+ data.tar.gz: b58306111cfcc24c1f88d3467da3b9a77e5e410b8c8b93e2ebdafafe5c72922828e03c9abb6a89b00ff75d8a8dfd71163b6b582363ce7139a78cb034a6aef36c
data/.gitignore CHANGED
@@ -12,3 +12,4 @@ log/
12
12
  .idea/
13
13
  todo
14
14
  .DS_Store
15
+ /git_stats
@@ -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, 'net%2Fhttp')
38
+ capture_exception(response, request)
39
39
  rescue => e
40
- klass = "External/#{request.uri.to_s.gsub('/','%2F')}/net%2Fhttp"
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
- TingYun::Support::Serialize::JSONWrapper.load(response[TY_DATA_HEADER].gsub("'",'"')))
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')}/net%2Fhttp"
127
- metrics << "External/#{request.uri.to_s.gsub('/','%2F')}/net%2Fhttp"
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] or
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[TY_DATA_HEADER].gsub("'",'"')
161
- uri = "#{request.uri.to_s.gsub('/','%2F')}/net%2Fhttp"
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
- "#{product}/#{collection}/#{operation}"
33
+ "#{product}%2F#{collection}/#{operation}"
24
34
  else
25
- "Database #{product}/#{collection}/#{operation}"
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
- def self.metrics_for(product, operation, collection = nil, generic_product = nil)
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
- metrics.unshift metric_name(product, collection, operation) if collection
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/method_tracer'
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
- result = yield
17
+ yield
23
18
  ensure
24
19
  elapsed_time = (Time.now - t0).to_f
25
20
  if callback
26
- callback.call(result, scoped_metric, elapsed_time)
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
- @service.send(endpoint, items)
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
- Transaction.stop(state)
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?(RAKE_TRANSACTION_PREFIX)
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
- @metrics.record_unscoped(@frozen_name, TingYun::Helper.time_to_millis(end_time.to_f - start_time.to_f))
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