tingyun_rpm 1.0.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.DS_Store +0 -0
- data/.gitignore +14 -0
- data/.travis.yml +4 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +3 -0
- data/Guardfile +25 -0
- data/LICENSE.txt +22 -0
- data/README.md +41 -0
- data/cert/cacert.pem +0 -0
- data/lib/ting_yun/agent/agent.rb +128 -0
- data/lib/ting_yun/agent/class_methods.rb +21 -0
- data/lib/ting_yun/agent/collector/base_sampler.rb +2 -0
- data/lib/ting_yun/agent/collector/error_collector/error_trace_array.rb +88 -0
- data/lib/ting_yun/agent/collector/error_collector/noticed_error.rb +129 -0
- data/lib/ting_yun/agent/collector/error_collector.rb +165 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/cpu_sampler.rb +68 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/memory_sampler.rb +139 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/middle_ware.rb +13 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector/sampler.rb +59 -0
- data/lib/ting_yun/agent/collector/middle_ware_collector.rb +80 -0
- data/lib/ting_yun/agent/collector/sql_sampler.rb +299 -0
- data/lib/ting_yun/agent/collector/stats_engine/metric_stats.rb +170 -0
- data/lib/ting_yun/agent/collector/stats_engine/stats_hash.rb +172 -0
- data/lib/ting_yun/agent/collector/stats_engine.rb +28 -0
- data/lib/ting_yun/agent/collector/transaction_sampler/slowest_sample_buffer.rb +25 -0
- data/lib/ting_yun/agent/collector/transaction_sampler/transaction_sample_buffer_base.rb +96 -0
- data/lib/ting_yun/agent/collector/transaction_sampler.rb +226 -0
- data/lib/ting_yun/agent/container_data_manager.rb +94 -0
- data/lib/ting_yun/agent/cross_app/cross_app_monitor.rb +131 -0
- data/lib/ting_yun/agent/cross_app/cross_app_tracing.rb +202 -0
- data/lib/ting_yun/agent/cross_app/inbound_request_monitor.rb +22 -0
- data/lib/ting_yun/agent/database.rb +410 -0
- data/lib/ting_yun/agent/datastore/metric_helper.rb +82 -0
- data/lib/ting_yun/agent/datastore/mongo.rb +44 -0
- data/lib/ting_yun/agent/datastore.rb +33 -0
- data/lib/ting_yun/agent/dispatcher.rb +39 -0
- data/lib/ting_yun/agent/event/event_listener.rb +47 -0
- data/lib/ting_yun/agent/event/event_loop.rb +194 -0
- data/lib/ting_yun/agent/instance_methods/connect.rb +164 -0
- data/lib/ting_yun/agent/instance_methods/container_data_manager.rb +137 -0
- data/lib/ting_yun/agent/instance_methods/handle_errors.rb +71 -0
- data/lib/ting_yun/agent/instance_methods/start.rb +219 -0
- data/lib/ting_yun/agent/instance_methods/start_worker_thread.rb +51 -0
- data/lib/ting_yun/agent/instance_methods.rb +39 -0
- data/lib/ting_yun/agent/method_tracer.rb +256 -0
- data/lib/ting_yun/agent/method_tracer_helpers.rb +85 -0
- data/lib/ting_yun/agent/threading/agent_thread.rb +49 -0
- data/lib/ting_yun/agent/transaction/attributes.rb +22 -0
- data/lib/ting_yun/agent/transaction/request_attributes.rb +126 -0
- data/lib/ting_yun/agent/transaction/trace.rb +125 -0
- data/lib/ting_yun/agent/transaction/trace_node.rb +110 -0
- data/lib/ting_yun/agent/transaction/traced_method_stack.rb +80 -0
- data/lib/ting_yun/agent/transaction/transaction_metrics.rb +51 -0
- data/lib/ting_yun/agent/transaction/transaction_sample_builder.rb +63 -0
- data/lib/ting_yun/agent/transaction/transaction_state.rb +112 -0
- data/lib/ting_yun/agent/transaction.rb +522 -0
- data/lib/ting_yun/agent.rb +207 -0
- data/lib/ting_yun/configuration/default_source.rb +638 -0
- data/lib/ting_yun/configuration/dotted_hash.rb +46 -0
- data/lib/ting_yun/configuration/environment_source.rb +116 -0
- data/lib/ting_yun/configuration/manager.rb +232 -0
- data/lib/ting_yun/configuration/manual_source.rb +14 -0
- data/lib/ting_yun/configuration/server_source.rb +88 -0
- data/lib/ting_yun/configuration/yaml_source.rb +136 -0
- data/lib/ting_yun/configuration.rb +9 -0
- data/lib/ting_yun/environment_report.rb +123 -0
- data/lib/ting_yun/frameworks/class_methods.rb +47 -0
- data/lib/ting_yun/frameworks/external.rb +15 -0
- data/lib/ting_yun/frameworks/instance_methods.rb +120 -0
- data/lib/ting_yun/frameworks/instrumentation.rb +67 -0
- data/lib/ting_yun/frameworks/rails.rb +63 -0
- data/lib/ting_yun/frameworks/rails3.rb +26 -0
- data/lib/ting_yun/frameworks/rails4.rb +14 -0
- data/lib/ting_yun/frameworks/ruby.rb +17 -0
- data/lib/ting_yun/frameworks/sinatra.rb +10 -0
- data/lib/ting_yun/frameworks.rb +34 -0
- data/lib/ting_yun/http/generic_request.rb +8 -0
- data/lib/ting_yun/http/net_http_request.rb +46 -0
- data/lib/ting_yun/instrumentation/active_record.rb +103 -0
- data/lib/ting_yun/instrumentation/middleware_proxy.rb +77 -0
- data/lib/ting_yun/instrumentation/middleware_tracing.rb +84 -0
- data/lib/ting_yun/instrumentation/mongo.rb +103 -0
- data/lib/ting_yun/instrumentation/mongo2.rb +37 -0
- data/lib/ting_yun/instrumentation/mongo_command_log_subscriber.rb +97 -0
- data/lib/ting_yun/instrumentation/moped.rb +95 -0
- data/lib/ting_yun/instrumentation/net.rb +59 -0
- data/lib/ting_yun/instrumentation/rack.rb +109 -0
- data/lib/ting_yun/instrumentation/rails3/action_controller.rb +63 -0
- data/lib/ting_yun/instrumentation/rails3/action_view.rb +115 -0
- data/lib/ting_yun/instrumentation/rails4/action_controller_subscriber.rb +124 -0
- data/lib/ting_yun/instrumentation/rails4/action_view_subscriber.rb +118 -0
- data/lib/ting_yun/instrumentation/rails4/active_record_subscriber.rb +124 -0
- data/lib/ting_yun/instrumentation/rails_middleware.rb +38 -0
- data/lib/ting_yun/instrumentation/redis.rb +70 -0
- data/lib/ting_yun/instrumentation/support/active_record_helper.rb +178 -0
- data/lib/ting_yun/instrumentation/support/controller_instrumentation.rb +54 -0
- data/lib/ting_yun/instrumentation/support/database.rb +38 -0
- data/lib/ting_yun/instrumentation/support/event_formatter.rb +19 -0
- data/lib/ting_yun/instrumentation/support/evented_subscriber.rb +97 -0
- data/lib/ting_yun/instrumentation/support/external_error.rb +52 -0
- data/lib/ting_yun/instrumentation/support/metric_translator.rb +84 -0
- data/lib/ting_yun/instrumentation/support/mongo_formatter.rb +49 -0
- data/lib/ting_yun/instrumentation/support/parameter_filtering.rb +21 -0
- data/lib/ting_yun/instrumentation/support/queue_time.rb +76 -0
- data/lib/ting_yun/instrumentation/support/transaction_namer.rb +68 -0
- data/lib/ting_yun/instrumentation/thrift.rb +329 -0
- data/lib/ting_yun/logger/agent_logger.rb +196 -0
- data/lib/ting_yun/logger/log_once.rb +38 -0
- data/lib/ting_yun/logger/memory_logger.rb +56 -0
- data/lib/ting_yun/logger/null_logger.rb +31 -0
- data/lib/ting_yun/logger/startup_logger.rb +13 -0
- data/lib/ting_yun/logger.rb +8 -0
- data/lib/ting_yun/metrics/metric_data.rb +86 -0
- data/lib/ting_yun/metrics/metric_spec.rb +89 -0
- data/lib/ting_yun/metrics/stats.rb +158 -0
- data/lib/ting_yun/metrics.rb +12 -0
- data/lib/ting_yun/support/coerce.rb +86 -0
- data/lib/ting_yun/support/collector.rb +29 -0
- data/lib/ting_yun/support/exception.rb +79 -0
- data/lib/ting_yun/support/hash_extensions.rb +25 -0
- data/lib/ting_yun/support/helper.rb +54 -0
- data/lib/ting_yun/support/hostname.rb +13 -0
- data/lib/ting_yun/support/http_clients/uri_util.rb +49 -0
- data/lib/ting_yun/support/language_support.rb +155 -0
- data/lib/ting_yun/support/library_detection.rb +129 -0
- data/lib/ting_yun/support/local_environment.rb +185 -0
- data/lib/ting_yun/support/path.rb +13 -0
- data/lib/ting_yun/support/serialize/encodes.rb +61 -0
- data/lib/ting_yun/support/serialize/encoding_normalizer.rb +84 -0
- data/lib/ting_yun/support/serialize/json_marshaller.rb +73 -0
- data/lib/ting_yun/support/serialize/json_wrapper.rb +78 -0
- data/lib/ting_yun/support/serialize/marshaller.rb +69 -0
- data/lib/ting_yun/support/serialize/ok_json.rb +651 -0
- data/lib/ting_yun/support/system_info.rb +206 -0
- data/lib/ting_yun/support/timer_lib.rb +29 -0
- data/lib/ting_yun/support/version_number.rb +70 -0
- data/lib/ting_yun/ting_yun_service/connection.rb +118 -0
- data/lib/ting_yun/ting_yun_service/http.rb +41 -0
- data/lib/ting_yun/ting_yun_service/request.rb +90 -0
- data/lib/ting_yun/ting_yun_service/ssl.rb +45 -0
- data/lib/ting_yun/ting_yun_service/upload_service.rb +149 -0
- data/lib/ting_yun/ting_yun_service.rb +124 -0
- data/lib/ting_yun/version.rb +17 -0
- data/lib/tingyun_rpm.rb +47 -0
- data/tingyun_rpm.gemspec +60 -0
- 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
|