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
@@ -8,13 +8,14 @@ module TingYun
8
8
  class Transaction
9
9
  class Trace
10
10
 
11
- attr_accessor :root_node, :node_count, :threshold, :metric_name, :uri, :guid, :attributes, :start_time, :finished, :tx_id
11
+ attr_accessor :root_node, :node_count, :threshold, :guid, :attributes, :start_time, :finished
12
12
 
13
13
  def initialize(start_time)
14
14
  @start_time = start_time
15
15
  @node_count = 0
16
16
  @prepared = false
17
17
  @guid = generate_guid
18
+ @root_node = TingYun::Agent::Transaction::TraceNode.new(0.0, "ROOT")
18
19
  end
19
20
 
20
21
  def create_node(time_since_start, metric_name = nil)
@@ -27,6 +28,7 @@ module TingYun
27
28
  end
28
29
 
29
30
 
31
+ EMPTY_STRING = ''.freeze
30
32
 
31
33
  include TingYun::Support::Coerce
32
34
 
@@ -43,10 +45,10 @@ module TingYun
43
45
  [
44
46
  @start_time.round,
45
47
  duration,
46
- TingYun::Helper.correctly_encoded(metric_name)|| '',
47
- TingYun::Helper.correctly_encoded(uri||metric_name||''),
48
+ TingYun::Helper.correctly_encoded(attributes.agent_attributes[:metric_name]|| EMPTY_STRING),
49
+ TingYun::Helper.correctly_encoded(attributes.agent_attributes[:request_path]||attributes.agent_attributes[:metric_name]|| EMPTY_STRING),
48
50
  encoder.encode(trace_tree),
49
- tx_id || '',
51
+ attributes.agent_attributes[:tx_id],
50
52
  guid
51
53
  ]
52
54
  end
@@ -95,7 +97,7 @@ module TingYun
95
97
  def custom_params
96
98
  custom_param = {
97
99
  :threadName => string(attributes.agent_attributes[:threadName]),
98
- :referer => string(attributes.agent_attributes[:referer]) || ''
100
+ :referer => string(attributes.agent_attributes[:referer]) || EMPTY_STRING
99
101
  }
100
102
  custom_param[:httpStatus] = int(attributes.agent_attributes[:httpStatus]) if attributes.agent_attributes[:httpStatus]
101
103
 
@@ -95,9 +95,7 @@ module TingYun
95
95
  return nil unless statement.respond_to?(:config) &&
96
96
  statement.respond_to?(:explainer)
97
97
 
98
- TingYun::Agent::Database.explain_sql(statement.sql,
99
- statement.config,
100
- statement.explainer)
98
+ TingYun::Agent::Database.explain_sql(statement)
101
99
  end
102
100
 
103
101
  protected
@@ -1,4 +1,5 @@
1
1
  # encoding: utf-8
2
+ require 'ting_yun/agent/collector/transaction_sampler'
2
3
 
3
4
  module TingYun
4
5
  module Agent
@@ -62,10 +63,8 @@ module TingYun
62
63
  TingYun::Agent.config[:'nbs.action_tracer.enabled']
63
64
  end
64
65
 
65
-
66
-
67
66
  def transaction_sampler
68
- TingYun::Agent.instance.transaction_sampler
67
+ ::TingYun::Agent::Collector::TransactionSampler
69
68
  end
70
69
 
71
70
  def clear
@@ -31,6 +31,7 @@ module TingYun
31
31
  def initialize(time=Time.now)
32
32
  @trace = TingYun::Agent::Transaction::Trace.new(time.to_f)
33
33
  @trace_start = time.to_f
34
+ @current_node = @trace.root_node
34
35
  end
35
36
 
36
37
  def trace_entry(time)
@@ -91,11 +92,15 @@ module TingYun
91
92
  end
92
93
 
93
94
 
94
-
95
+ def set_txId_and_txData(txid, txdata)
96
+ @current_node[:txId] = txid
97
+ @current_node[:txData] = txdata
98
+ end
95
99
 
96
100
  def node_limit
97
101
  Agent.config[:'transaction_tracer.limit_segments']
98
102
  end
103
+
99
104
  end
100
105
  end
101
106
  end
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'ting_yun/agent/transaction/traced_method_stack'
4
+ require 'ting_yun/agent/transaction/transaction_timings'
4
5
  module TingYun
5
6
  module Agent
6
7
 
@@ -10,19 +11,12 @@ module TingYun
10
11
 
11
12
  # Request data
12
13
  attr_accessor :transaction_sample_builder
13
- attr_reader :current_transaction, :traced_method_stack
14
+ attr_reader :current_transaction, :traced_method_stack, :timings
14
15
  # Sql Sampler Transaction Data
15
16
  attr_accessor :sql_sampler_transaction_data,
16
17
  :client_transaction_id,
17
18
  :client_tingyun_id_secret,
18
19
  :client_req_id,
19
- :sql_duration,
20
- :external_duration,
21
- :web_duration,
22
- :queue_duration,
23
- :rds_duration,
24
- :mc_duration,
25
- :mon_duration,
26
20
  :thrift_return_data
27
21
 
28
22
 
@@ -54,26 +48,21 @@ module TingYun
54
48
  @untraced = []
55
49
  @current_transaction = nil
56
50
  @traced_method_stack = TingYun::Agent::TracedMethodStack.new
57
- @sql_duration = 0
58
- @external_duration = 0
59
- @web_duration = 0
60
- @queue_duration = 0
61
- @rds_duration = 0
62
- @mc_duration = 0
63
- @mon_duration = 0
51
+ @record_tt = nil
64
52
  end
65
53
 
66
54
  # This starts the timer for the transaction.
67
55
  def reset(transaction=nil)
68
- # We purposefully don't reset @untraced, @record_tt and @record_sql
56
+ # We purposefully don't reset @untraced, @record_tt and @record_sql,@client_transaction_id,@client_tingyun_id_secret
69
57
  # since those are managed by TingYun::Agent.disable_* calls explicitly
70
58
  # and (more importantly) outside the scope of a transaction
71
59
  @current_transaction = transaction
72
60
  @traced_method_stack.clear
73
61
  @transaction_sample_builder = nil
74
62
  @sql_sampler_transaction_data = nil
75
- @cross_tx_data = nil
76
63
  @thrift_return_data = nil
64
+ @timings = nil
65
+ @client_req_id = nil
77
66
  end
78
67
 
79
68
  # TT's and SQL
@@ -106,6 +95,59 @@ module TingYun
106
95
  end
107
96
 
108
97
 
98
+ def init_sql_transaction(obj)
99
+ @sql_sampler_transaction_data = obj
100
+ end
101
+
102
+ def self.process_thrift_data(data)
103
+ state = tl_get
104
+ state.thrift_return_data = data
105
+ builder = state.transaction_sample_builder
106
+ builder.set_txId_and_txData(state.request_guid, data) if builder
107
+ end
108
+
109
+ def save_referring_transaction_info(data)
110
+ data = Array(data)
111
+ @client_tingyun_id_secret = data.shift
112
+ data.each do |e|
113
+ if m = e.match(/x=/)
114
+ @client_transaction_id = m.post_match
115
+ elsif m = e.match(/r=/)
116
+ @client_req_id = m.post_match
117
+ end
118
+ end
119
+ end
120
+
121
+ def timings
122
+ @timings ||= TingYun::Agent::TransactionTimings.new(transaction_queue_time, transaction_start_time)
123
+ end
124
+
125
+ def transaction_start_time
126
+ current_transaction.nil? ? 0.0 : current_transaction.start_time
127
+ end
128
+
129
+ def transaction_queue_time
130
+ current_transaction.nil? ? 0.0 : current_transaction.apdex.queue_time
131
+ end
132
+
133
+ def transaction_name
134
+ current_transaction.nil? ? nil : current_transaction.best_name
135
+ end
136
+
137
+ def trace_id
138
+ transaction_sample_builder.nil? ? nil : transaction_sample_builder.trace.guid
139
+ end
140
+
141
+ def same_account?
142
+ server_info = TingYun::Agent.config[:tingyunIdSecret].split('|')
143
+ client_info = (@client_tingyun_id_secret || '').split('|')
144
+ if server_info[0] && !server_info[0].empty? && server_info[0] == client_info[0]
145
+ return true
146
+ else
147
+ return false
148
+ end
149
+ end
150
+
109
151
  end
110
152
  end
111
153
  end
@@ -0,0 +1,72 @@
1
+ # encoding: utf-8
2
+
3
+ require 'forwardable'
4
+
5
+ module TingYun
6
+ module Agent
7
+ class TransactionTimings
8
+
9
+ class Timings < Struct.new :sql_duration, :external_duration, :rds_duration, :mc_duration, :mon_duration; end
10
+
11
+ def initialize(queue_time_in_seconds, start_time_in_seconds)
12
+ @queue_time_in_seconds = clamp_to_positive(queue_time_in_seconds.to_f)
13
+ @start_time_in_seconds = clamp_to_positive(start_time_in_seconds.to_f)
14
+
15
+ @timings = TingYun::Agent::TransactionTimings::Timings.new(0.0,0.0,0.0,0.0,0.0)
16
+ end
17
+
18
+
19
+ attr_reader :start_time_in_seconds, :queue_time_in_seconds, :timings
20
+
21
+ extend Forwardable
22
+
23
+ def_delegators :@timings, :sql_duration, :sql_duration= ,
24
+ :external_duration, :external_duration=,
25
+ :rds_duration, :rds_duration=,
26
+ :mc_duration, :mc_duration=,
27
+ :mon_duration, :mon_duration=
28
+
29
+
30
+
31
+ def start_time_as_time
32
+ Time.at(@start_time_in_seconds)
33
+ end
34
+
35
+ def start_time_in_millis
36
+ convert_to_milliseconds(@start_time_in_seconds)
37
+ end
38
+
39
+ def queue_time_in_millis
40
+ convert_to_milliseconds(queue_time_in_seconds)
41
+ end
42
+
43
+ def app_time_in_millis
44
+ convert_to_milliseconds(app_time_in_seconds)
45
+ end
46
+
47
+ def app_time_in_seconds
48
+ Time.now.to_f - @start_time_in_seconds
49
+ end
50
+
51
+ def app_execute_duration
52
+ app_time_in_millis - queue_time_in_millis - sql_duration - external_duration - rds_duration - mon_duration - mc_duration
53
+ end
54
+
55
+ # Helpers
56
+
57
+ def slow_action_tracer?
58
+ return app_time_in_seconds > TingYun::Agent.config[:'nbs.action_tracer.action_threshold']
59
+ end
60
+
61
+ def convert_to_milliseconds(value_in_seconds)
62
+ clamp_to_positive((value_in_seconds.to_f * 1000.0).round)
63
+ end
64
+
65
+ def clamp_to_positive(value)
66
+ return 0.0 if value < 0.0
67
+ value
68
+ end
69
+
70
+ end
71
+ end
72
+ end
@@ -5,5 +5,16 @@
5
5
  module TingYun
6
6
  module Configuration
7
7
 
8
+ def self.get_name
9
+ app_name = TingYun::Agent.config[:app_name]
10
+ case app_name
11
+ when Array then
12
+ app_name
13
+ when String then
14
+ app_name.split(';')
15
+ else
16
+ []
17
+ end
18
+ end
8
19
  end
9
20
  end
@@ -15,6 +15,7 @@ module TingYun
15
15
  TingYun::Agent.config[key]
16
16
  end
17
17
  end
18
+
18
19
 
19
20
  class Boolean;
20
21
  end
@@ -107,12 +108,6 @@ module TingYun
107
108
  Proc.new { TingYun::Agent.config[:ssl] ? 443 : 80 }
108
109
  end
109
110
 
110
- def self.agent_enabled
111
- Proc.new {
112
- TingYun::Agent.config[:enabled]
113
- }
114
- end
115
-
116
111
  def self.action_tracer_action_threshold
117
112
  Proc.new { TingYun::Agent.config[:apdex_t] * 4 }
118
113
  end
@@ -161,7 +156,7 @@ module TingYun
161
156
  :description => 'Enable or disable the agent.'
162
157
  },
163
158
  :'nbs.agent_enabled' => {
164
- :default => DefaultSource.agent_enabled,
159
+ :default => true,
165
160
  :public => true,
166
161
  :type => Boolean,
167
162
  :allowed_from_server => true,
@@ -289,7 +284,7 @@ module TingYun
289
284
  },
290
285
  :'nbs.rum.enabled' => {
291
286
  :default => false,
292
- :public => false,
287
+ :public => true,
293
288
  :type => Boolean,
294
289
  :allowed_from_server => true,
295
290
  :description => 'Enable or disable page load timing (sometimes referred to as real user monitoring or RUM).'
@@ -297,11 +292,19 @@ module TingYun
297
292
  :'nbs.rum.script' => {
298
293
  :default => nil,
299
294
  :allow_nil => true,
300
- :public => false,
295
+ :public => true,
301
296
  :type => String,
302
297
  :allowed_from_server => true,
303
298
  :description => 'RUM Script URI'
304
299
  },
300
+ :'nbs.rum.mix_enabled' => {
301
+ :default => false,
302
+ :allow_nil => false,
303
+ :public => true,
304
+ :type => String,
305
+ :allowed_from_server => true,
306
+ :description => '混合嵌码'
307
+ },
305
308
  :'nbs.rum.sample_ratio' => {
306
309
  :default => 1,
307
310
  :public => true,
@@ -373,13 +376,6 @@ module TingYun
373
376
  :allowed_from_server => false,
374
377
  :description => 'Autodetected application framework used to enable framework-specific functionality.'
375
378
  },
376
- :monitor_mode => {
377
- :default => true,
378
- :public => true,
379
- :type => Boolean,
380
- :allowed_from_server => false,
381
- :description => 'Enable or disable the transmission of data to the collector.'
382
- },
383
379
  :'nbs.audit_mode' => {
384
380
  :default => false,
385
381
  :public => true,
@@ -454,7 +450,7 @@ module TingYun
454
450
  :public => false,
455
451
  :type => Fixnum,
456
452
  :allowed_from_server => false,
457
- :description => 'Port for the New Relic API host.'
453
+ :description => 'Port for the TingYun API host.'
458
454
  },
459
455
  :disable_middleware_instrumentation => {
460
456
  :default => false,
@@ -642,6 +638,13 @@ module TingYun
642
638
  :type => Array,
643
639
  :allowed_from_server => false,
644
640
  :description => 'Specify an array of Rake tasks to automatically instrument.'
641
+ },
642
+ :'nbs.transaction_tracer.thrift' =>{
643
+ :default => true,
644
+ :public => true,
645
+ :type => Boolean,
646
+ :allowed_from_server => true,
647
+ :description => 'Enable or disable the thrift cross application feature'
645
648
  }
646
649
  }.freeze
647
650
  end
@@ -5,12 +5,56 @@ require 'ting_yun/configuration/environment_source'
5
5
  require 'ting_yun/configuration/yaml_source'
6
6
  require 'ting_yun/configuration/server_source'
7
7
  require 'ting_yun/configuration/manual_source'
8
-
8
+ require 'ting_yun/configuration'
9
9
 
10
10
  module TingYun
11
11
  module Configuration
12
12
  class Manager
13
13
 
14
+ # module Arel
15
+ # module Visitors
16
+ # class Visitor
17
+ # def initialize
18
+ # @dispatch = get_dispatch_cache
19
+ # end
20
+ #
21
+ # def accept object
22
+ # visit object
23
+ # end
24
+ #
25
+ # private
26
+ #
27
+ # def self.dispatch_cache
28
+ # Hash.new do |hash, klass|
29
+ # hash[klass] = "visit_#{(klass.name || '').gsub('::', '_')}"
30
+ # end
31
+ # end
32
+ #
33
+ # def get_dispatch_cache
34
+ # self.class.dispatch_cache
35
+ # end
36
+ #
37
+ # def dispatch
38
+ # @dispatch
39
+ # end
40
+ #
41
+ # def visit object
42
+ # send dispatch[object.class], object
43
+ # rescue NoMethodError => e
44
+ # raise e if respond_to?(dispatch[object.class], true)
45
+ # superklass = object.class.ancestors.find { |klass|
46
+ # respond_to?(dispatch[klass], true)
47
+ # }
48
+ # raise(TypeError, "Cannot visit #{object.class}") unless superklass
49
+ # dispatch[object.class] = dispatch[superklass]
50
+ # retry
51
+ # end
52
+ # end
53
+ # end
54
+ # end
55
+ # 实现缓存的一种方式
56
+
57
+
14
58
  def initialize
15
59
  reset_to_defaults
16
60
  end
@@ -31,23 +75,11 @@ module TingYun
31
75
  if TingYun::Agent.config[:'nbs.auto_app_naming']
32
76
  begin
33
77
  [::TingYun::Frameworks.framework.root.split('/').last]
34
- rescue Exception => e
35
- get_name
78
+ rescue
79
+ ::TingYun::Configuration.get_name
36
80
  end
37
81
  else
38
- get_name
39
- end
40
-
41
- end
42
-
43
- def get_name
44
- case TingYun::Agent.config[:app_name]
45
- when Array then
46
- TingYun::Agent.config[:app_name]
47
- when String then
48
- TingYun::Agent.config[:app_name].split(';')
49
- else
50
- []
82
+ ::TingYun::Configuration.get_name
51
83
  end
52
84
  end
53
85
 
@@ -74,7 +106,7 @@ module TingYun
74
106
  accessor = key.to_sym
75
107
 
76
108
  if config.has_key?(accessor)
77
- return evaluated = evaluate_procs(config[accessor]) #if it's proc
109
+ return evaluate_procs(config[accessor]) #if it's proc
78
110
  end
79
111
  end
80
112
  nil
@@ -144,12 +176,9 @@ module TingYun
144
176
 
145
177
  log_config(:add, source)
146
178
 
147
- notify_finished_configuring if !was_finished && finished_configuring?
179
+ TingYun::Agent.instance.events.notify(:finished_configuring) if !was_finished && finished_configuring?
148
180
  end
149
181
 
150
- def notify_finished_configuring
151
- TingYun::Agent.instance.events.notify(:finished_configuring)
152
- end
153
182
 
154
183
  def finished_configuring?
155
184
  !@server_source.nil?