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
@@ -9,7 +9,7 @@ require 'ting_yun/instrumentation/support/parameter_filtering'
9
9
 
10
10
  module TingYun
11
11
  module Instrumentation
12
- module Rails4
12
+ module Rails
13
13
  class ActionControllerSubscriber < TingYun::Instrumentation::Support::EventedSubscriber
14
14
  def start(name, id, payload) #THREAD_LOCAL_ACCES
15
15
  state = TingYun::Agent::TransactionState.tl_get
@@ -17,8 +17,8 @@ module TingYun
17
17
  event = ControllerEvent.new(name, Time.now, nil, id, payload, request)
18
18
  push_event(event)
19
19
  # if state.execution_traced?
20
- start_transaction(state, event)
21
- # end
20
+ start_transaction(state, event)
21
+ # end
22
22
  rescue => e
23
23
  log_notification_error(e, name, 'start')
24
24
  end
@@ -80,7 +80,7 @@ module TingYun
80
80
  if TingYun::Agent.config[:'nbs.auto_action_naming']
81
81
  @metric_name ||= "WebAction/Rails/#{metric_path}%2F#{metric_action}"
82
82
  else
83
- "WebAction/#{uri}"
83
+ "WebAction/URI/#{uri[1..-1].gsub(/\//,'%2F')}"
84
84
  end
85
85
  end
86
86
  end
@@ -90,7 +90,7 @@ module TingYun
90
90
  end
91
91
 
92
92
  def params
93
- payload[:params]
93
+ payload[:params]
94
94
  end
95
95
 
96
96
  def metric_path
@@ -122,27 +122,3 @@ module TingYun
122
122
  end
123
123
  end
124
124
  end
125
-
126
-
127
- TingYun::Support::LibraryDetection.defer do
128
- @name = :rails4_controller
129
-
130
- depends_on do
131
- defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 4
132
- end
133
-
134
- depends_on do
135
- defined?(ActionController) && defined?(ActionController::Base)
136
- end
137
-
138
- executes do
139
- ::TingYun::Agent.logger.info 'Installing Rails 4 Controller instrumentation'
140
- end
141
-
142
- executes do
143
- ::TingYun::Instrumentation::Rails4::ActionControllerSubscriber \
144
- .subscribe(/^process_action.action_controller$/)
145
- end
146
- end
147
-
148
-
@@ -7,7 +7,7 @@ require 'ting_yun/agent'
7
7
 
8
8
  module TingYun
9
9
  module Instrumentation
10
- module Rails4
10
+ module Rails
11
11
  class ActionViewSubscriber < TingYun::Instrumentation::Support::EventedSubscriber
12
12
 
13
13
  def start(name, id, payload) #THREAD_LOCAL_ACCESS
@@ -93,26 +93,4 @@ module TingYun
93
93
  end
94
94
  end
95
95
  end
96
- end
97
-
98
- TingYun::Support::LibraryDetection.defer do
99
- @name = :rails4_view
100
-
101
- depends_on do
102
- defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 4
103
- end
104
-
105
- depends_on do
106
- !TingYun::Agent.config[:disable_view_instrumentation] &&
107
- !TingYun::Instrumentation::Rails4::ActionViewSubscriber.subscribed?
108
- end
109
-
110
- executes do
111
- TingYun::Agent.logger.info 'Installing Rails 4 view instrumentation'
112
- end
113
-
114
- executes do
115
- TingYun::Instrumentation::Rails4::ActionViewSubscriber.subscribe(/render_.+\.action_view$/)
116
- end
117
- end
118
- #
96
+ end
@@ -12,6 +12,7 @@ module TingYun
12
12
 
13
13
 
14
14
  ACTIVE_RECORD = "ActiveRecord".freeze unless defined?(ACTIVE_RECORD)
15
+ DATA_MAPPER = "DataMapper".freeze
15
16
 
16
17
  # Used by both the AR 3.x and 4.x instrumentation
17
18
  def instrument_additional_methods
@@ -68,15 +69,29 @@ module TingYun
68
69
  end
69
70
  end
70
71
 
71
- def metrics_for(name, sql, adapter_name)
72
- product = map_product(adapter_name)
72
+ def metrics_for(name, sql, config)
73
+ config ||={}
74
+ product = map_product(config[:adapter])
73
75
  splits = split_name(name)
74
76
  model = model_from_splits(splits) || product
75
77
  operation = operation_from_splits(splits, sql)
76
78
 
77
- TingYun::Agent::Datastore::MetricHelper.metrics_for(product, operation, model, ACTIVE_RECORD)
79
+ TingYun::Agent::Datastore::MetricHelper.metrics_for(product, operation, config[:host], config[:port], config[:database], model, ACTIVE_RECORD)
78
80
  end
79
81
 
82
+ def metrics_for_data_mapper(name, sql, config, model=nil)
83
+ if config
84
+ product = map_product(config.query['adapter'])
85
+ operation = name || TingYun::Instrumentation::Support::Database.parse_operation_from_query(sql)
86
+ model ||= product
87
+ db = config.query['database'] || config.path.split('/').last
88
+ host = config.host
89
+ port = config.port
90
+ host = nil if config.host && config.host.empty?
91
+ port = nil if config.host && config.host.empty?
92
+ TingYun::Agent::Datastore::MetricHelper.metrics_for(product, operation, host, port, db, model, DATA_MAPPER)
93
+ end
94
+ end
80
95
 
81
96
  SPACE = ' '.freeze unless defined?(SPACE)
82
97
  EMPTY = [].freeze unless defined?(EMPTY)
@@ -132,7 +147,9 @@ module TingYun
132
147
  "mysql" => "MySQL",
133
148
  "mysql2" => "MySQL",
134
149
 
135
- "postgresql" => "Postgres",
150
+ "postgresql" => "PostgreSQL",
151
+
152
+ "postgres" => 'PostgreSQL',
136
153
 
137
154
  "sqlite3" => "SQLite",
138
155
 
@@ -140,7 +157,7 @@ module TingYun
140
157
  "jdbcmysql" => "MySQL",
141
158
 
142
159
  # https://rubygems.org/gems/activerecord-jdbcpostgresql-adapter
143
- "jdbcpostgresql" => "Postgres",
160
+ "jdbcpostgresql" => "PostgreSQL",
144
161
 
145
162
  # https://rubygems.org/gems/activerecord-jdbcsqlite3-adapter
146
163
  "jdbcsqlite3" => "SQLite",
@@ -157,7 +174,7 @@ module TingYun
157
174
  "mssql" => "MSSQL",
158
175
 
159
176
  # https://rubygems.org/gems/activerecord-sqlserver-adapter
160
- "sqlserver" => "MSSQL",
177
+ "sqlserver" => "SQLServer",
161
178
 
162
179
  # https://rubygems.org/gems/activerecord-odbc-adapter
163
180
  "odbc" => "ODBC",
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+
2
3
  require 'ting_yun/instrumentation/support/evented_subscriber'
3
4
  require 'ting_yun/agent/transaction/transaction_state'
4
5
  require 'ting_yun/instrumentation/support/active_record_helper'
@@ -9,7 +10,7 @@ require 'ting_yun/agent/database'
9
10
 
10
11
  module TingYun
11
12
  module Instrumentation
12
- module Rails4
13
+ module Rails
13
14
  class ActiveRecordSubscriber < TingYun::Instrumentation::Support::EventedSubscriber
14
15
  CACHED_QUERY_NAME = 'CACHE'.freeze unless defined? CACHED_QUERY_NAME
15
16
 
@@ -37,37 +38,37 @@ module TingYun
37
38
  state = TingYun::Agent::TransactionState.tl_get
38
39
  event = pop_event(id)
39
40
  config = active_record_config_for_event(event)
40
- base_metric = record_metrics(event, config)
41
- notice_sql(state, event, config, base_metric)
41
+ base, metric = record_metrics(event, config)
42
+ notice_sql(state, event, config, base, metric)
42
43
  rescue Exception => e
43
44
  log_notification_error(e, name, 'finish')
44
45
  end
45
46
 
46
47
 
47
- def notice_sql(state, event, config, metric)
48
+ def notice_sql(state, event, config, base, metric)
48
49
  stack = state.traced_method_stack
49
50
  state.timings.sql_duration = state.timings.sql_duration + event.duration
50
51
  # enter transaction trace node
51
52
  frame = stack.push_frame(state, :active_record, event.time)
52
53
 
53
- sql_sampler.notice_sql(event.payload[:sql], metric, config,
54
- TingYun::Helper.milliseconds_to_seconds(event.duration),
55
- state, @explainer, event.payload[:binds], event.payload[:name])
54
+ sql_sampler.notice_sql(event.payload[:sql], base, config,
55
+ TingYun::Helper.milliseconds_to_seconds(event.duration),
56
+ state, @explainer, event.payload[:binds], event.payload[:name])
56
57
 
57
58
  transaction_sampler.notice_sql(event.payload[:sql], config, event.duration,
58
- state, @explainer, event.payload[:binds], event.payload[:name])
59
+ state, @explainer, event.payload[:binds], event.payload[:name])
59
60
  # exit transaction trace node
60
- stack.pop_frame(state, frame, metric, event.end)
61
+ stack.pop_frame(state, frame, base, event.end, true, metric)
61
62
  end
62
63
 
63
64
  def record_metrics(event, config)
64
- base, *other_metrics = TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for(event.payload[:name],
65
+ metric, base, *other_metrics = TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for(event.payload[:name],
65
66
  TingYun::Helper.correctly_encoded(event.payload[:sql]),
66
- config && config[:adapter])
67
+ config)
67
68
 
68
69
  TingYun::Agent.agent.stats_engine.tl_record_scoped_and_unscoped_metrics(base, other_metrics, event.duration)
69
70
 
70
- base
71
+ return base, metric
71
72
  end
72
73
 
73
74
 
@@ -98,29 +99,4 @@ module TingYun
98
99
  end
99
100
  end
100
101
  end
101
- end
102
-
103
- TingYun::Support::LibraryDetection.defer do
104
- named :active_record_4
105
-
106
-
107
- depends_on do
108
- defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) &&
109
- defined?(::ActiveRecord::VERSION) &&
110
- ::ActiveRecord::VERSION::MAJOR.to_i >= 4
111
- end
112
-
113
- depends_on do
114
- !TingYun::Instrumentation::Rails4::ActiveRecordSubscriber.subscribed?
115
- end
116
-
117
- executes do
118
- ::TingYun::Agent.logger.info 'Installing ActiveRecord 4 instrumentation'
119
- end
120
-
121
- executes do
122
- ActiveSupport::Notifications.subscribe('sql.active_record',
123
- TingYun::Instrumentation::Rails4::ActiveRecordSubscriber.new)
124
- ::TingYun::Instrumentation::Support::ActiveRecordHelper.instrument_additional_methods
125
- end
126
102
  end
@@ -4,19 +4,221 @@ require 'ting_yun/agent/transaction/transaction_state'
4
4
  require 'ting_yun/instrumentation/support/transaction_namer'
5
5
  require 'ting_yun/agent/transaction'
6
6
  require 'ting_yun/agent'
7
-
7
+ require 'ting_yun/support/helper'
8
8
 
9
9
  module TingYun
10
10
  module Instrumentation
11
11
  module Support
12
+
13
+ # This module can also be used to capture performance information for
14
+ # background tasks and other non-web transactions, including
15
+ # detailed transaction traces and traced errors.
12
16
  module ControllerInstrumentation
13
17
 
18
+ extend self
19
+
20
+ def self.included klass
21
+ klass.extend ClassMethods
22
+ end
23
+
24
+ def self.extended klass
25
+ klass.extend ClassMethods
26
+ end
27
+
28
+
29
+ module ClassMethods
30
+ # Add transaction tracing to the given method. This will treat
31
+ # the given method as a main entrypoint for instrumentation, just
32
+ # like controller actions are treated by default. Useful especially
33
+ # for background tasks.
34
+ # Example for background job:
35
+ # class Job
36
+ # include TingYun::Instrumentation::Support::ControllerInstrumentation
37
+ # def run(task)
38
+ # ...
39
+ # end
40
+ # # Instrument run so tasks show up under task.name. Note single
41
+ # # quoting to defer eval to runtime.
42
+ # add_transaction_tracer :run, :name => '#{args[0].name}'
43
+ # end
44
+ #
45
+ # Here's an example of a controller that uses a dispatcher
46
+ # action to invoke operations which you want treated as top
47
+ # level actions, so they aren't all lumped into the invoker
48
+ # action.
49
+ #
50
+ # MyController < ActionController::Base
51
+ # include TingYun::Instrumentation::Support::ControllerInstrumentation
52
+ # # dispatch the given op to the method given by the service parameter.
53
+ # def invoke_operation
54
+ # op = params['operation']
55
+ # send op
56
+ # end
57
+ # # Ignore the invoker to avoid double counting
58
+ # tingyun_ignore :only => 'invoke_operation'
59
+ # # Instrument the operations:
60
+ # add_transaction_tracer :print
61
+ # add_transaction_tracer :show
62
+ # add_transaction_tracer :forward
63
+ # end
64
+ #
65
+ # Here's an example of how to pass contextual information into the transaction
66
+ # so it will appear in transaction traces:
67
+ #
68
+ # class Job
69
+ # include TingYun::Instrumentation::Support::ControllerInstrumentation
70
+ # def process(account)
71
+ # ...
72
+ # end
73
+ # # Include the account name in the transaction details. Note the single
74
+ # # quotes to defer eval until call time.
75
+ # add_transaction_tracer :process, :params => '{ :account_name => args[0].name }'
76
+ # end
77
+ #``
78
+ #
79
+ # @api public
80
+ #
81
+ def add_transaction_tracer(method, options={})
82
+ options[:name] ||= method.to_s
83
+ argument_list = generate_argument_list(options)
84
+ traced_method, punctuation = parse_punctuation(method)
85
+ with_method_name, without_method_name = build_method_names(traced_method, punctuation)
86
+
87
+ if already_added_transaction_tracer?(self, with_method_name)
88
+ ::TingYun::Agent.logger.warn("Transaction tracer already in place for class = #{self.name}, method = #{method.to_s}, skipping")
89
+ return
90
+ end
91
+
92
+ class_eval <<-EOC
93
+ def #{with_method_name}(*args,&block)
94
+ perform_action_with_tingyun_trace(#{argument_list.join(',')}) do
95
+ #{without_method_name}(*args, &block)
96
+ end
97
+ end
98
+ EOC
99
+
100
+ visibility = TingYun::Helper.instance_method_visibility self, method
101
+
102
+ alias_method without_method_name, method.to_s
103
+ alias_method method.to_s, with_method_name
104
+ send visibility, method
105
+ send visibility, with_method_name
106
+ ::TingYun::Agent.logger.debug("Traced transaction: class = #{self.name}, method = #{method.to_s}, options = #{options.inspect}")
107
+ end
108
+
109
+ def already_added_transaction_tracer?(target, with_method_name)
110
+ if TingYun::Helper.instance_methods_include?(target, with_method_name)
111
+ true
112
+ else
113
+ false
114
+ end
115
+ end
116
+
117
+ def parse_punctuation(method)
118
+ [method.to_s.sub(/([?!=])$/, ''), $1]
119
+ end
120
+
121
+ def build_method_names(traced_method, punctuation)
122
+ [ "#{traced_method.to_s}_with_tingyun_transaction_trace#{punctuation}",
123
+ "#{traced_method.to_s}_without_tingyun_transaction_trace#{punctuation}" ]
124
+ end
125
+
126
+ def generate_argument_list(options)
127
+ options.map do |key, value|
128
+ value = if value.is_a?(Symbol)
129
+ value.inspect
130
+ elsif key == :params
131
+ value.to_s
132
+ else
133
+ %Q["#{value.to_s}"]
134
+ end
135
+
136
+ %Q[:#{key} => #{value}]
137
+ end
138
+ end
139
+
140
+
141
+
142
+ end
143
+
144
+
145
+
146
+ # Yield to the given block with TingYun tracing. Used by
147
+ # default instrumentation on controller actions in Rails and Merb.
148
+ # But it can also be used in custom instrumentation of controller
149
+ # methods and background tasks.
150
+
151
+ # This is the method invoked by instrumentation added by the
152
+ # <tt>ClassMethods#add_transaction_tracer</tt>.
153
+
154
+ # Below is a controller with an +invoke_operation+ action which
155
+ # dispatches to more specific operation methods based on a
156
+ # parameter (very dangerous, btw!). With this instrumentation,
157
+ # the +invoke_operation+ action is ignored but the operation
158
+ # methods show up in TingYun as if they were first class controller
159
+ # actions
160
+ #
161
+ # MyController < ActionController::Base
162
+ # include TingYun::Instrumentation::Support::ControllerInstrumentation
163
+ # # dispatch the given op to the method given by the service parameter.
164
+ # def invoke_operation
165
+ # op = params['operation']
166
+ # perform_action_with_tingyun_trace(:name => op) do
167
+ # send op, params['message']
168
+ # end
169
+ # end
170
+ # # Ignore the invoker to avoid double counting
171
+ # tingyun_ignore :only => 'invoke_operation'
172
+ # end
173
+ #
174
+ # When invoking this method explicitly as in the example above, pass in a
175
+ # block to measure with some combination of options:
176
+ #
177
+ # * <tt>:category => :controller</tt> indicates that this is a
178
+ # controller action and will appear with all the other actions. This
179
+ # is the default.
180
+ # * <tt>:category => :task</tt> indicates that this is a
181
+ # background task and will show up in Ting Yun with other background
182
+ # tasks instead of in the controllers list
183
+ # * <tt>:category => :middleware</tt> if you are instrumenting a rack
184
+ # middleware call. The <tt>:name</tt> is optional, useful if you
185
+ # have more than one potential transaction in the #call.
186
+ # * <tt>:category => :uri</tt> indicates that this is a
187
+ # web transaction whose name is a normalized URI, where 'normalized'
188
+ # means the URI does not have any elements with data in them such
189
+ # as in many REST URIs.
190
+ # * <tt>:name => action_name</tt> is used to specify the action
191
+ # name used as part of the metric name
192
+ # * <tt>:params => {...}</tt> to provide information about the context
193
+ # of the call, used in transaction trace display, for example:
194
+ # <tt>:params => { :account => @account.name, :file => file.name }</tt>
195
+ # These are treated similarly to request parameters in web transactions.
196
+ #
197
+ # Seldomly used options:
198
+ #
199
+ # * <tt>:class_name => aClass.name</tt> is used to override the name
200
+ # of the class when used inside the metric name. Default is the
201
+ # current class.
202
+ # * <tt>:path => metric_path</tt> is *deprecated* in the public API. It
203
+ # allows you to set the entire metric after the category part. Overrides
204
+ # all the other options.
205
+ # * <tt>:request => Rack::Request#new(env)</tt> is used to pass in a
206
+ # request object that may respond to path and referer.
207
+ #
208
+ # @api public
209
+ #
14
210
  NR_DEFAULT_OPTIONS = {}.freeze unless defined?(NR_DEFAULT_OPTIONS )
15
211
 
16
212
  def perform_action_with_tingyun_trace (*args, &block)
17
213
 
18
214
  state = TingYun::Agent::TransactionState.tl_get
19
215
 
216
+ skip_tracing = !state.execution_traced?
217
+
218
+ if skip_tracing
219
+ state.current_transaction.ignore! if state.current_transaction
220
+ TingYun::Agent.disable_all_tracing { return yield }
221
+ end
20
222
  trace_options = args.last.is_a?(Hash) ? args.last : NR_DEFAULT_OPTIONS
21
223
  category = trace_options[:category] || :controller
22
224
  txn_options = create_transaction_options(trace_options, category)
@@ -40,6 +242,7 @@ module TingYun
40
242
  txn_options = {}
41
243
 
42
244
  txn_options[:request] ||= request if respond_to?(:request)
245
+ txn_options[:request] ||= trace_options[:request] if trace_options[:request]
43
246
  txn_options[:filtered_params] = trace_options[:params]
44
247
  txn_options[:transaction_name] = TingYun::Instrumentation::Support::TransactionNamer.name_for(nil, self, category, trace_options)
45
248
  txn_options[:apdex_start_time] = Time.now
@@ -14,7 +14,8 @@ module TingYun
14
14
  'DELETE',
15
15
  'INSERT',
16
16
  'SHOW',
17
- 'CALL'
17
+ 'CALL',
18
+ 'PRAGMA'
18
19
  ]
19
20
 
20
21
  SQL_COMMENT_REGEX = Regexp.new('/\*.*?\*/', Regexp::MULTILINE).freeze
@@ -13,10 +13,10 @@ module TingYun
13
13
 
14
14
  module_function
15
15
 
16
- def capture_exception(response,request,type)
16
+ def capture_exception(response,request)
17
17
  if response && response.code =~ /^[4,5][0-9][0-9]$/ && response.code!='401'
18
18
  e = TingYun::Support::Exception::InternalServerError.new("#{response.code}: #{response.message}")
19
- klass = "External/#{request.uri.to_s.gsub('/','%2F')}/#{type}"
19
+ klass = "External/#{request.uri.to_s.gsub('/','%2F')}/#{request.from}"
20
20
  set_attributes(e, klass, response.code)
21
21
 
22
22
  TingYun::Agent.notice_error(e)
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ module TingYun
5
+ module Instrumentation
6
+ module Support
7
+ module ExternalHelper
8
+ def create_tingyun_id(protocol)
9
+ state = TingYun::Agent::TransactionState.tl_get
10
+ externel_guid = tingyun_externel_guid
11
+ state.transaction_sample_builder.current_node["externalId"] = externel_guid
12
+ cross_app_id = TingYun::Agent.config[:tingyunIdSecret] or
13
+ raise TingYun::Agent::CrossAppTracing::Error, "no tingyunIdSecret configured"
14
+ "#{cross_app_id};c=1;x=#{state.request_guid};e=#{externel_guid};s=#{TingYun::Helper.time_to_millis(Time.now)};p=#{protocol}"
15
+ end
16
+
17
+ # generate a random 64 bit uuid
18
+ def tingyun_externel_guid
19
+ guid = ''
20
+ 16.times do
21
+ guid << (0..15).map{|i| i.to_s(16)}[rand(16)]
22
+ end
23
+ guid
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+