tingyun_rpm 1.1.4.2 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -1
  3. data/Guardfile +10 -0
  4. data/lib/ting_yun/agent.rb +1 -0
  5. data/lib/ting_yun/agent/agent.rb +16 -27
  6. data/lib/ting_yun/agent/collector/error_collector.rb +7 -18
  7. data/lib/ting_yun/agent/collector/error_collector/noticed_error.rb +26 -21
  8. data/lib/ting_yun/agent/collector/middle_ware_collector/cpu_sampler.rb +4 -9
  9. data/lib/ting_yun/agent/collector/sql_sampler.rb +32 -188
  10. data/lib/ting_yun/agent/collector/sql_sampler/slow_sql.rb +47 -0
  11. data/lib/ting_yun/agent/collector/sql_sampler/sql_trace.rb +73 -0
  12. data/lib/ting_yun/agent/collector/sql_sampler/transaction_sql_data.rb +26 -0
  13. data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +6 -5
  14. data/lib/ting_yun/agent/collector/stats_engine/stats_hash.rb +2 -2
  15. data/lib/ting_yun/agent/collector/transaction_sampler.rb +23 -159
  16. data/lib/ting_yun/agent/collector/transaction_sampler/class_method.rb +130 -0
  17. data/lib/ting_yun/agent/collector/transaction_sampler/slowest_sample_buffer.rb +1 -1
  18. data/lib/ting_yun/agent/collector/transaction_sampler/transaction_sample_buffer_base.rb +1 -1
  19. data/lib/ting_yun/agent/cross_app/cross_app_monitor.rb +29 -79
  20. data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +36 -66
  21. data/lib/ting_yun/agent/database.rb +41 -349
  22. data/lib/ting_yun/agent/database/connection_manager.rb +44 -0
  23. data/lib/ting_yun/agent/database/explain_plan_helpers.rb +173 -0
  24. data/lib/ting_yun/agent/database/obfuscator.rb +151 -0
  25. data/lib/ting_yun/agent/database/statement.rb +70 -0
  26. data/lib/ting_yun/agent/event/event_loop.rb +1 -2
  27. data/lib/ting_yun/agent/instance_methods/connect.rb +8 -20
  28. data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +2 -3
  29. data/lib/ting_yun/agent/instance_methods/handle_errors.rb +6 -1
  30. data/lib/ting_yun/agent/instance_methods/start.rb +13 -81
  31. data/lib/ting_yun/agent/transaction.rb +48 -391
  32. data/lib/ting_yun/agent/transaction/apdex.rb +53 -0
  33. data/lib/ting_yun/agent/transaction/attributes.rb +2 -1
  34. data/lib/ting_yun/agent/transaction/class_method.rb +127 -0
  35. data/lib/ting_yun/agent/transaction/exceptions.rb +42 -0
  36. data/lib/ting_yun/agent/transaction/instance_method.rb +139 -0
  37. data/lib/ting_yun/agent/transaction/request_attributes.rb +9 -39
  38. data/lib/ting_yun/agent/transaction/trace.rb +7 -5
  39. data/lib/ting_yun/agent/transaction/trace_node.rb +1 -3
  40. data/lib/ting_yun/agent/transaction/traced_method_stack.rb +2 -3
  41. data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +6 -1
  42. data/lib/ting_yun/agent/transaction/transaction_state.rb +59 -17
  43. data/lib/ting_yun/agent/transaction/transaction_timings.rb +72 -0
  44. data/lib/ting_yun/configuration.rb +11 -0
  45. data/lib/ting_yun/configuration/default_source.rb +20 -17
  46. data/lib/ting_yun/configuration/manager.rb +50 -21
  47. data/lib/ting_yun/frameworks.rb +1 -0
  48. data/lib/ting_yun/frameworks/rails.rb +15 -0
  49. data/lib/ting_yun/instrumentation/active_record.rb +12 -18
  50. data/lib/ting_yun/instrumentation/middleware_tracing.rb +8 -14
  51. data/lib/ting_yun/instrumentation/mongo.rb +21 -27
  52. data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +7 -3
  53. data/lib/ting_yun/instrumentation/moped.rb +2 -2
  54. data/lib/ting_yun/instrumentation/net.rb +4 -5
  55. data/lib/ting_yun/instrumentation/rack.rb +1 -2
  56. data/lib/ting_yun/instrumentation/rails4/active_record_subscriber.rb +22 -20
  57. data/lib/ting_yun/instrumentation/redis.rb +2 -2
  58. data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +1 -1
  59. data/lib/ting_yun/instrumentation/support/external_error.rb +19 -16
  60. data/lib/ting_yun/instrumentation/support/javascript_instrumentor.rb +92 -0
  61. data/lib/ting_yun/instrumentation/support/thrift_helper.rb +73 -0
  62. data/lib/ting_yun/instrumentation/thrift.rb +19 -222
  63. data/lib/ting_yun/logger.rb +1 -0
  64. data/lib/ting_yun/logger/agent_logger.rb +11 -67
  65. data/lib/ting_yun/logger/create_logger_helper.rb +72 -0
  66. data/lib/ting_yun/metrics/metric_data.rb +9 -31
  67. data/lib/ting_yun/metrics/metric_spec.rb +11 -0
  68. data/lib/ting_yun/metrics/stats.rb +24 -1
  69. data/lib/ting_yun/middleware/agent_middleware.rb +28 -0
  70. data/lib/ting_yun/middleware/browser_monitoring.rb +111 -0
  71. data/lib/ting_yun/support/coerce.rb +1 -0
  72. data/lib/ting_yun/support/exception.rb +2 -33
  73. data/lib/ting_yun/support/local_environment.rb +7 -7
  74. data/lib/ting_yun/support/serialize/marshaller.rb +7 -25
  75. data/lib/ting_yun/ting_yun_service.rb +12 -9
  76. data/lib/ting_yun/ting_yun_service/connection.rb +3 -0
  77. data/lib/ting_yun/ting_yun_service/http.rb +4 -1
  78. data/lib/ting_yun/ting_yun_service/request.rb +5 -13
  79. data/lib/ting_yun/ting_yun_service/upload_service.rb +5 -7
  80. data/lib/ting_yun/version.rb +3 -5
  81. data/lib/tingyun_rpm.rb +12 -10
  82. data/tingyun_rpm.gemspec +3 -0
  83. metadata +49 -5
  84. data/.DS_Store +0 -0
  85. data/lib/ting_yun/agent/collector/base_sampler.rb +0 -2
@@ -15,6 +15,7 @@ module TingYun
15
15
  framework.init_plugin(options)
16
16
  end
17
17
 
18
+
18
19
  class Framework
19
20
  include InstanceMethods
20
21
  extend ClassMethods
@@ -46,6 +46,8 @@ module TingYun
46
46
  # Might not be running if it does not think mongrel, thin, passenger, etc
47
47
  # is running, if it thinks it's a rake task, or if the nbs.agent_enabled is false.
48
48
  ::TingYun::Agent.logger.info("TingYun Agent is unable to run.")
49
+ else
50
+ install_browser_monitoring(rails_config)
49
51
  end
50
52
  rescue => e
51
53
  ::TingYun::Agent.logger.error("Failure during init_config for Rails. Is Rails required in a non-Rails app? Set TING_YUN_FRAMEWORK=ruby to avoid this message.",
@@ -53,6 +55,19 @@ module TingYun
53
55
  e)
54
56
  end
55
57
 
58
+ def install_browser_monitoring(config)
59
+ return if @browser_monitoring_installed
60
+ @browser_monitoring_installed = true
61
+ return if config.nil? || !config.respond_to?(:middleware)
62
+ begin
63
+ require 'ting_yun/middleware/browser_monitoring'
64
+ config.middleware.use TingYun::BrowserMonitoring
65
+ ::TingYun::Agent.logger.debug("Installed TingYun Browser Monitoring middleware")
66
+ rescue => e
67
+ ::TingYun::Agent.logger.error("Error installing TingYun Browser Monitoring middleware", e)
68
+ end
69
+ end
70
+
56
71
  protected
57
72
 
58
73
  def rails_vendor_root
@@ -1,26 +1,24 @@
1
1
  # encoding: utf-8
2
-
3
- require 'ting_yun/agent'
4
2
  require 'ting_yun/agent/transaction/transaction_state'
5
3
  require 'ting_yun/instrumentation/support/active_record_helper'
6
4
  require 'ting_yun/support/helper'
7
5
  require 'ting_yun/agent/method_tracer'
8
-
6
+ require 'ting_yun/agent/collector/transaction_sampler'
7
+ require 'ting_yun/agent/collector/sql_sampler'
8
+ require 'ting_yun/agent/database'
9
9
 
10
10
  module TingYun
11
11
  module Instrumentation
12
12
  module ActiveRecord
13
13
 
14
- EXPLAINER = lambda do |config, query|
15
- connection = TingYun::Agent::Database.get_connection(config) do
16
- ::ActiveRecord::Base.send("#{config[:adapter]}_connection",
17
- config)
18
- end
19
- if connection && connection.respond_to?(:execute)
20
- return connection.execute("EXPLAIN #{query}")
21
- end
14
+
15
+
16
+ def self.explain_plan(statement)
17
+ TingYun::Agent::Database.explain_plan(statement)
22
18
  end
23
19
 
20
+ EXPLAINER = method(:explain_plan)
21
+
24
22
  def self.included(instrumented_class)
25
23
  instrumented_class.class_eval do
26
24
  unless instrumented_class.method_defined?(:log_without_tingyun_instrumentation)
@@ -58,18 +56,14 @@ module TingYun
58
56
  log_without_tingyun_instrumentation(*args, &block)
59
57
  ensure
60
58
  elapsed_time = (Time.now - t0).to_f
61
- state.sql_duration = elapsed_time * 1000
59
+ state.timings.sql_duration = state.timings.sql_duration + elapsed_time * 1000
62
60
 
63
- TingYun::Agent.instance.transaction_sampler.notice_sql(sql, @config, elapsed_time,
64
- state, EXPLAINER)
65
- TingYun::Agent.instance.sql_sampler.notice_sql(sql, scoped_metric,
66
- @config, elapsed_time,
67
- state, EXPLAINER)
61
+ ::TingYun::Agent::Collector::TransactionSampler.notice_sql(sql, @config, elapsed_time, state, EXPLAINER)
62
+ ::TingYun::Agent::Collector::SqlSampler.notice_sql(sql, scoped_metric, @config, elapsed_time, state, EXPLAINER)
68
63
  end
69
64
 
70
65
  end
71
66
  end
72
-
73
67
  end
74
68
  end
75
69
  end
@@ -31,7 +31,7 @@ module TingYun
31
31
 
32
32
  def capture_http_response_code(state, result)
33
33
  if result.is_a?(Array) && state.current_transaction
34
- state.current_transaction.http_response_code = result[0]
34
+ state.current_transaction.attributes.add_agent_attribute(:httpStatus, result[0].to_s)
35
35
  end
36
36
  end
37
37
  # the trailing unless is for the benefit for Ruby 1.8.7 and can be removed
@@ -41,33 +41,27 @@ module TingYun
41
41
  def capture_response_content_type(state, result)
42
42
  if result.is_a?(Array) && state.current_transaction
43
43
  _, headers, _ = result
44
- state.current_transaction.response_content_type = headers[CONTENT_TYPE]
44
+ state.current_transaction.attributes.add_agent_attribute(:contentType, headers[CONTENT_TYPE].to_s)
45
45
  end
46
46
  end
47
47
 
48
- def capture_request(state, env)
49
- if env.is_a? Hash
50
-
51
- end
52
- end
53
48
 
54
49
  def call(env)
55
50
  first_middleware = note_transaction_started(env)
56
-
57
51
  state = TingYun::Agent::TransactionState.tl_get
58
- if first_middleware
59
- capture_request(state, env)
60
- end
61
52
  begin
53
+
54
+ if first_middleware
55
+ events.notify(:cross_app_before_call, env)
56
+ end
62
57
  TingYun::Agent::Transaction.start(state, category, build_transaction_options(env, first_middleware))
63
- events.notify(:before_call, env) if first_middleware
64
58
 
65
- result = target.call(env)
59
+ result = (target == self) ? traced_call(env) : target.call(env)
66
60
 
67
61
  if first_middleware
68
62
  capture_http_response_code(state, result)
69
63
  capture_response_content_type(state, result)
70
- events.notify(:after_call, result)
64
+ events.notify(:cross_app_after_call, result)
71
65
  end
72
66
 
73
67
  result
@@ -10,8 +10,7 @@ module TingYun
10
10
 
11
11
  def install_mongo_instrumentation
12
12
  hook_instrument_methods
13
- instrument_save
14
- instrument_ensure_index
13
+ instrument
15
14
  end
16
15
 
17
16
  def hook_instrument_methods
@@ -28,56 +27,51 @@ module TingYun
28
27
 
29
28
  def record_mongo_duration(duration)
30
29
  state = TingYun::Agent::TransactionState.tl_get
31
- unless state.nil?
32
- state.mon_duration += duration * 1000
30
+ if state
31
+ state.timings.mon_duration = state.timings.mon_duration + duration * 1000
33
32
  end
34
33
  end
35
34
 
36
- def ting_yun_generate_metrics(operation, payload = nil)
35
+ def tingyun_generate_metrics(operation, payload = nil)
37
36
  payload ||= { :collection => self.name, :database => self.db.name }
38
37
  TingYun::Instrumentation::Support::MetricTranslator.metrics_for(operation, payload)
39
38
  end
40
39
 
41
- def instrument_with_ting_yun_trace(name, payload = {}, &block)
42
- metrics = ting_yun_generate_metrics(name, payload)
40
+ def instrument_with_tingyun(name, payload = {}, &block)
41
+ metrics = tingyun_generate_metrics(name, payload)
43
42
 
44
43
  TingYun::Agent::MethodTracer.trace_execution_scoped(metrics, payload, method(:record_mongo_duration)) do
45
- instrument_without_ting_yun_trace(name, payload, &block)
44
+ instrument_without_tingyun(name, payload, &block)
46
45
  end
47
46
  end
48
47
 
49
- alias_method :instrument_without_ting_yun_trace, :instrument
50
- alias_method :instrument, :instrument_with_ting_yun_trace
48
+ alias_method :instrument_without_tingyun, :instrument
49
+ alias_method :instrument, :instrument_with_tingyun
51
50
  end
52
51
  end
53
52
 
54
- def instrument_save
53
+ def instrument
55
54
  ::Mongo::Collection.class_eval do
56
- def save_with_ting_yun_trace(doc, opts = {}, &block)
57
- metrics = ting_yun_generate_metrics(:save)
58
- TingYun::Agent::MethodTracer.trace_execution_scoped(metrics, opts, method(:record_mongo_duration)) do
59
- save_without_ting_yun_trace(doc, opts, &block)
55
+ def save_with_tingyun(doc, opts = {}, &block)
56
+ TingYun::Agent::MethodTracer.trace_execution_scoped(tingyun_generate_metrics(:save), opts, method(:record_mongo_duration)) do
57
+ save_without_tingyun(doc, opts, &block)
60
58
  end
61
59
  end
62
60
 
63
- alias_method :save_without_ting_yun_trace, :save
64
- alias_method :save, :save_with_ting_yun_trace
65
- end
66
- end
61
+ alias_method :save_without_tingyun, :save
62
+ alias_method :save, :save_with_tingyun
67
63
 
68
- def instrument_ensure_index
69
- ::Mongo::Collection.class_eval do
70
- def ensure_index_with_ting_yun_trace(spec, opts = {}, &block)
71
- metrics = ting_yun_generate_metrics(:ensureIndex)
72
- TingYun::Agent::MethodTracer.trace_execution_scoped(metrics, opts, method(:record_mongo_duration)) do
73
- ensure_index_with_out_ting_yun_trace(spec, opts, &block)
64
+ def ensure_index_with_tingyun(spec, opts = {}, &block)
65
+ TingYun::Agent::MethodTracer.trace_execution_scoped(tingyun_generate_metrics(:ensureIndex), opts, method(:record_mongo_duration)) do
66
+ ensure_index_without_tingyun(spec, opts, &block)
74
67
  end
75
68
  end
76
69
 
77
- alias_method :ensure_index_with_out_ting_yun_trace, :ensure_index
78
- alias_method :ensure_index, :ensure_index_with_ting_yun_trace
70
+ alias_method :ensure_index_without_tingyun, :ensure_index
71
+ alias_method :ensure_index, :ensure_index_with_tingyun
79
72
  end
80
73
  end
74
+
81
75
  end
82
76
  end
83
77
  end
@@ -5,7 +5,7 @@ require 'ting_yun/agent/transaction/transaction_state'
5
5
  require 'ting_yun/agent/datastore/metric_helper'
6
6
  require 'ting_yun/agent/datastore/mongo'
7
7
  require 'ting_yun/instrumentation/support/event_formatter'
8
-
8
+ require 'ting_yun/agent/collector/transaction_sampler'
9
9
 
10
10
  module TingYun
11
11
  module Instrumentation
@@ -27,7 +27,7 @@ module TingYun
27
27
  def completed(event)
28
28
  begin
29
29
  state = TingYun::Agent::TransactionState.tl_get
30
- state.mon_duration = event.duration*1000
30
+ state.timings.mon_duration = state.timings.mon_duration + event.duration * 1000
31
31
  started_event = operations.delete(event.operation_id)
32
32
 
33
33
  base, *other_metrics = metrics(started_event)
@@ -87,11 +87,15 @@ module TingYun
87
87
  # enter transaction trace node
88
88
  frame = stack.push_frame(state, :mongo_db, end_time - duration)
89
89
 
90
- TingYun::Agent.instance.transaction_sampler.notice_nosql_statement(generate_statement(event),duration*1000)
90
+ transaction_sampler.notice_nosql_statement(generate_statement(event),duration*1000)
91
91
 
92
92
  # exit transaction trace node
93
93
  stack.pop_frame(state, frame, metric, end_time)
94
94
  end
95
+
96
+ def transaction_sampler
97
+ ::TingYun::Agent::Collector::TransactionSampler
98
+ end
95
99
  end
96
100
  end
97
101
  end
@@ -63,8 +63,8 @@ module TingYun
63
63
 
64
64
  def record_mongo_duration(_1, _2, duration)
65
65
  state = TingYun::Agent::TransactionState.tl_get
66
- unless state.nil?
67
- state.mon_duration += duration * 1000
66
+ if state
67
+ state.timings.mon_duration = state.timings.mon_duration + duration * 1000
68
68
  end
69
69
  end
70
70
 
@@ -34,10 +34,9 @@ TingYun::Support::LibraryDetection.defer do
34
34
  class << self
35
35
  def get_response_with_tingyun(uri_or_host, path = nil, port = nil, &block)
36
36
  begin
37
- get_response_without_tingyun(uri_or_host, path = nil, port = nil, &block)
37
+ get_response_without_tingyun(uri_or_host, path , port , &block)
38
38
  rescue => e
39
- klass = "External/#{uri_or_host.to_s.gsub('/','%2F')}/net%2Fhttp"
40
- ::TingYun::Instrumentation::Support::ExternalError.handle_error(e,klass)
39
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{uri_or_host.to_s.gsub('/','%2F')}/net%2Fhttp")
41
40
  raise e
42
41
  end
43
42
  end
@@ -48,13 +47,13 @@ TingYun::Support::LibraryDetection.defer do
48
47
  begin
49
48
  start_without_tingyun(address, *arg, &block)
50
49
  rescue => e
51
- klass = "External/#{address.to_s.gsub('/','%2F')}/net%2Fhttp"
52
- ::TingYun::Instrumentation::Support::ExternalError.handle_error(e,klass)
50
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e, "External/#{address.to_s.gsub('/','%2F')}/net%2Fhttp")
53
51
  raise e
54
52
  end
55
53
  end
56
54
  alias :start_without_tingyun :start
57
55
  alias :start :start_with_tingyun
56
+
58
57
  end
59
58
  end
60
59
  end
@@ -60,8 +60,7 @@ module TingYun
60
60
  TingYun::Support::LibraryDetection.detect!
61
61
  ::Rack::Builder._nr_deferred_detection_ran = true
62
62
  end
63
-
64
- result = to_app_without_tingyun
63
+ to_app_without_tingyun
65
64
  end
66
65
  end
67
66
  end
@@ -3,7 +3,9 @@ require 'ting_yun/instrumentation/support/evented_subscriber'
3
3
  require 'ting_yun/agent/transaction/transaction_state'
4
4
  require 'ting_yun/instrumentation/support/active_record_helper'
5
5
  require 'ting_yun/support/helper'
6
-
6
+ require 'ting_yun/agent/collector/transaction_sampler'
7
+ require 'ting_yun/agent/collector/sql_sampler'
8
+ require 'ting_yun/agent/database'
7
9
 
8
10
  module TingYun
9
11
  module Instrumentation
@@ -14,10 +16,14 @@ module TingYun
14
16
  def initialize
15
17
  # We cache this in an instance variable to avoid re-calling method
16
18
  # on each query.
17
- @explainer = method(:get_explain_plan)
19
+ @explainer = method(:explain_plan)
18
20
  super
19
21
  end
20
22
 
23
+ def explain_plan(statement)
24
+ TingYun::Agent::Database.explain_plan(statement)
25
+ end
26
+
21
27
  def start(name, id, payload) #THREAD_LOCAL_ACCESS
22
28
 
23
29
  return if payload[:name] == CACHED_QUERY_NAME
@@ -33,35 +39,23 @@ module TingYun
33
39
  config = active_record_config_for_event(event)
34
40
  base_metric = record_metrics(event, config)
35
41
  notice_sql(state, event, config, base_metric)
36
- rescue => e
42
+ rescue Exception => e
37
43
  log_notification_error(e, name, 'finish')
38
44
  end
39
45
 
40
- def get_explain_plan( config, query )
41
- connection = TingYun::Agent::Database.get_connection(config) do
42
- ::ActiveRecord::Base.send("#{config[:adapter]}_connection",
43
- config)
44
- end
45
- if connection && connection.respond_to?(:execute)
46
- return connection.execute("EXPLAIN #{query}")
47
- end
48
- end
49
46
 
50
47
  def notice_sql(state, event, config, metric)
51
48
  stack = state.traced_method_stack
52
- state.sql_duration = event.duration
49
+ state.timings.sql_duration = state.timings.sql_duration + event.duration
53
50
  # enter transaction trace node
54
51
  frame = stack.push_frame(state, :active_record, event.time)
55
52
 
56
- TingYun::Agent.instance.sql_sampler \
57
- .notice_sql(event.payload[:sql], metric, config,
53
+ sql_sampler.notice_sql(event.payload[:sql], metric, config,
58
54
  TingYun::Helper.milliseconds_to_seconds(event.duration),
59
- state, @explainer)
55
+ state, @explainer, event.payload[:binds], event.payload[:name])
60
56
 
61
- TingYun::Agent.instance.transaction_sampler \
62
- .notice_sql(event.payload[:sql], config,
63
- event.duration,
64
- state, @explainer)
57
+ transaction_sampler.notice_sql(event.payload[:sql], config, event.duration,
58
+ state, @explainer, event.payload[:binds], event.payload[:name])
65
59
  # exit transaction trace node
66
60
  stack.pop_frame(state, frame, metric, event.end)
67
61
  end
@@ -93,6 +87,14 @@ module TingYun
93
87
 
94
88
  connection.instance_variable_get(:@config) if connection
95
89
  end
90
+
91
+ def transaction_sampler
92
+ ::TingYun::Agent::Collector::TransactionSampler
93
+ end
94
+
95
+ def sql_sampler
96
+ ::TingYun::Agent::Collector::SqlSampler
97
+ end
96
98
  end
97
99
  end
98
100
  end
@@ -22,8 +22,8 @@ TingYun::Support::LibraryDetection.defer do
22
22
 
23
23
  def record_redis_duration(_1, _2, duration)
24
24
  state = TingYun::Agent::TransactionState.tl_get
25
- unless state.nil?
26
- state.rds_duration += duration * 1000
25
+ if state
26
+ state.timings.rds_duration = state.timings.rds_duration + duration * 1000
27
27
  end
28
28
  end
29
29
 
@@ -22,7 +22,7 @@ module TingYun
22
22
  txn_options = create_transaction_options(trace_options, category)
23
23
 
24
24
  begin
25
- txn = TingYun::Agent::Transaction.start(state, category, txn_options)
25
+ TingYun::Agent::Transaction.start(state, category, txn_options)
26
26
  begin
27
27
  yield
28
28
  rescue => e
@@ -2,50 +2,53 @@
2
2
  require 'ting_yun/agent'
3
3
  require 'ting_yun/support/exception'
4
4
 
5
+
5
6
  module TingYun
6
7
  module Instrumentation
7
8
  module Support
9
+ module Variables
10
+ attr_accessor :tingyun_code, :tingyun_klass, :tingyun_external, :tingyun_trace
11
+ end
8
12
  module ExternalError
9
13
 
10
-
11
14
  module_function
12
15
 
13
16
  def capture_exception(response,request,type)
14
- if !response.nil? && response.code =~ /^[4,5][0-9][0-9]$/ && response.code!='401'
17
+ if response && response.code =~ /^[4,5][0-9][0-9]$/ && response.code!='401'
15
18
  e = TingYun::Support::Exception::InternalServerError.new("#{response.code}: #{response.message}")
16
19
  klass = "External/#{request.uri.to_s.gsub('/','%2F')}/#{type}"
17
- set_attributes(e, klass)
18
- e.instance_variable_set(:@tingyun_code, response.code)
20
+ set_attributes(e, klass, response.code)
21
+
19
22
  TingYun::Agent.notice_error(e)
20
23
  end
21
24
  end
22
25
 
23
26
  def handle_error(e,klass)
24
-
25
- set_attributes(e, klass)
26
27
  case e
27
28
  when Errno::ECONNREFUSED
28
- e.instance_variable_set(:@tingyun_code, 902)
29
+ set_attributes(e, klass, 902)
29
30
  when SocketError
30
- e.instance_variable_set(:@tingyun_code, 901)
31
+ set_attributes(e, klass, 901)
31
32
  when OpenSSL::SSL::SSLError
32
- e.instance_variable_set(:@tingyun_code, 908)
33
+ set_attributes(e, klass, 908)
33
34
  when Timeout::Error
34
- e.instance_variable_set(:@tingyun_code, 903)
35
+ set_attributes(e, klass, 903)
35
36
  else
36
- e.instance_variable_set(:@tingyun_code, 1000)
37
+ set_attributes(e, klass, 1000)
37
38
  end
38
39
 
39
40
  TingYun::Agent.notice_error(e)
40
41
  end
41
42
 
42
- def set_attributes(exception, klass)
43
+ def set_attributes(exception, klass, code)
44
+ exception.instance_exec {extend TingYun::Instrumentation::Support::Variables}
43
45
  begin
44
- exception.instance_variable_set(:@tingyun_klass, klass)
45
- exception.instance_variable_set(:@tingyun_external, true)
46
+ exception.tingyun_code = code
47
+ exception.tingyun_klass = klass
48
+ exception.tingyun_external = true
46
49
  trace = caller.reject! { |t| t.include?('tingyun_rpm') }
47
- trace = trace.first(40) if trace.length > 40
48
- exception.instance_variable_set(:@tingyun_trace, trace)
50
+ trace = trace.first(20)
51
+ exception.tingyun_trace = trace
49
52
  rescue => e
50
53
  TingYun::Agent.logger.warn("Failed to set attributes for : #{exception}: ", e)
51
54
  end