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
@@ -2,6 +2,8 @@
2
2
  require 'ting_yun/metrics/metric_spec'
3
3
  require 'ting_yun/metrics/metric_data'
4
4
  require 'ting_yun/support/serialize/encodes'
5
+ require 'ting_yun/support/quantile_p2'
6
+ require 'json'
5
7
 
6
8
  module TingYun
7
9
  class TingYunService
@@ -20,9 +22,8 @@ module TingYun
20
22
  TingYun::Support::Serialize::Encoders::Json
21
23
  end
22
24
 
23
- def metric_data(stats_hash)
24
-
25
- action_array, adpex_array, general_array, components_array, errors_array = build_metric_data_array(stats_hash)
25
+ def metric_data(stats_hash, base_quantile_hash)
26
+ action_array, adpex_array, general_array, components_array, errors_array = build_metric_data_array(stats_hash, base_quantile_hash)
26
27
 
27
28
  upload_data = {
28
29
  :type => 'perfMetrics',
@@ -35,7 +36,9 @@ module TingYun
35
36
  :general => general_array,
36
37
  :errors => errors_array
37
38
  }
39
+ upload_data.merge!(:config => {"nbs.quantile" => TingYun::Agent.config[:'nbs.quantile']}) if TingYun::Agent.config[:'nbs.quantile']
38
40
  result = invoke_remote(:upload, [upload_data])
41
+ self.quantile_cache = {}
39
42
  fill_metric_id_cache(result)
40
43
  result
41
44
  end
@@ -44,12 +47,15 @@ module TingYun
44
47
  # The collector wants to recieve metric data in a format that's different
45
48
  # # from how we store it inte -nally, so this method handles the translation.
46
49
  # # It also handles translating metric names to IDs using our metric ID cache.
47
- def build_metric_data_array(stats_hash)
50
+ def build_metric_data_array(stats_hash, base_quantile_hash)
48
51
  action_array = []
49
52
  adpex_array = []
50
53
  general_array = []
51
54
  components_array = []
52
55
  errors_array = []
56
+
57
+ calculate_quantile(base_quantile_hash.hash)
58
+
53
59
  stats_hash.each do |metric_spec, stats|
54
60
 
55
61
  # Omit empty stats as an optimization
@@ -57,17 +63,11 @@ module TingYun
57
63
  metric_id = metric_id_cache[metric_spec.hash]
58
64
 
59
65
  if metric_spec.name.start_with?('WebAction','BackgroundAction')
60
- action_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
66
+ action_array << generate_action(metric_spec, stats, metric_id)
61
67
  elsif metric_spec.name.start_with?('Apdex')
62
68
  adpex_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
63
69
  elsif metric_spec.name.start_with?('Errors') && metric_spec.scope.empty?
64
70
  errors_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
65
- elsif metric_spec.name.start_with?('Database','View','MongoDB','Redis','Memcached','External','Nested', 'CPU', 'Memory', 'WebFrontend','Rake')
66
- if metric_spec.scope.empty?
67
- general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
68
- else
69
- components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id) unless metric_spec.name.start_with?('External/NULL')
70
- end
71
71
  elsif metric_spec.name.start_with?('cross_app')
72
72
  external = metric_spec.name.split(';')
73
73
  if metric_spec.scope.empty?
@@ -79,14 +79,40 @@ module TingYun
79
79
  metric_spec.calleeName = external[2]
80
80
  components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
81
81
  end
82
-
82
+ else
83
+ if metric_spec.scope.empty?
84
+ general_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
85
+ else
86
+ components_array << TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id) unless metric_spec.name.start_with?('External/NULL')
87
+ end
83
88
  end
89
+
84
90
  end
85
91
  end
86
92
 
87
93
  [action_array, adpex_array, general_array, components_array, errors_array]
88
94
  end
89
95
 
96
+ def generate_action(metric_spec, stats, metric_id)
97
+ if !TingYun::Support::QuantileP2.support? || metric_spec.name.start_with?('BackgroundAction')
98
+ TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id)
99
+ else
100
+ quantile = self.quantile_cache[metric_spec.full_name] || []
101
+ TingYun::Metrics::MetricData.new(metric_spec, stats, metric_id, quantile)
102
+ end
103
+ end
104
+
105
+ def calculate_quantile(base)
106
+ if TingYun::Support::QuantileP2.support?
107
+ quantile = TingYun::Agent.config[:'nbs.quantile']
108
+ base.each do |action_name, base_list|
109
+ qm = TingYun::Support::QuantileP2.new(JSON.parse(quantile).map{|i| i.to_f/100})
110
+ base_list.each{ |l| qm.add(l) }
111
+ self.quantile_cache[action_name] = qm.markers
112
+ end
113
+ end
114
+ end
115
+
90
116
 
91
117
  # takes an array of arrays of spec and id, adds it into the
92
118
  # metric cache so we can save the collector some work by
@@ -29,7 +29,8 @@ module TingYun
29
29
  :metric_id_cache,
30
30
  :applicationId,
31
31
  :ssl_cert_store,
32
- :shared_tcp_connection
32
+ :shared_tcp_connection,
33
+ :quantile_cache
33
34
 
34
35
 
35
36
  def initialize(license_key=nil)
@@ -39,6 +40,7 @@ module TingYun
39
40
  @data_version = TingYun::VERSION::STRING
40
41
  @marshaller =TingYun::Support::Serialize::JsonMarshaller.new
41
42
  @metric_id_cache = {}
43
+ @quantile_cache = {}
42
44
  end
43
45
 
44
46
  def connect(settings={})
@@ -61,6 +63,7 @@ module TingYun
61
63
  @applicationId = nil
62
64
  @appSessionKey = nil
63
65
  @metric_id_cache = {}
66
+ @quantile_cache = {}
64
67
  close_shared_connection
65
68
  end
66
69
 
@@ -121,11 +124,5 @@ module TingYun
121
124
  raise error
122
125
  end
123
126
 
124
-
125
-
126
-
127
-
128
-
129
-
130
127
  end
131
128
  end
@@ -6,12 +6,14 @@ module TingYun
6
6
 
7
7
  MAJOR = 1
8
8
 
9
- MINOR = 2
9
+ MINOR = 3
10
10
 
11
11
  TINY = 0
12
12
 
13
13
 
14
14
 
15
+
16
+
15
17
  STRING = [MAJOR, MINOR, TINY].compact.join('.')
16
18
  end
17
19
  end
data/lib/tingyun_rpm.rb CHANGED
@@ -23,10 +23,8 @@
23
23
 
24
24
  require 'ting_yun/frameworks'
25
25
 
26
- # require 'pry'
27
26
  #if the agent had started in manual , then shouldn't start in auto again
28
27
 
29
-
30
28
  if defined?(Rails::VERSION)
31
29
  if Rails::VERSION::MAJOR.to_i >= 3
32
30
  module TingYun
@@ -48,5 +46,3 @@ if defined?(Rails::VERSION)
48
46
  else
49
47
  TingYun::Frameworks.init_start
50
48
  end
51
-
52
-
data/tingyun_rpm.gemspec CHANGED
@@ -25,12 +25,12 @@ Gem::Specification.new do |s|
25
25
  s.require_paths = ['lib']
26
26
  s.rubygems_version = Gem::VERSION
27
27
 
28
- s.add_development_dependency 'rake', '10.1.0'
28
+ s.add_development_dependency 'rake', '~> 10.1.0'
29
29
  s.add_development_dependency 'minitest', '~> 4.7'
30
- s.add_development_dependency 'minitest-ci', '= 2.4.0'
30
+ s.add_development_dependency 'minitest-ci', '~> 2.4.0'
31
31
  s.add_development_dependency 'minitest-focus', '~> 1.1'
32
32
  s.add_development_dependency 'minitest-reporters', '0.14.24'
33
- s.add_development_dependency 'simplecov', '= 0.10.0'
33
+ s.add_development_dependency 'simplecov', '~> 0.10.0'
34
34
  s.add_development_dependency 'mocha', '~> 0.13.0'
35
35
  s.add_development_dependency 'rails', '~> 3.2'
36
36
  s.add_development_dependency 'pry', '~> 0.9.12'
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tingyun_rpm
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - tingyun
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-08 00:00:00.000000000 Z
11
+ date: 2017-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - '='
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: 10.1.0
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - '='
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 10.1.0
27
27
  - !ruby/object:Gem::Dependency
@@ -42,14 +42,14 @@ dependencies:
42
42
  name: minitest-ci
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - '='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: 2.4.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - '='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 2.4.0
55
55
  - !ruby/object:Gem::Dependency
@@ -84,14 +84,14 @@ dependencies:
84
84
  name: simplecov
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - '='
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: 0.10.0
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - '='
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: 0.10.0
97
97
  - !ruby/object:Gem::Dependency
@@ -270,7 +270,6 @@ extra_rdoc_files: []
270
270
  files:
271
271
  - ".gitignore"
272
272
  - ".travis.yml"
273
- - CODE_OF_CONDUCT.md
274
273
  - Gemfile
275
274
  - Guardfile
276
275
  - LICENSE.txt
@@ -292,6 +291,7 @@ files:
292
291
  - lib/ting_yun/agent/collector/sql_sampler/sql_trace.rb
293
292
  - lib/ting_yun/agent/collector/sql_sampler/transaction_sql_data.rb
294
293
  - lib/ting_yun/agent/collector/stats_engine.rb
294
+ - lib/ting_yun/agent/collector/stats_engine/base_quantile_hash.rb
295
295
  - lib/ting_yun/agent/collector/stats_engine/metric_stats.rb
296
296
  - lib/ting_yun/agent/collector/stats_engine/stats_hash.rb
297
297
  - lib/ting_yun/agent/collector/transaction_sampler.rb
@@ -318,7 +318,6 @@ files:
318
318
  - lib/ting_yun/agent/instance_methods/handle_errors.rb
319
319
  - lib/ting_yun/agent/instance_methods/start.rb
320
320
  - lib/ting_yun/agent/instance_methods/start_worker_thread.rb
321
- - lib/ting_yun/agent/method_tracer.rb
322
321
  - lib/ting_yun/agent/method_tracer_helpers.rb
323
322
  - lib/ting_yun/agent/threading/agent_thread.rb
324
323
  - lib/ting_yun/agent/transaction.rb
@@ -352,11 +351,19 @@ files:
352
351
  - lib/ting_yun/frameworks/rails.rb
353
352
  - lib/ting_yun/frameworks/rails3.rb
354
353
  - lib/ting_yun/frameworks/rails4.rb
354
+ - lib/ting_yun/frameworks/rails5.rb
355
355
  - lib/ting_yun/frameworks/ruby.rb
356
356
  - lib/ting_yun/frameworks/sinatra.rb
357
357
  - lib/ting_yun/http/generic_request.rb
358
+ - lib/ting_yun/http/http_client_request.rb
358
359
  - lib/ting_yun/http/net_http_request.rb
359
360
  - lib/ting_yun/instrumentation/active_record.rb
361
+ - lib/ting_yun/instrumentation/bunny.rb
362
+ - lib/ting_yun/instrumentation/data_mapper.rb
363
+ - lib/ting_yun/instrumentation/grape.rb
364
+ - lib/ting_yun/instrumentation/http_client.rb
365
+ - lib/ting_yun/instrumentation/kafka.rb
366
+ - lib/ting_yun/instrumentation/memcached.rb
360
367
  - lib/ting_yun/instrumentation/middleware_proxy.rb
361
368
  - lib/ting_yun/instrumentation/middleware_tracing.rb
362
369
  - lib/ting_yun/instrumentation/mongo.rb
@@ -367,23 +374,37 @@ files:
367
374
  - lib/ting_yun/instrumentation/rack.rb
368
375
  - lib/ting_yun/instrumentation/rails3/action_controller.rb
369
376
  - lib/ting_yun/instrumentation/rails3/action_view.rb
370
- - lib/ting_yun/instrumentation/rails4/action_controller_subscriber.rb
371
- - lib/ting_yun/instrumentation/rails4/action_view_subscriber.rb
372
- - lib/ting_yun/instrumentation/rails4/active_record_subscriber.rb
377
+ - lib/ting_yun/instrumentation/rails4/action_controller.rb
378
+ - lib/ting_yun/instrumentation/rails4/action_view.rb
379
+ - lib/ting_yun/instrumentation/rails4/active_record.rb
380
+ - lib/ting_yun/instrumentation/rails5/action_cable.rb
381
+ - lib/ting_yun/instrumentation/rails5/action_controller.rb
382
+ - lib/ting_yun/instrumentation/rails5/action_view.rb
383
+ - lib/ting_yun/instrumentation/rails5/active_record.rb
373
384
  - lib/ting_yun/instrumentation/rails_middleware.rb
374
385
  - lib/ting_yun/instrumentation/rake.rb
375
386
  - lib/ting_yun/instrumentation/redis.rb
387
+ - lib/ting_yun/instrumentation/sidekiq.rb
388
+ - lib/ting_yun/instrumentation/sinatra/action.rb
389
+ - lib/ting_yun/instrumentation/sinatra/view.rb
390
+ - lib/ting_yun/instrumentation/support/action_cable_subscriber.rb
391
+ - lib/ting_yun/instrumentation/support/action_controller_subscriber.rb
392
+ - lib/ting_yun/instrumentation/support/action_view_subscriber.rb
376
393
  - lib/ting_yun/instrumentation/support/active_record_helper.rb
394
+ - lib/ting_yun/instrumentation/support/active_record_subscriber.rb
377
395
  - lib/ting_yun/instrumentation/support/controller_instrumentation.rb
378
396
  - lib/ting_yun/instrumentation/support/database.rb
379
397
  - lib/ting_yun/instrumentation/support/event_formatter.rb
380
398
  - lib/ting_yun/instrumentation/support/evented_subscriber.rb
381
399
  - lib/ting_yun/instrumentation/support/external_error.rb
400
+ - lib/ting_yun/instrumentation/support/external_helper.rb
382
401
  - lib/ting_yun/instrumentation/support/javascript_instrumentor.rb
402
+ - lib/ting_yun/instrumentation/support/method_instrumentation.rb
383
403
  - lib/ting_yun/instrumentation/support/metric_translator.rb
384
404
  - lib/ting_yun/instrumentation/support/mongo_formatter.rb
385
405
  - lib/ting_yun/instrumentation/support/parameter_filtering.rb
386
406
  - lib/ting_yun/instrumentation/support/queue_time.rb
407
+ - lib/ting_yun/instrumentation/support/sinatra_helper.rb
387
408
  - lib/ting_yun/instrumentation/support/split_controller.rb
388
409
  - lib/ting_yun/instrumentation/support/thrift_helper.rb
389
410
  - lib/ting_yun/instrumentation/support/transaction_namer.rb
@@ -412,6 +433,7 @@ files:
412
433
  - lib/ting_yun/support/library_detection.rb
413
434
  - lib/ting_yun/support/local_environment.rb
414
435
  - lib/ting_yun/support/path.rb
436
+ - lib/ting_yun/support/quantile_p2.rb
415
437
  - lib/ting_yun/support/serialize/encodes.rb
416
438
  - lib/ting_yun/support/serialize/encoding_normalizer.rb
417
439
  - lib/ting_yun/support/serialize/json_marshaller.rb
data/CODE_OF_CONDUCT.md DELETED
@@ -1,13 +0,0 @@
1
- # Contributor Code of Conduct
2
-
3
- As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
4
-
5
- We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.
6
-
7
- Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
8
-
9
- Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
10
-
11
- Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
12
-
13
- This Code of Conduct is adapted from the [Contributor Covenant](http://contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
@@ -1,256 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # This file may be independently required to set up method tracing prior to
4
- # the full agent loading. In those cases, we do need at least this require to
5
- # bootstrap things.
6
-
7
- require 'ting_yun/frameworks' unless defined?(TingYun::Frameworks::Framework)
8
- require 'ting_yun/support/helper'
9
- require 'ting_yun/agent/method_tracer_helpers'
10
-
11
- module TingYun
12
- module Agent
13
-
14
- # This module contains class methods added to support installing custom
15
- # metric tracers and executing for individual metrics.
16
- #
17
- # == Examples
18
- #
19
- # When the agent initializes, it extends Module with these methods.
20
- # However if you want to use the API in code that might get loaded
21
- # before the agent is initialized you will need to require
22
- # this file:
23
- #
24
- # require 'ting_yun/agent/method_tracer'
25
- # class A
26
- # include TingYun::Agent::MethodTracer
27
- # def process
28
- # ...
29
- # end
30
- # add_method_tracer :process
31
- # end
32
- #
33
- # To instrument a class method:
34
- #
35
- # require 'ting_yun/agent/method_tracer'
36
- # class An
37
- # def self.process
38
- # ...
39
- # end
40
- # class << self
41
- # include TingYun::Agent::MethodTracer
42
- # add_method_tracer :process
43
- # end
44
- # end
45
- #
46
- # @api public
47
- module MethodTracer
48
-
49
- def self.included klass
50
- klass.extend ClassMethods
51
- end
52
-
53
- def self.extended klass
54
- klass.extend ClassMethods
55
- end
56
-
57
-
58
- def self.trace_execution_scoped(metric_names, options={}, callback = nil) #THREAD_LOCAL_ACCESS
59
- TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(metric_names, options, callback) do
60
- # Using an implicit block avoids object allocation for a &block param
61
- yield
62
- end
63
- end
64
-
65
- # Defines methods used at the class level, for adding instrumentation
66
- # @api public
67
- module ClassMethods
68
-
69
- # contains methods refactored out of the #add_method_tracer method
70
- module AddMethodTracer
71
- # Checks to see if the method we are attempting to trace
72
- # actually exists or not. #add_method_tracer can't do
73
- # anything if the method doesn't exist.
74
- def _method_exists?(method_name)
75
- exists = method_defined?(method_name) || private_method_defined?(method_name)
76
- ::TingYun::Agent.logger.error("Did not trace #{self.name}##{method_name} because that method does not exist") unless exists
77
- exists
78
- end
79
-
80
- # Default to the class where the method is defined.
81
- #
82
- # Example:
83
- # Foo.default_metric_name_code('bar') #=> "Custom/#{Foo.name}/bar"
84
- def default_metric_name_code(method_name)
85
- "Custom/#{self.name}/#{method_name.to_s}"
86
- end
87
-
88
- # Checks to see if we have already traced a method with a
89
- # given metric by checking to see if the traced method
90
- # exists. Warns the user if methods are being double-traced
91
- # to help with debugging custom instrumentation.
92
- def traced_method_exists?(method_name, metric_name_code)
93
- exists = method_defined?(_traced_method_name(method_name, metric_name_code))
94
- ::TingYun::Agent.logger.error("Attempt to trace a method twice with the same metric: Method = #{method_name}, Metric Name = #{metric_name_code}") if exists
95
- exists
96
- end
97
-
98
- # Decides which code snippet we should be eval'ing in this
99
- # context, based on the options.
100
- def code_to_eval(method_name, metric_name_code, options)
101
- options = validate_options(method_name, options)
102
- if options[:push_scope]
103
- method_with_push_scope(method_name, metric_name_code, options)
104
- else
105
- method_without_push_scope(method_name, metric_name_code, options)
106
- end
107
- end
108
-
109
- # returns an eval-able string that contains the tracing code
110
- # for a fully traced metric including scoping
111
- def method_with_push_scope(method_name, metric_name_code, options)
112
- "def #{_traced_method_name(method_name, metric_name_code)}(*args, &block)
113
- #{options[:code_header]}
114
- result = ::TingYun::Agent::MethodTracerHelpers.trace_execution_scoped(\"#{metric_name_code}\",
115
- :metric => #{options[:metric]}) do
116
- #{_untraced_method_name(method_name, metric_name_code)}(*args, &block)
117
- end
118
- #{options[:code_footer]}
119
- result
120
- end"
121
- end
122
-
123
- # returns an eval-able string that contains the traced
124
- # method code used if the agent is not creating a scope for
125
- # use in scoped metrics.
126
- def method_without_push_scope(method_name, metric_name_code, options)
127
- "def #{_traced_method_name(method_name, metric_name_code)}(*args, &block)
128
- #{assemble_code_header(method_name, metric_name_code, options)}
129
- t0 = Time.now
130
- begin
131
- #{_untraced_method_name(method_name, metric_name_code)}(*args, &block)\n
132
- ensure
133
- duration = (Time.now - t0).to_f
134
- ::TingYun::Agent.record_metric(\"#{metric_name_code}\", duration)
135
- #{options[:code_footer]}
136
- end
137
- end"
138
- end
139
-
140
- # Returns a code snippet to be eval'd that skips tracing
141
- # when the agent is not tracing execution. turns
142
- # instrumentation into effectively one method call overhead
143
- # when the agent is disabled
144
- def assemble_code_header(method_name, metric_name_code, options)
145
- # header = "return #{_untraced_method_name(method_name, metric_name_code)}(*args, &block) unless TingYun::Agent.tl_is_execution_traced?\n"
146
- header += options[:code_header].to_s
147
- header
148
- end
149
-
150
-
151
-
152
- end
153
- include AddMethodTracer
154
-
155
-
156
- # Add a method tracer to the specified method.
157
- #
158
- # By default, this will cause invocations of the traced method to be
159
- # recorded in transaction traces, and in a metric named after the class
160
- # and method. It will also make the method show up in transaction-level
161
- # breakdown charts and tables.
162
- #
163
- # === Overriding the metric name
164
- #
165
- # +metric_name_code+ is a string that is eval'd to get the name of the
166
- # metric associated with the call, so if you want to use interpolation
167
- # evaluated at call time, then single quote the value like this:
168
- #
169
- # add_method_tracer :foo, 'Custom/#{self.class.name}/foo'
170
- #
171
- # This would name the metric according to the class of the runtime
172
- # intance, as opposed to the class where +foo+ is defined.
173
- #
174
- # If not provided, the metric name will be <tt>Custom/ClassName/method_name</tt>.
175
- #
176
- # @param [Symbol] method_name the name of the method to trace
177
- # @param [String] metric_name_code the metric name to record calls to
178
- # the traced method under. This may be either a static string, or Ruby
179
- # code to be evaluated at call-time in order to determine the metric
180
- # name dynamically.
181
- # @param [Hash] options additional options controlling how the method is
182
- # traced.
183
- # @option options [Boolean] :push_scope (true) If false, the traced method will
184
- # not appear in transaction traces or breakdown charts, and it will
185
- # only be visible in custom dashboards.
186
- # @option options [Boolean] :metric (true) If false, the traced method will
187
- # only appear in transaction traces, but no metrics will be recorded
188
- # for it.
189
- # @option options [String] :code_header ('') Ruby code to be inserted and run
190
- # before the tracer begins timing.
191
- # @option options [String] :code_footer ('') Ruby code to be inserted and run
192
- # after the tracer stops timing.
193
- #
194
- # @example
195
- # add_method_tracer :foo
196
- #
197
- # # With a custom metric name
198
- # add_method_tracer :foo, 'Custom/#{self.class.name}/foo'
199
- #
200
- # # Instrument foo only for custom dashboards (not in transaction
201
- # # traces or breakdown charts)
202
- # add_method_tracer :foo, 'Custom/foo', :push_scope => false
203
- #
204
- # # Instrument foo in transaction traces only
205
- # add_method_tracer :foo, 'Custom/foo', :metric => false
206
- #
207
- # @api public
208
- #
209
- def add_method_tracer(method_name, metric_name_code=nil, options = {})
210
- return unless _method_exists?(method_name)
211
- metric_name_code ||= default_metric_name_code(method_name)
212
- return if traced_method_exists?(method_name, metric_name_code)
213
-
214
- traced_method = code_to_eval(method_name, metric_name_code, options)
215
-
216
- visibility = TingYun::Support::Helper.instance_method_visibility self, method_name
217
-
218
- class_eval traced_method, __FILE__, __LINE__
219
- alias_method _untraced_method_name(method_name, metric_name_code), method_name
220
- alias_method method_name, _traced_method_name(method_name, metric_name_code)
221
- send visibility, method_name
222
- send visibility, _traced_method_name(method_name, metric_name_code)
223
- ::TingYun::Agent.logger.debug("Traced method: class = #{self.name},"+
224
- "method = #{method_name}, "+
225
- "metric = '#{metric_name_code}'")
226
- end
227
-
228
- private
229
-
230
- # given a method and a metric, this method returns the
231
- # untraced alias of the method name
232
- def _untraced_method_name(method_name, metric_name)
233
- "#{_sanitize_name(method_name)}_without_trace_#{_sanitize_name(metric_name)}"
234
- end
235
-
236
- # given a method and a metric, this method returns the traced
237
- # alias of the method name
238
- def _traced_method_name(method_name, metric_name)
239
- "#{_sanitize_name(method_name)}_with_trace_#{_sanitize_name(metric_name)}"
240
- end
241
-
242
- # makes sure that method names do not contain characters that
243
- # might break the interpreter, for example ! or ? characters
244
- # that are not allowed in the middle of method names
245
- def _sanitize_name(name)
246
- name.to_s.tr_s('^a-zA-Z0-9', '_')
247
- end
248
- end
249
-
250
-
251
- end
252
-
253
-
254
- end
255
- end
256
-