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
@@ -0,0 +1,47 @@
1
+ # encoding: utf-8
2
+ require 'ting_yun/agent/database'
3
+ module TingYun
4
+ module Agent
5
+ module Collector
6
+ class SlowSql
7
+ attr_reader :statement
8
+ attr_reader :metric_name
9
+ attr_reader :duration
10
+ attr_reader :backtrace
11
+ attr_reader :start_time
12
+
13
+
14
+ def initialize(statement, metric_name, duration, time, backtrace=nil)
15
+ @start_time = time
16
+ @statement = statement
17
+ @metric_name = metric_name
18
+ @duration = duration
19
+ @backtrace = backtrace
20
+ end
21
+
22
+ def sql
23
+ statement.sql
24
+ end
25
+
26
+ def obfuscate
27
+ TingYun::Agent::Database.obfuscate_sql(statement)
28
+ end
29
+
30
+
31
+ def normalize
32
+ TingYun::Agent::Database::Obfuscator.instance.default_sql_obfuscator(statement)
33
+ end
34
+
35
+ def explain
36
+ TingYun::Agent::Database.explain_sql(statement) if statement.config && statement.explainer
37
+ end
38
+
39
+ # We can't serialize the explainer, so clear it before we transmit
40
+ def prepare_to_send
41
+ statement.explainer = nil
42
+ end
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/metrics/stats'
4
+ require 'ting_yun/support/helper'
5
+ require 'ting_yun/support/coerce'
6
+
7
+ module TingYun
8
+ module Agent
9
+ module Collector
10
+
11
+ class SqlTrace < TingYun::Metrics::Stats
12
+
13
+ attr_reader :action_metric_name
14
+ attr_reader :uri
15
+ attr_reader :sql
16
+ attr_reader :slow_sql
17
+ attr_reader :params
18
+
19
+ def initialize(normalized_query, slow_sql, action_name, uri)
20
+ super()
21
+ @params = {}
22
+
23
+ @action_metric_name = action_name
24
+ @slow_sql = slow_sql
25
+ @sql = normalized_query
26
+ @uri = uri
27
+ @params[:stacktrace] = slow_sql.backtrace
28
+ record_data_point(float(slow_sql.duration))
29
+ end
30
+
31
+ def aggregate(slow_sql, action_name, uri)
32
+ duration = slow_sql.duration
33
+ if duration > max_call_time
34
+ @action_metric_name = action_name
35
+ @slow_sql = slow_sql
36
+ @uri = uri
37
+ @params[:stacktrace] = slow_sql.backtrace
38
+ end
39
+ record_data_point(float(duration))
40
+ end
41
+
42
+
43
+ def prepare_to_send
44
+ @sql = @slow_sql.sql unless Agent.config[:'nbs.action_tracer.record_sql'].to_s == 'obfuscated'
45
+ @params[:explainPlan] = @slow_sql.explain if need_to_explain?
46
+ end
47
+
48
+
49
+ def need_to_explain?
50
+ Agent.config[:'nbs.action_tracer.explain_enabled'] && @slow_sql.duration * 1000 > TingYun::Agent.config[:'nbs.action_tracer.explain_threshold']
51
+ end
52
+
53
+
54
+ include TingYun::Support::Coerce
55
+
56
+ def to_collector_array(encoder)
57
+ [
58
+ @slow_sql.start_time,
59
+ string(@action_metric_name),
60
+ string(@slow_sql.metric_name),
61
+ string(@uri||@action_metric_name),
62
+ string(@sql),
63
+ int(@call_count),
64
+ TingYun::Helper.time_to_millis(@total_call_time),
65
+ TingYun::Helper.time_to_millis(@max_call_time),
66
+ TingYun::Helper.time_to_millis(@min_call_time),
67
+ encoder.encode(@params)
68
+ ]
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ module TingYun
4
+ module Agent
5
+ module Collector
6
+ class TransactionSqlData
7
+ attr_reader :metric_name
8
+ attr_reader :uri
9
+ attr_reader :sql_data
10
+
11
+ def initialize(uri)
12
+ @sql_data = []
13
+ @uri = uri
14
+ end
15
+
16
+ def set_transaction_info(uri)
17
+ @uri = uri
18
+ end
19
+
20
+ def set_transaction_name(name)
21
+ @metric_name = name
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -126,16 +126,17 @@ module TingYun
126
126
 
127
127
  def reset!
128
128
  with_stats_lock do
129
- old = @stats_hash
130
129
  @stats_hash = StatsHash.new
131
- old
132
130
  end
133
131
  end
134
132
 
135
133
  def harvest!
136
- now = Time.now
137
- snapshot = reset!
138
- snapshot.harvested_at = now
134
+ snapshot = nil
135
+ with_stats_lock do
136
+ snapshot = @stats_hash
137
+ snapshot.harvested_at = Time.now
138
+ @stats_hash = StatsHash.new
139
+ end
139
140
  snapshot
140
141
  end
141
142
 
@@ -109,7 +109,7 @@ module TingYun
109
109
  end
110
110
 
111
111
  class StatsHashLookupError < TingYun::Support::Exception::InternalAgentError
112
- def initialize(original_error, hash, metric_spec)
112
+ def initialize(original_error, metric_spec)
113
113
  super("Lookup error in StatsHash: #{original_error.class}: #{original_error.message}. Falling back adding #{metric_spec.inspect}")
114
114
  end
115
115
  end
@@ -157,7 +157,7 @@ module TingYun
157
157
  # This only happen in the case of a corrupted default_proc
158
158
  # Side-step it manually, notice the issue, and carry on....
159
159
  ::TingYun::Agent.instance.error_collector. \
160
- notice_agent_error(StatsHashLookupError.new(error, hash, key))
160
+ notice_agent_error(StatsHashLookupError.new(error, key))
161
161
  stats = TingYun::Metrics::Stats.new
162
162
  hash[key] = stats
163
163
  # Try to restore the default_proc so we won't continually trip the error
@@ -2,7 +2,7 @@
2
2
 
3
3
  require 'ting_yun/agent/transaction/transaction_sample_builder'
4
4
  require 'ting_yun/agent/collector/transaction_sampler/slowest_sample_buffer'
5
-
5
+ require 'ting_yun/agent/collector/transaction_sampler/class_method'
6
6
  require 'ting_yun/agent/transaction/transaction_state'
7
7
 
8
8
 
@@ -11,6 +11,7 @@ module TingYun
11
11
  module Collector
12
12
  class TransactionSampler
13
13
 
14
+ extend TingYun::Agent::Collector::TransactionSampler::ClassMethod
14
15
 
15
16
  attr_accessor :last_sample
16
17
 
@@ -21,151 +22,8 @@ module TingYun
21
22
  @sample_buffers << TingYun::Agent::Collector::TransactionSampler::SlowestSampleBuffer.new
22
23
  end
23
24
 
24
-
25
- def notice_push_frame(state, time=Time.now)
26
- builder = state.transaction_sample_builder
27
- return unless builder
28
- builder.trace_entry(time.to_f)
29
- end
30
-
31
- # Informs the transaction sample builder about the end of a traced frame
32
- def notice_pop_frame(state, frame, time = Time.now)
33
- builder = state.transaction_sample_builder
34
- return unless builder
35
- builder.trace_exit(frame, time.to_f)
36
- end
37
-
38
- def enabled?
39
- TingYun::Agent.config[:'nbs.action_tracer.enabled']
40
- end
41
-
42
- def on_start_transaction(state, time)
43
- start_builder(state, time)
44
- end
45
-
46
- def start_builder(state, time=nil)
47
- if enabled?
48
- state.transaction_sample_builder ||= TingYun::Agent::TransactionSampleBuilder.new(time)
49
- else
50
- state.transaction_sample_builder = nil
51
- end
52
- end
53
-
54
-
55
- def on_finishing_transaction(state, txn, time=Time.now.to_f)
56
- last_builder = state.transaction_sample_builder
57
- return unless last_builder && enabled?
58
-
59
- last_builder.finish_trace(time)
60
-
61
- state.transaction_sample_builder = nil
62
-
63
-
64
- final_trace = last_builder.trace
65
- final_trace.metric_name = txn.best_name
66
- final_trace.uri = txn.request_path
67
- final_trace.attributes = txn.attributes
68
-
69
-
70
- @lock.synchronize do
71
- @last_sample = final_trace
72
-
73
- store_sample(@last_sample)
74
- @last_sample
75
- end
76
- end
77
-
78
- def store_sample(sample)
79
- @sample_buffers.each do |sample_buffer|
80
- sample_buffer.store(sample)
81
- end
82
- end
83
-
84
-
85
- # Attaches an SQL query on the current transaction trace node.
86
- # @param sql [String] the SQL query being recorded
87
- # @param config [Object] the driver configuration for the connection
88
- # @param duration [Float] number of seconds the query took to execute
89
- # @param explainer [Proc] for internal use only - 3rd-party clients must
90
- # not pass this parameter.
91
- # duration{:type => sec}
92
- def notice_sql(sql, config, duration, state=nil, explainer=nil)
93
- # some statements (particularly INSERTS with large BLOBS
94
- # may be very large; we should trim them to a maximum usable length
95
- state ||= TingYun::Agent::TransactionState.tl_get
96
- builder = state.transaction_sample_builder
97
- if state.sql_recorded?
98
- statement = TingYun::Agent::Database::Statement.new(sql, config, explainer)
99
- action_tracer_segment(builder, statement, duration, :sql)
100
- end
101
- end
102
-
103
- # duration{:type => sec}
104
- def notice_nosql(key, duration) #THREAD_LOCAL_ACCESS
105
- builder = tl_builder
106
- return unless builder
107
- action_tracer_segment(builder, key, duration, :key)
108
- end
109
-
110
- # duration{:type => sec}
111
- def notice_nosql_statement(statement, duration) #THREAD_LOCAL_ACCESS
112
- builder = tl_builder
113
- return unless builder
114
- action_tracer_segment(builder, statement, duration, :statement)
115
- end
116
-
117
-
118
-
119
- MAX_DATA_LENGTH = 16384
120
- # This method is used to record metadata into the currently
121
- # active node like a sql query, memcache key, or Net::HTTP uri
122
- #
123
- # duration is milliseconds, float value.
124
- # duration{:type => sec}
125
- def action_tracer_segment(builder, message, duration, key)
126
- return unless builder
127
- node = builder.current_node
128
- if node
129
- if key == :sql
130
- statement = node[:sql]
131
- if statement && !statement.sql.empty?
132
- statement.sql = self.class.truncate_message(statement.sql + "\n#{message.sql}") if statement.sql.length <= MAX_DATA_LENGTH
133
- else
134
- # message is expected to have been pre-truncated by notice_sql
135
- node[:sql] = message
136
- end
137
- else
138
- node[key] = self.class.truncate_message(message)
139
- end
140
- append_backtrace(node, duration)
141
- end
142
- end
143
-
144
- # Truncates the message to `MAX_DATA_LENGTH` if needed, and
145
- # appends an ellipsis because it makes the trucation clearer in
146
- # the UI
147
- def self.truncate_message(message)
148
- if message.length > (MAX_DATA_LENGTH - 4)
149
- message.slice!(MAX_DATA_LENGTH - 4..message.length)
150
- message << '...'
151
- else
152
- message
153
- end
154
- end
155
-
156
- # Appends a backtrace to a node if that node took longer
157
- # than the specified duration
158
- def append_backtrace(node, duration)
159
- if duration*1000 >= Agent.config[:'nbs.action_tracer.stack_trace_threshold']
160
- trace = caller.reject! { |t| t.include?('tingyun_rpm') }
161
- trace = trace.first(20)
162
- node[:stacktrace] = trace
163
- end
164
-
165
- end
166
-
167
25
  def harvest!
168
- return [] unless enabled?
26
+ return [] unless TingYun::Agent.config[:'nbs.action_tracer.enabled']
169
27
 
170
28
  samples = @lock.synchronize do
171
29
  @last_sample = nil
@@ -174,53 +32,59 @@ module TingYun
174
32
 
175
33
  prepare_samples(samples)
176
34
  end
177
-
178
35
  def harvest_from_sample_buffers
179
36
  result = []
180
37
  @sample_buffers.each { |buffer| result.concat(buffer.harvest_samples) }
181
38
  result.uniq
182
39
  end
183
-
184
40
  def prepare_samples(samples)
185
41
  samples.select do |sample|
186
42
  begin
187
43
  sample.prepare_to_send!
188
44
  rescue => e
189
-
190
45
  TingYun::Agent.logger.error('Failed to prepare transaction trace. Error: ', e)
191
-
192
46
  false
193
47
  else
194
48
  true
195
49
  end
196
50
  end
197
51
  end
198
-
199
52
  def merge!(previous)
200
-
201
53
  @lock.synchronize do
202
54
  @sample_buffers.each do |buffer|
203
55
  buffer.store_previous(previous)
204
56
  end
205
57
  end
206
58
  end
207
-
208
59
  def reset!
209
60
  @lock.synchronize do
210
61
  @sample_buffers.each { |sample| sample.reset! }
211
62
  end
212
63
  end
213
64
 
65
+ def on_finishing_transaction(state, txn, time=Time.now.to_f)
66
+ last_builder = state.transaction_sample_builder
67
+ return unless last_builder && TingYun::Agent.config[:'nbs.action_tracer.enabled']
214
68
 
215
- def add_node_info(params)
216
- builder = tl_builder
217
- return unless builder
218
- params.each { |k,v| builder.current_node.instance_variable_set(('@'<<k.to_s).to_sym, v) }
219
- end
69
+ last_builder.finish_trace(time)
70
+
71
+ final_trace = last_builder.trace
72
+ final_trace.attributes = txn.attributes
73
+
74
+
75
+ @lock.synchronize do
76
+ @last_sample = final_trace
220
77
 
221
- def tl_builder
222
- TingYun::Agent::TransactionState.tl_get.transaction_sample_builder
78
+ store_sample(@last_sample)
79
+ @last_sample
80
+ end
223
81
  end
82
+ def store_sample(sample)
83
+ @sample_buffers.each do |sample_buffer|
84
+ sample_buffer.store(sample)
85
+ end
86
+ end
87
+
224
88
 
225
89
  end
226
90
  end
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+
3
+ module TingYun
4
+ module Agent
5
+ module Collector
6
+ class TransactionSampler
7
+ module ClassMethod
8
+
9
+
10
+ def notice_push_frame(state, time=Time.now)
11
+ builder = state.transaction_sample_builder
12
+ return unless builder
13
+ builder.trace_entry(time.to_f)
14
+ end
15
+
16
+ # Informs the transaction sample builder about the end of a traced frame
17
+ def notice_pop_frame(state, frame, time = Time.now)
18
+ builder = state.transaction_sample_builder
19
+ return unless builder
20
+ builder.trace_exit(frame, time.to_f)
21
+ end
22
+
23
+
24
+ def on_start_transaction(state, time)
25
+ if TingYun::Agent.config[:'nbs.action_tracer.enabled']
26
+ state.transaction_sample_builder ||= TingYun::Agent::TransactionSampleBuilder.new(time)
27
+ else
28
+ state.transaction_sample_builder = nil
29
+ end
30
+ end
31
+
32
+ # Attaches an SQL query on the current transaction trace node.
33
+ # @param sql [String] the SQL query being recorded
34
+ # @param config [Object] the driver configuration for the connection
35
+ # @param duration [Float] number of seconds the query took to execute
36
+ # @param explainer [Proc] for internal use only - 3rd-party clients must
37
+ # not pass this parameter.
38
+ # duration{:type => sec}
39
+ def notice_sql(sql, config, duration, state=nil, explainer=nil, binds=[], name="SQL")
40
+ # some statements (particularly INSERTS with large BLOBS
41
+ # may be very large; we should trim them to a maximum usable length
42
+ state ||= TingYun::Agent::TransactionState.tl_get
43
+ builder = state.transaction_sample_builder
44
+ if state.sql_recorded?
45
+ statement = TingYun::Agent::Database::Statement.new(sql, config, explainer, binds, name)
46
+ action_tracer_segment(builder, statement, duration, :sql)
47
+ end
48
+ end
49
+
50
+ # duration{:type => sec}
51
+ def notice_nosql(key, duration) #THREAD_LOCAL_ACCESS
52
+ builder = tl_builder
53
+ action_tracer_segment(builder, key, duration, :key)
54
+ end
55
+
56
+ # duration{:type => sec}
57
+ def notice_nosql_statement(statement, duration) #THREAD_LOCAL_ACCESS
58
+ builder = tl_builder
59
+ action_tracer_segment(builder, statement, duration, :statement)
60
+ end
61
+
62
+
63
+
64
+
65
+
66
+ MAX_DATA_LENGTH = 16384
67
+ # This method is used to record metadata into the currently
68
+ # active node like a sql query, memcache key, or Net::HTTP uri
69
+ #
70
+ # duration is milliseconds, float value.
71
+ # duration{:type => sec}
72
+ def action_tracer_segment(builder, message, duration, key)
73
+ return unless builder
74
+ node = builder.current_node
75
+ if node
76
+ if key == :sql
77
+ statement = node[:sql]
78
+ if statement && !statement.sql.empty?
79
+ statement.sql = truncate_message(statement.sql + "\n#{message.sql}") if statement.sql.length <= MAX_DATA_LENGTH
80
+ else
81
+ # message is expected to have been pre-truncated by notice_sql
82
+ node[:sql] = message
83
+ end
84
+ else
85
+ node[key] = truncate_message(message)
86
+ end
87
+ append_backtrace(node, duration)
88
+ end
89
+ end
90
+
91
+ # Truncates the message to `MAX_DATA_LENGTH` if needed, and
92
+ # appends an ellipsis because it makes the trucation clearer in
93
+ # the UI
94
+ def truncate_message(message)
95
+ size = MAX_DATA_LENGTH - 4
96
+ if message.length > size
97
+ message.slice!(size..message.length)
98
+ message << '...'
99
+ else
100
+ message
101
+ end
102
+ end
103
+
104
+
105
+ # Appends a backtrace to a node if that node took longer
106
+ # than the specified duration
107
+ def append_backtrace(node, duration)
108
+ if duration*1000 >= Agent.config[:'nbs.action_tracer.stack_trace_threshold']
109
+ trace = caller.reject! { |t| t.include?('tingyun_rpm') }
110
+ trace = trace.first(20)
111
+ node[:stacktrace] = trace
112
+ end
113
+ end
114
+
115
+ def add_node_info(params)
116
+ builder = tl_builder
117
+ return unless builder
118
+ params.each { |k,v| builder.current_node.instance_variable_set(('@'<<k.to_s).to_sym, v) }
119
+ end
120
+
121
+ def tl_builder
122
+ TingYun::Agent::TransactionState.tl_get.transaction_sample_builder
123
+ end
124
+
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+