tingyun_rpm 1.0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.DS_Store +0 -0
  3. data/.gitignore +14 -0
  4. data/.travis.yml +4 -0
  5. data/CODE_OF_CONDUCT.md +13 -0
  6. data/Gemfile +3 -0
  7. data/Guardfile +25 -0
  8. data/LICENSE.txt +22 -0
  9. data/README.md +41 -0
  10. data/cert/cacert.pem +0 -0
  11. data/lib/ting_yun/agent/agent.rb +128 -0
  12. data/lib/ting_yun/agent/class_methods.rb +21 -0
  13. data/lib/ting_yun/agent/collector/base_sampler.rb +2 -0
  14. data/lib/ting_yun/agent/collector/error_collector/error_trace_array.rb +88 -0
  15. data/lib/ting_yun/agent/collector/error_collector/noticed_error.rb +129 -0
  16. data/lib/ting_yun/agent/collector/error_collector.rb +165 -0
  17. data/lib/ting_yun/agent/collector/middle_ware_collector/cpu_sampler.rb +68 -0
  18. data/lib/ting_yun/agent/collector/middle_ware_collector/memory_sampler.rb +139 -0
  19. data/lib/ting_yun/agent/collector/middle_ware_collector/middle_ware.rb +13 -0
  20. data/lib/ting_yun/agent/collector/middle_ware_collector/sampler.rb +59 -0
  21. data/lib/ting_yun/agent/collector/middle_ware_collector.rb +80 -0
  22. data/lib/ting_yun/agent/collector/sql_sampler.rb +299 -0
  23. data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +170 -0
  24. data/lib/ting_yun/agent/collector/stats_engine/stats_hash.rb +172 -0
  25. data/lib/ting_yun/agent/collector/stats_engine.rb +28 -0
  26. data/lib/ting_yun/agent/collector/transaction_sampler/slowest_sample_buffer.rb +25 -0
  27. data/lib/ting_yun/agent/collector/transaction_sampler/transaction_sample_buffer_base.rb +96 -0
  28. data/lib/ting_yun/agent/collector/transaction_sampler.rb +226 -0
  29. data/lib/ting_yun/agent/container_data_manager.rb +94 -0
  30. data/lib/ting_yun/agent/cross_app/cross_app_monitor.rb +131 -0
  31. data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +202 -0
  32. data/lib/ting_yun/agent/cross_app/inbound_request_monitor.rb +22 -0
  33. data/lib/ting_yun/agent/database.rb +410 -0
  34. data/lib/ting_yun/agent/datastore/metric_helper.rb +82 -0
  35. data/lib/ting_yun/agent/datastore/mongo.rb +44 -0
  36. data/lib/ting_yun/agent/datastore.rb +33 -0
  37. data/lib/ting_yun/agent/dispatcher.rb +39 -0
  38. data/lib/ting_yun/agent/event/event_listener.rb +47 -0
  39. data/lib/ting_yun/agent/event/event_loop.rb +194 -0
  40. data/lib/ting_yun/agent/instance_methods/connect.rb +164 -0
  41. data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +137 -0
  42. data/lib/ting_yun/agent/instance_methods/handle_errors.rb +71 -0
  43. data/lib/ting_yun/agent/instance_methods/start.rb +219 -0
  44. data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +51 -0
  45. data/lib/ting_yun/agent/instance_methods.rb +39 -0
  46. data/lib/ting_yun/agent/method_tracer.rb +256 -0
  47. data/lib/ting_yun/agent/method_tracer_helpers.rb +85 -0
  48. data/lib/ting_yun/agent/threading/agent_thread.rb +49 -0
  49. data/lib/ting_yun/agent/transaction/attributes.rb +22 -0
  50. data/lib/ting_yun/agent/transaction/request_attributes.rb +126 -0
  51. data/lib/ting_yun/agent/transaction/trace.rb +125 -0
  52. data/lib/ting_yun/agent/transaction/trace_node.rb +110 -0
  53. data/lib/ting_yun/agent/transaction/traced_method_stack.rb +80 -0
  54. data/lib/ting_yun/agent/transaction/transaction_metrics.rb +51 -0
  55. data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +63 -0
  56. data/lib/ting_yun/agent/transaction/transaction_state.rb +112 -0
  57. data/lib/ting_yun/agent/transaction.rb +522 -0
  58. data/lib/ting_yun/agent.rb +207 -0
  59. data/lib/ting_yun/configuration/default_source.rb +638 -0
  60. data/lib/ting_yun/configuration/dotted_hash.rb +46 -0
  61. data/lib/ting_yun/configuration/environment_source.rb +116 -0
  62. data/lib/ting_yun/configuration/manager.rb +232 -0
  63. data/lib/ting_yun/configuration/manual_source.rb +14 -0
  64. data/lib/ting_yun/configuration/server_source.rb +88 -0
  65. data/lib/ting_yun/configuration/yaml_source.rb +136 -0
  66. data/lib/ting_yun/configuration.rb +9 -0
  67. data/lib/ting_yun/environment_report.rb +123 -0
  68. data/lib/ting_yun/frameworks/class_methods.rb +47 -0
  69. data/lib/ting_yun/frameworks/external.rb +15 -0
  70. data/lib/ting_yun/frameworks/instance_methods.rb +120 -0
  71. data/lib/ting_yun/frameworks/instrumentation.rb +67 -0
  72. data/lib/ting_yun/frameworks/rails.rb +63 -0
  73. data/lib/ting_yun/frameworks/rails3.rb +26 -0
  74. data/lib/ting_yun/frameworks/rails4.rb +14 -0
  75. data/lib/ting_yun/frameworks/ruby.rb +17 -0
  76. data/lib/ting_yun/frameworks/sinatra.rb +10 -0
  77. data/lib/ting_yun/frameworks.rb +34 -0
  78. data/lib/ting_yun/http/generic_request.rb +8 -0
  79. data/lib/ting_yun/http/net_http_request.rb +46 -0
  80. data/lib/ting_yun/instrumentation/active_record.rb +103 -0
  81. data/lib/ting_yun/instrumentation/middleware_proxy.rb +77 -0
  82. data/lib/ting_yun/instrumentation/middleware_tracing.rb +84 -0
  83. data/lib/ting_yun/instrumentation/mongo.rb +103 -0
  84. data/lib/ting_yun/instrumentation/mongo2.rb +37 -0
  85. data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +97 -0
  86. data/lib/ting_yun/instrumentation/moped.rb +95 -0
  87. data/lib/ting_yun/instrumentation/net.rb +59 -0
  88. data/lib/ting_yun/instrumentation/rack.rb +109 -0
  89. data/lib/ting_yun/instrumentation/rails3/action_controller.rb +63 -0
  90. data/lib/ting_yun/instrumentation/rails3/action_view.rb +115 -0
  91. data/lib/ting_yun/instrumentation/rails4/action_controller_subscriber.rb +124 -0
  92. data/lib/ting_yun/instrumentation/rails4/action_view_subscriber.rb +118 -0
  93. data/lib/ting_yun/instrumentation/rails4/active_record_subscriber.rb +124 -0
  94. data/lib/ting_yun/instrumentation/rails_middleware.rb +38 -0
  95. data/lib/ting_yun/instrumentation/redis.rb +70 -0
  96. data/lib/ting_yun/instrumentation/support/active_record_helper.rb +178 -0
  97. data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +54 -0
  98. data/lib/ting_yun/instrumentation/support/database.rb +38 -0
  99. data/lib/ting_yun/instrumentation/support/event_formatter.rb +19 -0
  100. data/lib/ting_yun/instrumentation/support/evented_subscriber.rb +97 -0
  101. data/lib/ting_yun/instrumentation/support/external_error.rb +52 -0
  102. data/lib/ting_yun/instrumentation/support/metric_translator.rb +84 -0
  103. data/lib/ting_yun/instrumentation/support/mongo_formatter.rb +49 -0
  104. data/lib/ting_yun/instrumentation/support/parameter_filtering.rb +21 -0
  105. data/lib/ting_yun/instrumentation/support/queue_time.rb +76 -0
  106. data/lib/ting_yun/instrumentation/support/transaction_namer.rb +68 -0
  107. data/lib/ting_yun/instrumentation/thrift.rb +329 -0
  108. data/lib/ting_yun/logger/agent_logger.rb +196 -0
  109. data/lib/ting_yun/logger/log_once.rb +38 -0
  110. data/lib/ting_yun/logger/memory_logger.rb +56 -0
  111. data/lib/ting_yun/logger/null_logger.rb +31 -0
  112. data/lib/ting_yun/logger/startup_logger.rb +13 -0
  113. data/lib/ting_yun/logger.rb +8 -0
  114. data/lib/ting_yun/metrics/metric_data.rb +86 -0
  115. data/lib/ting_yun/metrics/metric_spec.rb +89 -0
  116. data/lib/ting_yun/metrics/stats.rb +158 -0
  117. data/lib/ting_yun/metrics.rb +12 -0
  118. data/lib/ting_yun/support/coerce.rb +86 -0
  119. data/lib/ting_yun/support/collector.rb +29 -0
  120. data/lib/ting_yun/support/exception.rb +79 -0
  121. data/lib/ting_yun/support/hash_extensions.rb +25 -0
  122. data/lib/ting_yun/support/helper.rb +54 -0
  123. data/lib/ting_yun/support/hostname.rb +13 -0
  124. data/lib/ting_yun/support/http_clients/uri_util.rb +49 -0
  125. data/lib/ting_yun/support/language_support.rb +155 -0
  126. data/lib/ting_yun/support/library_detection.rb +129 -0
  127. data/lib/ting_yun/support/local_environment.rb +185 -0
  128. data/lib/ting_yun/support/path.rb +13 -0
  129. data/lib/ting_yun/support/serialize/encodes.rb +61 -0
  130. data/lib/ting_yun/support/serialize/encoding_normalizer.rb +84 -0
  131. data/lib/ting_yun/support/serialize/json_marshaller.rb +73 -0
  132. data/lib/ting_yun/support/serialize/json_wrapper.rb +78 -0
  133. data/lib/ting_yun/support/serialize/marshaller.rb +69 -0
  134. data/lib/ting_yun/support/serialize/ok_json.rb +651 -0
  135. data/lib/ting_yun/support/system_info.rb +206 -0
  136. data/lib/ting_yun/support/timer_lib.rb +29 -0
  137. data/lib/ting_yun/support/version_number.rb +70 -0
  138. data/lib/ting_yun/ting_yun_service/connection.rb +118 -0
  139. data/lib/ting_yun/ting_yun_service/http.rb +41 -0
  140. data/lib/ting_yun/ting_yun_service/request.rb +90 -0
  141. data/lib/ting_yun/ting_yun_service/ssl.rb +45 -0
  142. data/lib/ting_yun/ting_yun_service/upload_service.rb +149 -0
  143. data/lib/ting_yun/ting_yun_service.rb +124 -0
  144. data/lib/ting_yun/version.rb +17 -0
  145. data/lib/tingyun_rpm.rb +47 -0
  146. data/tingyun_rpm.gemspec +60 -0
  147. metadata +415 -0
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/agent'
4
+ require 'ting_yun/agent/transaction/transaction_state'
5
+ require 'ting_yun/instrumentation/support/active_record_helper'
6
+ require 'ting_yun/support/helper'
7
+ require 'ting_yun/agent/method_tracer'
8
+
9
+
10
+ module TingYun
11
+ module Instrumentation
12
+ module ActiveRecord
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
22
+ end
23
+
24
+ def self.included(instrumented_class)
25
+ instrumented_class.class_eval do
26
+ unless instrumented_class.method_defined?(:log_without_tingyun_instrumentation)
27
+ alias_method :log_without_tingyun_instrumentation, :log
28
+ alias_method :log, :log_with_tingyun_instrumentation
29
+ protected :log
30
+ end
31
+ end
32
+ end
33
+
34
+ def self.instrument
35
+ if defined?(::ActiveRecord::VERSION::MAJOR) && ::ActiveRecord::VERSION::MAJOR.to_i >= 3
36
+ ::TingYun::Instrumentation::Support::ActiveRecordHelper.instrument_additional_methods
37
+ end
38
+
39
+ ::ActiveRecord::ConnectionAdapters::AbstractAdapter.module_eval do
40
+ include ::TingYun::Instrumentation::ActiveRecord
41
+ end
42
+ end
43
+
44
+ def log_with_tingyun_instrumentation(*args, &block)
45
+
46
+ state = TingYun::Agent::TransactionState.tl_get
47
+ sql, name, _ = args
48
+ metrics = ::TingYun::Instrumentation::Support::ActiveRecordHelper.metrics_for(
49
+ TingYun::Helper.correctly_encoded(name),
50
+ TingYun::Helper.correctly_encoded(sql),
51
+ @config && @config[:adapter])
52
+
53
+ scoped_metric = metrics.first
54
+
55
+ TingYun::Agent::MethodTracer.trace_execution_scoped(metrics) do
56
+ t0 = Time.now
57
+ begin
58
+ log_without_tingyun_instrumentation(*args, &block)
59
+ ensure
60
+ elapsed_time = (Time.now - t0).to_f
61
+ state.sql_duration = elapsed_time * 1000
62
+
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)
68
+ end
69
+
70
+ end
71
+ end
72
+
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ TingYun::Support::LibraryDetection.defer do
79
+ named :active_record
80
+
81
+ depends_on do
82
+ defined?(::ActiveRecord) && defined?(::ActiveRecord::Base) &&
83
+ (!defined?(::ActiveRecord::VERSION) ||
84
+ ::ActiveRecord::VERSION::MAJOR.to_i <= 3)
85
+ end
86
+
87
+ executes do
88
+ ::TingYun::Agent.logger.info 'Installing ActiveRecord instrumentation'
89
+ end
90
+
91
+ executes do
92
+ require 'ting_yun/instrumentation/support/active_record_helper'
93
+
94
+ if defined?(::Rails) && ::Rails::VERSION::MAJOR.to_i == 3
95
+ ActiveSupport.on_load(:active_record) do
96
+ ::TingYun::Instrumentation::ActiveRecord.instrument
97
+ end
98
+ else
99
+ ::TingYun::Instrumentation::ActiveRecord.instrument
100
+ end
101
+ end
102
+
103
+ end
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+ require 'ting_yun/instrumentation/middleware_tracing'
3
+ require 'ting_yun/instrumentation/support/transaction_namer'
4
+
5
+ module TingYun
6
+ module Instrumentation
7
+ class MiddlewareProxy
8
+ include TingYun::Instrumentation::MiddlewareTracing
9
+
10
+
11
+
12
+ def self.is_sinatra_app?(target)
13
+ defined?(::Sinatra::Base) && target.kind_of?(::Sinatra::Base)
14
+ end
15
+
16
+ def self.needs_wrapping?(target)
17
+ (
18
+ !target.respond_to?(:_nr_has_middleware_tracing) &&
19
+ !is_sinatra_app?(target)
20
+ )
21
+ end
22
+
23
+ def self.wrap(target, is_app=false)
24
+ if needs_wrapping?(target)
25
+ self.new(target, is_app)
26
+ else
27
+ target
28
+ end
29
+ end
30
+
31
+
32
+ attr_reader :target, :category, :transaction_options
33
+
34
+ def initialize(target, is_app=false)
35
+ @target = target
36
+ @is_app = is_app
37
+ @category = determine_category
38
+ @target_class_name = determine_class_name
39
+ @transaction_name = "#{determine_prefix}#{@target_class_name}/call"
40
+ @transaction_options = {
41
+ :transaction_name => @transaction_name
42
+ }
43
+ end
44
+
45
+
46
+ def determine_category
47
+ if @is_app
48
+ :rack
49
+ else
50
+ :middleware
51
+ end
52
+ end
53
+
54
+ def determine_prefix
55
+ TingYun::Instrumentation::Support::TransactionNamer.prefix_for_category(nil,@category)
56
+ end
57
+
58
+ def determine_class_name
59
+ clazz = class_for_target
60
+
61
+ name = clazz.name
62
+ name = clazz.superclass.name if name.nil? || name == ""
63
+ name
64
+ end
65
+
66
+ def class_for_target
67
+ if @target.is_a?(Class)
68
+ @target
69
+ else
70
+ @target.class
71
+ end
72
+ end
73
+
74
+ end
75
+ end
76
+ end
77
+
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/agent/transaction/transaction_state'
4
+ require 'rack/request'
5
+ require 'ting_yun/instrumentation/support/queue_time'
6
+ require 'ting_yun/agent/transaction'
7
+ require 'ting_yun/agent'
8
+ require 'ting_yun/instrumentation/support/external_error'
9
+
10
+ module TingYun
11
+ module Instrumentation
12
+ module MiddlewareTracing
13
+ TXN_STARTED_KEY = 'tingyun.transaction_started'.freeze unless defined?(TXN_STARTED_KEY)
14
+
15
+ def _nr_has_middleware_tracing
16
+ true
17
+ end
18
+
19
+ def build_transaction_options(env, first_middleware)
20
+ opts = transaction_options
21
+ opts = merge_first_middleware_options(opts, env) if first_middleware
22
+ opts
23
+ end
24
+
25
+ def merge_first_middleware_options(opts, env)
26
+ opts.merge(
27
+ :request => ::Rack::Request.new(env),
28
+ :apdex_start_time => TingYun::Instrumentation::Support::QueueTime.parse_frontend_timestamp(env)
29
+ )
30
+ end
31
+
32
+ def capture_http_response_code(state, result)
33
+ if result.is_a?(Array) && state.current_transaction
34
+ state.current_transaction.http_response_code = result[0]
35
+ end
36
+ end
37
+ # the trailing unless is for the benefit for Ruby 1.8.7 and can be removed
38
+ # when it is deprecated.
39
+ CONTENT_TYPE = 'Content-Type'.freeze unless defined?(CONTENT_TYPE)
40
+
41
+ def capture_response_content_type(state, result)
42
+ if result.is_a?(Array) && state.current_transaction
43
+ _, headers, _ = result
44
+ state.current_transaction.response_content_type = headers[CONTENT_TYPE]
45
+ end
46
+ end
47
+
48
+ def call(env)
49
+ first_middleware = note_transaction_started(env)
50
+
51
+ state = TingYun::Agent::TransactionState.tl_get
52
+ begin
53
+ TingYun::Agent::Transaction.start(state, category, build_transaction_options(env, first_middleware))
54
+ events.notify(:before_call, env) if first_middleware
55
+
56
+ result = target.call(env)
57
+
58
+ if first_middleware
59
+ capture_http_response_code(state, result)
60
+ capture_response_content_type(state, result)
61
+ events.notify(:after_call, result)
62
+ end
63
+
64
+ result
65
+ rescue Exception => e
66
+
67
+ TingYun::Agent.notice_error(e)
68
+ raise e
69
+ ensure
70
+ TingYun::Agent::Transaction.stop(state)
71
+ end
72
+ end
73
+
74
+
75
+ def note_transaction_started(env)
76
+ env[TXN_STARTED_KEY] = true unless env[TXN_STARTED_KEY]
77
+ end
78
+
79
+ def events
80
+ ::TingYun::Agent.instance.events
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,103 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/agent'
4
+ require 'ting_yun/instrumentation/support/metric_translator'
5
+
6
+ module TingYun
7
+ module Instrumentation
8
+ module Mongo
9
+ extend self
10
+
11
+ def install_mongo_instrumentation
12
+ hook_instrument_methods
13
+ instrument_save
14
+ instrument_ensure_index
15
+ end
16
+
17
+ def hook_instrument_methods
18
+ hook_instrument_method(::Mongo::Collection)
19
+ hook_instrument_method(::Mongo::Connection)
20
+ hook_instrument_method(::Mongo::Cursor)
21
+ hook_instrument_method(::Mongo::CollectionWriter) if defined?(::Mongo::CollectionWriter)
22
+ end
23
+
24
+
25
+ def hook_instrument_method(target_class)
26
+ target_class.class_eval do
27
+ require 'ting_yun/agent/method_tracer'
28
+
29
+ def record_mongo_duration(duration)
30
+ state = TingYun::Agent::TransactionState.tl_get
31
+ unless state.nil?
32
+ state.mon_duration += duration * 1000
33
+ end
34
+ end
35
+
36
+ def ting_yun_generate_metrics(operation, payload = nil)
37
+ payload ||= { :collection => self.name, :database => self.db.name }
38
+ TingYun::Instrumentation::Support::MetricTranslator.metrics_for(operation, payload)
39
+ end
40
+
41
+ def instrument_with_ting_yun_trace(name, payload = {}, &block)
42
+ metrics = ting_yun_generate_metrics(name, payload)
43
+
44
+ TingYun::Agent::MethodTracer.trace_execution_scoped(metrics, payload, method(:record_mongo_duration)) do
45
+ instrument_without_ting_yun_trace(name, payload, &block)
46
+ end
47
+ end
48
+
49
+ alias_method :instrument_without_ting_yun_trace, :instrument
50
+ alias_method :instrument, :instrument_with_ting_yun_trace
51
+ end
52
+ end
53
+
54
+ def instrument_save
55
+ ::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)
60
+ end
61
+ end
62
+
63
+ alias_method :save_without_ting_yun_trace, :save
64
+ alias_method :save, :save_with_ting_yun_trace
65
+ end
66
+ end
67
+
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)
74
+ end
75
+ end
76
+
77
+ alias_method :ensure_index_with_out_ting_yun_trace, :ensure_index
78
+ alias_method :ensure_index, :ensure_index_with_ting_yun_trace
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ TingYun::Support::LibraryDetection.defer do
86
+ named :mongo
87
+
88
+ depends_on do
89
+ defined?(::Mongo)
90
+ end
91
+
92
+ depends_on do
93
+ TingYun::Agent::Datastore::Mongo.supported_version? && !TingYun::Agent::Datastore::Mongo.unsupported_2x?
94
+ end
95
+
96
+ executes do
97
+ TingYun::Agent.logger.info 'Installing Mongo instrumentation'
98
+ end
99
+
100
+ executes do
101
+ TingYun::Instrumentation::Mongo.install_mongo_instrumentation
102
+ end
103
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/agent'
4
+ require 'ting_yun/agent/method_tracer'
5
+
6
+ module TingYun
7
+ module Instrumentation
8
+ module Mongo2
9
+ def self.install_mongo_command_log_subscriber
10
+ require 'ting_yun/instrumentation/mongo_command_log_subscriber'
11
+ ::Mongo::Monitoring::Global.subscribe(
12
+ ::Mongo::Monitoring::COMMAND,
13
+ TingYun::Instrumentation::MongoCommandLogSubscriber.new
14
+ )
15
+ end
16
+ end
17
+ end
18
+ end
19
+
20
+
21
+
22
+ TingYun::Support::LibraryDetection.defer do
23
+ named :mongo2
24
+
25
+ depends_on do
26
+ require 'ting_yun/agent/datastore/mongo'
27
+ defined?(::Mongo) && TingYun::Agent::Datastore::Mongo.unsupported_2x? && defined?(::Mongo::Monitoring::Global)
28
+ end
29
+
30
+ executes do
31
+ TingYun::Agent.logger.info 'Installing Mongo2 instrumentation'
32
+ end
33
+
34
+ executes do
35
+ TingYun::Instrumentation::Mongo2.install_mongo_command_log_subscriber
36
+ end
37
+ end
@@ -0,0 +1,97 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/agent'
4
+ require 'ting_yun/agent/transaction/transaction_state'
5
+ require 'ting_yun/agent/datastore/metric_helper'
6
+ require 'ting_yun/agent/datastore/mongo'
7
+ require 'ting_yun/instrumentation/support/event_formatter'
8
+
9
+
10
+ module TingYun
11
+ module Instrumentation
12
+ class MongoCommandLogSubscriber
13
+
14
+ MONGODB = 'MongoDB'.freeze
15
+ GET_MORE = "getMore".freeze
16
+ COLLECTION = "collection".freeze
17
+
18
+ def started(event)
19
+ begin
20
+ operations[event.operation_id] = event
21
+ rescue Exception => e
22
+ log_notification_error('started', e)
23
+ end
24
+ end
25
+
26
+
27
+ def completed(event)
28
+ begin
29
+ state = TingYun::Agent::TransactionState.tl_get
30
+ state.mon_duration = event.duration*1000
31
+ started_event = operations.delete(event.operation_id)
32
+
33
+ base, *other_metrics = metrics(started_event)
34
+
35
+ TingYun::Agent.instance.stats_engine.tl_record_scoped_and_unscoped_metrics(
36
+ base, other_metrics, event.duration*1000
37
+ )
38
+ notice_nosql_statement(state, started_event, base, event.duration)
39
+ rescue Exception => e
40
+ log_notification_error('completed', e)
41
+ end
42
+ end
43
+
44
+ alias :succeeded :completed
45
+ alias :failed :completed
46
+
47
+
48
+
49
+
50
+ private
51
+
52
+ def collection(event)
53
+ if event.command_name == GET_MORE
54
+ event.command[COLLECTION]
55
+ else
56
+ event.command.values.first
57
+ end
58
+ end
59
+
60
+ def log_notification_error(event_type, error)
61
+ TingYun::Agent.logger.error("Error during MongoDB #{event_type} event:")
62
+ TingYun::Agent.logger.log_exception(:error, error)
63
+ end
64
+
65
+
66
+ def operations
67
+ @operations ||= {}
68
+ end
69
+
70
+ def metrics(event)
71
+ TingYun::Agent::Datastore::MetricHelper.metrics_for(MONGODB, TingYun::Agent::Datastore::Mongo.transform_operation(event.command_name), collection(event))
72
+ end
73
+
74
+ def generate_statement(event)
75
+ TingYun::Instrumentation::Support::EventFormatter.format(
76
+ event.command_name,
77
+ event.database_name,
78
+ event.command
79
+ )
80
+ end
81
+
82
+ def notice_nosql_statement(state, event, metric, duration)
83
+ end_time = Time.now.to_f
84
+
85
+ stack = state.traced_method_stack
86
+
87
+ # enter transaction trace node
88
+ frame = stack.push_frame(state, :mongo_db, end_time - duration)
89
+
90
+ TingYun::Agent.instance.transaction_sampler.notice_nosql_statement(generate_statement(event),duration*1000)
91
+
92
+ # exit transaction trace node
93
+ stack.pop_frame(state, frame, metric, end_time)
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,95 @@
1
+ # encoding: utf-8
2
+
3
+ require 'ting_yun/agent'
4
+ require 'ting_yun/agent/datastore'
5
+ require 'ting_yun/agent/datastore/mongo'
6
+ require 'ting_yun/agent/transaction/transaction_state'
7
+
8
+ module TingYun
9
+ module Instrumentation
10
+ module Moped
11
+
12
+ MONGODB = 'MongoDB'.freeze
13
+
14
+ def self.included(instrumented_class)
15
+ instrumented_class.class_eval do
16
+ unless instrumented_class.method_defined?(:log_without_tingyun_instrumentation)
17
+ alias_method :log_without_tingyun_instrumentation, :logging
18
+ alias_method :logging, :log_with_tingyun_instrumentation
19
+ end
20
+ end
21
+ end
22
+
23
+ def self.instrument
24
+ ::Moped::Node.class_eval do
25
+ include ::TingYun::Instrumentation::Moped
26
+ end
27
+ end
28
+
29
+
30
+ def log_with_tingyun_instrumentation(operations, &blk)
31
+ operation_name, collection = determine_operation_and_collection(operations.first)
32
+ operation = TingYun::Agent::Datastore::Mongo.transform_operation(operation_name)
33
+
34
+ res = nil
35
+ TingYun::Agent::Datastore.wrap(MONGODB, operation, collection, method(:record_mongo_duration)) do
36
+ res = log_without_tingyun_instrumentation(operations, &blk)
37
+ end
38
+
39
+ res
40
+ end
41
+
42
+ def determine_operation_and_collection(operation)
43
+ log_statement = operation.log_inspect.encode("UTF-8")
44
+
45
+ collection = operation.collection if operation.respond_to?(:collection)
46
+
47
+ operation_name = log_statement.split[0]
48
+ if operation_name == 'COMMAND' && log_statement.include?(":mapreduce")
49
+ operation_name = 'MAPREDUCE'
50
+ collection = log_statement[/:mapreduce=>"([^"]+)/,1]
51
+ elsif operation_name == 'COMMAND' && log_statement.include?(":count")
52
+ operation_name = 'COUNT'
53
+ collection = log_statement[/:count=>"([^"]+)/,1]
54
+ elsif operation_name == 'COMMAND' && log_statement.include?(":aggregate")
55
+ operation_name = 'AGGREGATE'
56
+ collection = log_statement[/:aggregate=>"([^"]+)/,1]
57
+ elsif operation_name == 'COMMAND' && log_statement.include?(":findAndModify")
58
+ operation_name = 'FIND_AND_MODIFY'
59
+ collection = log_statement[/:findAndModify=>"([^"]+)/,1]
60
+ end
61
+ return operation_name, collection
62
+ end
63
+
64
+ def record_mongo_duration(_1, _2, duration)
65
+ state = TingYun::Agent::TransactionState.tl_get
66
+ unless state.nil?
67
+ state.mon_duration += duration * 1000
68
+ end
69
+ end
70
+
71
+ end
72
+ end
73
+ end
74
+
75
+
76
+
77
+
78
+
79
+
80
+
81
+ TingYun::Support::LibraryDetection.defer do
82
+ named :mongo_moped
83
+ depends_on do
84
+ defined?(::Moped)
85
+ end
86
+
87
+ executes do
88
+ TingYun::Agent.logger.info 'Installing Mongo Moped instrumentation'
89
+ end
90
+
91
+ executes do
92
+ ::TingYun::Instrumentation::Moped.instrument
93
+ end
94
+ end
95
+
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+
3
+ TingYun::Support::LibraryDetection.defer do
4
+
5
+ named :net_http
6
+
7
+ depends_on do
8
+ defined?(Net) && defined?(Net::HTTP)
9
+ end
10
+
11
+ executes do
12
+ ::TingYun::Agent.logger.info 'Installing Net instrumentation'
13
+ require 'ting_yun/agent/cross_app/cross_app_tracing'
14
+ require 'ting_yun/http/net_http_request'
15
+ require 'ting_yun/instrumentation/support/external_error'
16
+ end
17
+
18
+ executes do
19
+ class Net::HTTP
20
+ def request_with_tingyun_trace(request, *args, &block)
21
+ tingyun_request = TingYun::Http::NetHttpRequest.new(self, request)
22
+
23
+ TingYun::Agent::CrossAppTracing.tl_trace_http_request(tingyun_request) do
24
+ TingYun::Agent.disable_all_tracing do
25
+ request_without_tingyun_trace(request, *args, &block )
26
+ end
27
+ end
28
+ end
29
+
30
+ alias :request_without_tingyun_trace :request
31
+ alias :request :request_with_tingyun_trace
32
+
33
+
34
+ class << self
35
+ def get_response_with_tingyun(uri_or_host, path = nil, port = nil, &block)
36
+ begin
37
+ get_response_without_tingyun(uri_or_host, path = nil, port = nil, &block)
38
+ rescue => e
39
+ klass = "External/#{uri_or_host.to_s.gsub('/','%2F')}/net%2Fhttp"
40
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e,klass)
41
+ end
42
+ end
43
+ alias get_response_without_tingyun get_response
44
+ alias get_response get_response_with_tingyun
45
+
46
+ def start_with_tingyun(address, *arg, &block)
47
+ begin
48
+ start_without_tingyun(address, *arg, &block)
49
+ rescue => e
50
+ klass = "External/#{address.to_s.gsub('/','%2F')}/net%2Fhttp"
51
+ ::TingYun::Instrumentation::Support::ExternalError.handle_error(e,klass)
52
+ end
53
+ end
54
+ alias :start_without_tingyun :start
55
+ alias :start :start_with_tingyun
56
+ end
57
+ end
58
+ end
59
+ end