oneapm_rpm 1.3.7 → 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.gitignore +3 -2
- data/Gemfile +1 -1
- data/lib/one_apm/agent.rb +17 -10
- data/lib/one_apm/agent/agent/connect.rb +9 -3
- data/lib/one_apm/agent/agent/container_data_manager.rb +20 -3
- data/lib/one_apm/agent/agent/cross_app_samples_sender.rb +22 -0
- data/lib/one_apm/agent/agent/rule_fetcher.rb +15 -0
- data/lib/one_apm/agent/agent/start.rb +15 -3
- data/lib/one_apm/agent/agent/start_worker_thread.rb +8 -2
- data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +7 -6
- data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +45 -9
- data/lib/one_apm/agent/cross_app/cross_app_tracing_message.rb +130 -0
- data/lib/one_apm/agent/database/active_record_helper.rb +104 -50
- data/lib/one_apm/agent/datastore.rb +8 -0
- data/lib/one_apm/agent/datastore/metric_helper.rb +37 -6
- data/lib/one_apm/agent/synthetics_monitor.rb +1 -1
- data/lib/one_apm/collector/collector/helper.rb +5 -1
- data/lib/one_apm/collector/collector/http_connection.rb +16 -8
- data/lib/one_apm/collector/collector_service.rb +6 -4
- data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +52 -75
- data/lib/one_apm/collector/containers/transaction_sampler.rb +6 -2
- data/lib/one_apm/configuration.rb +8 -4
- data/lib/one_apm/configuration/default_source.rb +24 -3
- data/lib/one_apm/configuration/server_source.rb +1 -1
- data/lib/one_apm/inst/http_clients/curb.rb +4 -1
- data/lib/one_apm/inst/http_clients/thrift.rb +57 -20
- data/lib/one_apm/inst/nosql/memcache.rb +21 -2
- data/lib/one_apm/inst/nosql/mongo2.rb +11 -8
- data/lib/one_apm/inst/nosql/redis.rb +8 -3
- data/lib/one_apm/inst/orm/active_record.rb +13 -7
- data/lib/one_apm/inst/rails4/active_record_subscriber.rb +16 -13
- data/lib/one_apm/inst/transaction_base.rb +0 -1
- data/lib/one_apm/logger/audit_logger.rb +19 -2
- data/lib/one_apm/manager.rb +1 -0
- data/lib/one_apm/probe/instance_methods.rb +0 -1
- data/lib/one_apm/rack/middleware_tracing.rb +1 -0
- data/lib/one_apm/support/event_buffer/sampled_buffer.rb +4 -0
- data/lib/one_apm/support/helper.rb +16 -0
- data/lib/one_apm/support/http_clients/curb_wrappers.rb +20 -0
- data/lib/one_apm/support/http_clients/excon_wrappers.rb +25 -0
- data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +20 -0
- data/lib/one_apm/support/http_clients/net_http_wrappers.rb +20 -0
- data/lib/one_apm/support/http_clients/thrift_tracer.rb +64 -0
- data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +21 -1
- data/lib/one_apm/support/http_clients/uri_util.rb +1 -0
- data/lib/one_apm/support/ip.rb +15 -0
- data/lib/one_apm/support/rename_rules_engine.rb +39 -0
- data/lib/one_apm/support/rename_rules_engine/external_rename_rule.rb +84 -0
- data/lib/one_apm/support/rename_rules_engine/match_expression/base.rb +46 -0
- data/lib/one_apm/support/rename_rules_engine/match_expression/engine.rb +35 -0
- data/lib/one_apm/support/rename_rules_engine/match_expression/method.rb +20 -0
- data/lib/one_apm/support/rename_rules_engine/match_expression/split_object.rb +19 -0
- data/lib/one_apm/support/rename_rules_engine/match_expression/url.rb +19 -0
- data/lib/one_apm/support/rename_rules_engine/rename/base.rb +25 -0
- data/lib/one_apm/support/rename_rules_engine/rename/engine.rb +36 -0
- data/lib/one_apm/support/rename_rules_engine/rename/header.rb +17 -0
- data/lib/one_apm/support/rename_rules_engine/rename/parameter.rb +18 -0
- data/lib/one_apm/support/rename_rules_engine/rename/segment.rb +41 -0
- data/lib/one_apm/transaction.rb +11 -2
- data/lib/one_apm/transaction/class_methods.rb +3 -3
- data/lib/one_apm/transaction/event_analytic_data.rb +51 -0
- data/lib/one_apm/transaction/event_analytic_sample.rb +35 -0
- data/lib/one_apm/transaction/instance_helpers.rb +1 -1
- data/lib/one_apm/transaction/sample_buffer/cross_sample_buffer.rb +47 -0
- data/lib/one_apm/transaction/segment.rb +2 -1
- data/lib/one_apm/transaction/transaction_finish_append.rb +4 -0
- data/lib/one_apm/transaction/transaction_name.rb +1 -1
- data/lib/one_apm/transaction/transaction_sample.rb +12 -7
- data/lib/one_apm/version.rb +2 -2
- data/lib/sequel/extensions/oneapm_instrumentation.rb +16 -9
- data/lib/sequel/plugins/oneapm_instrumentation.rb +3 -2
- data/oneapm_rpm.gemspec +2 -1
- metadata +41 -21
@@ -0,0 +1,130 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module OneApm
|
4
|
+
module Agent
|
5
|
+
module CrossAppTracingMessage
|
6
|
+
|
7
|
+
class Error < RuntimeError; end
|
8
|
+
|
9
|
+
OA_ID_MESSAGE_HEADER = 'BlueWareID'
|
10
|
+
|
11
|
+
OA_TXN_MESSAGE_HEADER = 'BlueWareTransaction'
|
12
|
+
|
13
|
+
OA_SYNTHETICS_MESSAGE_HEADER = 'BlueWareSynthetics'
|
14
|
+
|
15
|
+
###############
|
16
|
+
module_function
|
17
|
+
###############
|
18
|
+
|
19
|
+
def request_data(state)
|
20
|
+
rpc_request = {}
|
21
|
+
inject_rpc_request_headers(state, rpc_request) if cross_app_enabled?
|
22
|
+
json_rpc_request = OneApm::JSONWrapper.dump(rpc_request)
|
23
|
+
# OneApm::Manager.logger.debug "Thrift Header Message: #{json_rpc_request}"
|
24
|
+
obfuscator.obfuscate(json_rpc_request)
|
25
|
+
rescue OneApm::Agent::CrossAppTracingMessage::Error => err
|
26
|
+
OneApm::Manager.logger.debug "Not injecting x-process header", err
|
27
|
+
end
|
28
|
+
|
29
|
+
# TODO: just stub
|
30
|
+
def process_request message
|
31
|
+
OneApm::Manager.logger.debug "Thrift Process Message: #{message}"
|
32
|
+
end
|
33
|
+
|
34
|
+
def inject_rpc_request_headers state, rpc_request
|
35
|
+
txn_guid = state.request_guid
|
36
|
+
txn = state.current_transaction
|
37
|
+
if txn
|
38
|
+
trip_id = txn.cat_trip_id(state)
|
39
|
+
path_hash = txn.cat_path_hash(state)
|
40
|
+
if txn.raw_synthetics_header
|
41
|
+
rpc_request[OA_SYNTHETICS_MESSAGE_HEADER] = txn.raw_synthetics_header
|
42
|
+
end
|
43
|
+
end
|
44
|
+
rpc_request[OA_ID_MESSAGE_HEADER] = cross_app_id
|
45
|
+
rpc_request[OA_TXN_MESSAGE_HEADER] = [txn_guid, true, trip_id, path_hash, '']
|
46
|
+
rescue OneApm::Agent::CrossAppTracingMessage::Error => err #TODO
|
47
|
+
OneApm::Manager.logger.debug "Not injecting x-process header", err
|
48
|
+
end
|
49
|
+
|
50
|
+
def cross_app_id
|
51
|
+
OneApm::Manager.config[:cross_process_id] or
|
52
|
+
raise OneApm::Agent::CrossAppTracingMessage::Error, "no cross app ID configured"
|
53
|
+
end
|
54
|
+
|
55
|
+
def start_trace(state, t0, rpc_request)
|
56
|
+
state.is_cross_app_caller = true
|
57
|
+
stack = state.traced_method_stack
|
58
|
+
segment = stack.push_frame(state, :rpc_request, t0)
|
59
|
+
return segment
|
60
|
+
rescue => err
|
61
|
+
OneApm::Manager.logger.error "Uncaught exception while tracing RPC request", err
|
62
|
+
return nil
|
63
|
+
rescue Exception => e
|
64
|
+
OneApm::Manager.logger.debug "Unexpected exception raised while tracing RPC request", e
|
65
|
+
raise e
|
66
|
+
end
|
67
|
+
|
68
|
+
def finish_trace(state, t0, segment, request, metrics)
|
69
|
+
unless t0
|
70
|
+
OneApm::Manager.logger.error("RPC request trace finished without start time. This is probably an agent bug.")
|
71
|
+
return
|
72
|
+
end
|
73
|
+
|
74
|
+
t1 = Time.now
|
75
|
+
duration = t1.to_f - t0.to_f
|
76
|
+
begin
|
77
|
+
if request
|
78
|
+
scoped_metric, *other_metrics = metrics
|
79
|
+
OneApm::Manager.agent.stats_engine.record_scoped_and_unscoped_metrics(state, scoped_metric, nil, duration)
|
80
|
+
if segment
|
81
|
+
segment.name = scoped_metric
|
82
|
+
end
|
83
|
+
end
|
84
|
+
ensure
|
85
|
+
# If we have a segment, always pop the traced method stack to avoid
|
86
|
+
# an inconsistent state, which prevents tracing of whole transaction.
|
87
|
+
if segment
|
88
|
+
stack = state.traced_method_stack
|
89
|
+
stack.pop_frame(state, segment, scoped_metric, t1)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
rescue OneApm::Agent::CrossAppTracingMessage::Error => err
|
93
|
+
OneApm::Manager.logger.debug "while cross app tracing", err
|
94
|
+
rescue => err
|
95
|
+
OneApm::Manager.logger.error "Uncaught exception while finishing an RPC request trace", err
|
96
|
+
end
|
97
|
+
|
98
|
+
# Return +true+ if cross app tracing is enabled in the config.
|
99
|
+
def cross_app_enabled?
|
100
|
+
valid_cross_process_id? &&
|
101
|
+
valid_encoding_key? &&
|
102
|
+
cross_application_tracer_enabled?
|
103
|
+
end
|
104
|
+
|
105
|
+
def valid_cross_process_id?
|
106
|
+
OneApm::Manager.config[:cross_process_id] && OneApm::Manager.config[:cross_process_id].length > 0
|
107
|
+
end
|
108
|
+
|
109
|
+
def valid_encoding_key?
|
110
|
+
OneApm::Manager.config[:encoding_key] && OneApm::Manager.config[:encoding_key].length > 0
|
111
|
+
end
|
112
|
+
|
113
|
+
def cross_application_tracer_enabled?
|
114
|
+
OneApm::Manager.config[:"cross_application_tracer.enabled"]
|
115
|
+
end
|
116
|
+
|
117
|
+
# Fetcher for the cross app encoding key. Raises a
|
118
|
+
# OneApm::Agent::CrossAppTracingMessage::Error if the key isn't configured.
|
119
|
+
def cross_app_encoding_key
|
120
|
+
OneApm::Manager.config[:encoding_key] or
|
121
|
+
raise OneApm::Agent::CrossAppTracingMessage::Error, "No encoding_key set."
|
122
|
+
end
|
123
|
+
|
124
|
+
def obfuscator
|
125
|
+
@obfuscator ||= OneApm::Agent::Obfuscator.new(cross_app_encoding_key)
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
@@ -6,72 +6,126 @@ module OneApm
|
|
6
6
|
module ActiveRecordHelper
|
7
7
|
module_function
|
8
8
|
|
9
|
-
|
10
|
-
|
9
|
+
DATABASE = "Database".freeze
|
10
|
+
STATEMENT = "statement".freeze
|
11
|
+
ALL = "Database/all".freeze
|
12
|
+
ALLWEB = "Database/allWeb".freeze
|
13
|
+
ALLOTHER = "Database/allOther".freeze
|
14
|
+
|
15
|
+
def operation_metric_for(product, operation, model_name)
|
16
|
+
met_info = [ DATABASE, STATEMENT]
|
17
|
+
met_info << product
|
18
|
+
met_info << model_name
|
19
|
+
met_info << operation
|
20
|
+
met_info.compact.join("/")
|
21
|
+
end
|
22
|
+
|
23
|
+
def operation_all_metric_for(product, operation)
|
24
|
+
met_info = [ DATABASE, STATEMENT]
|
25
|
+
#without data_base_name
|
26
|
+
met_info << without_database_name(product)
|
27
|
+
met_info << operation
|
28
|
+
met_info.compact.join("/")
|
29
|
+
end
|
30
|
+
|
31
|
+
def product_rollup(product)
|
32
|
+
"Database/#{STATEMENT}/#{without_database_name(product)}/all"
|
33
|
+
end
|
34
|
+
|
35
|
+
def rollup_metrics_for
|
36
|
+
return ALLWEB if OneApm::Transaction.recording_web_transaction?
|
37
|
+
return ALLOTHER
|
38
|
+
end
|
39
|
+
|
40
|
+
#Database/statement/SqlType:10.128.6.33:3306/all
|
41
|
+
def all(product)
|
42
|
+
met_info = [ DATABASE, STATEMENT]
|
43
|
+
met_info << database_type(product)
|
44
|
+
met_info.compact.join("/")
|
45
|
+
end
|
46
|
+
|
47
|
+
def metric_for(product, operation, model_name = nil)
|
48
|
+
metrics = [
|
49
|
+
operation_metric_for(product, operation, model_name),
|
50
|
+
operation_all_metric_for(product, operation),
|
51
|
+
product_rollup(product),
|
52
|
+
rollup_metrics_for,
|
53
|
+
all(product)
|
54
|
+
]
|
55
|
+
metrics
|
56
|
+
end
|
57
|
+
|
58
|
+
def model_for_name(name)
|
59
|
+
return 'SQL' unless name && name.respond_to?(:split)
|
11
60
|
parts = name.split(' ')
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
61
|
+
if parts.size == 2
|
62
|
+
parts.first
|
63
|
+
else
|
64
|
+
'SQL'
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def operator_for_name(name)
|
69
|
+
return unless name && name.include?(' ')
|
70
|
+
parts = name.split(' ')
|
71
|
+
return rename_for(parts.last.downcase) if parts.size == 2
|
72
|
+
end
|
73
|
+
|
74
|
+
def rename_for operation
|
75
|
+
op_name = case operation.to_s
|
76
|
+
when 'find', 'load', 'count', 'exists', 'all', 'get', 'select'
|
77
|
+
'select'
|
78
|
+
when 'destroy', 'delete'
|
79
|
+
'delete'
|
80
|
+
when 'create', 'insert'
|
81
|
+
'insert'
|
22
82
|
when 'update', 'save'
|
23
|
-
|
83
|
+
'update'
|
84
|
+
when 'other'
|
85
|
+
'other'
|
24
86
|
else
|
25
|
-
|
87
|
+
nil
|
26
88
|
end
|
27
|
-
|
28
|
-
end
|
89
|
+
op_name
|
29
90
|
end
|
30
91
|
|
31
|
-
def
|
92
|
+
def operator_for_sql(sql)
|
32
93
|
txn = OneApm::Transaction.tl_current
|
33
94
|
metric = txn && txn.database_metric_name
|
95
|
+
operation = ""
|
34
96
|
if metric.nil?
|
35
97
|
operation = OneApm::Agent::Database.parse_operation_from_query(sql)
|
36
|
-
if operation
|
37
|
-
# Could not determine the model/operation so use a fallback metric
|
38
|
-
metric = "Database/SQL/#{operation}"
|
39
|
-
else
|
40
|
-
metric = "Database/SQL/other"
|
41
|
-
end
|
42
98
|
end
|
43
|
-
|
99
|
+
operation || "other"
|
100
|
+
end
|
101
|
+
|
102
|
+
def database_info config = {}
|
103
|
+
info = []
|
104
|
+
db_type, default_port = type_and_default_port_for_db config.fetch(:adapter, "SQL")
|
105
|
+
info << db_type
|
106
|
+
info << config.fetch(:host, '127.0.0.1')
|
107
|
+
info << config.fetch(:port, default_port)
|
108
|
+
#database need join with '/'
|
109
|
+
"#{info.compact.uniq.join(":")}/#{config.fetch(:database, 'unknown')}"
|
44
110
|
end
|
45
111
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
# If the metric name is in the form of "Database/action"
|
50
|
-
# this returns merely: [ "Database/all", "Database/all" ]
|
51
|
-
def rollup_metrics_for(metric)
|
52
|
-
metrics = ["Database/all"]
|
53
|
-
|
54
|
-
# If we're outside of a web transaction, don't record any rollup
|
55
|
-
# database metrics. This is to prevent metrics from background tasks
|
56
|
-
# from polluting the metrics used to drive overview graphs.
|
57
|
-
if OneApm::Transaction.recording_web_transaction?
|
58
|
-
metrics << "Database/allWeb"
|
59
|
-
else
|
60
|
-
metrics << "Database/allOther"
|
61
|
-
end
|
62
|
-
metrics << "Database/#{$1}" if metric =~ /Database\/[\w|\:]+\/(\w+)/
|
112
|
+
def without_database_name(product)
|
113
|
+
product.split('/')[0..-2].join('/')
|
114
|
+
end
|
63
115
|
|
64
|
-
|
116
|
+
def database_type(product)
|
117
|
+
product.split(':')[0]
|
65
118
|
end
|
66
119
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
120
|
+
|
121
|
+
def type_and_default_port_for_db adapter
|
122
|
+
type, port = case adapter
|
123
|
+
when /mysql/ then [:MySQL, 3306]
|
124
|
+
when /postgresql/ then [:PostgreSQL, 5432]
|
125
|
+
when /oracle/ then [:Oracle, 1521]
|
126
|
+
when /sqlserver/ then [:SQLSever, 1433]
|
127
|
+
else [:Other, -1]
|
128
|
+
end
|
75
129
|
end
|
76
130
|
end
|
77
131
|
end
|
@@ -6,6 +6,14 @@ module OneApm
|
|
6
6
|
module Agent
|
7
7
|
module Datastore
|
8
8
|
|
9
|
+
LOCALHOST = 'localhost'.freeze
|
10
|
+
LOCAL_127 = '127.0.0.1'.freeze
|
11
|
+
|
12
|
+
def self.oneapm_product *product
|
13
|
+
return product[0] if product[1].nil?
|
14
|
+
product.compact.join(":").gsub(LOCALHOST, LOCAL_127)
|
15
|
+
end
|
16
|
+
|
9
17
|
def self.trace(clazz, method_name, product, operation = method_name)
|
10
18
|
clazz.class_eval do
|
11
19
|
method_name_without_oneapm = "#{method_name}_without_oneapm"
|
@@ -14,26 +14,53 @@ module OneApm
|
|
14
14
|
OA_ALL_WEB = "allWeb".freeze
|
15
15
|
OA_ALL_OTHER = "allOther".freeze
|
16
16
|
|
17
|
-
|
18
|
-
"Datastore/statement/#{product}/#{collection}/#{operation}"
|
19
|
-
end
|
20
|
-
|
17
|
+
# Datastore/operation/NoSqlType:10.128.6.240:27017/update
|
21
18
|
def self.operation_metric_for(product, operation)
|
22
19
|
"Datastore/operation/#{product}/#{operation}"
|
23
20
|
end
|
24
21
|
|
22
|
+
#Datastore/operation/NoSqlType:10.128.6.240:27017/all
|
23
|
+
def self.operation_product_rollup(product)
|
24
|
+
"Datastore/operation/#{product}/all"
|
25
|
+
end
|
26
|
+
|
27
|
+
#Datastore/operation/NoSqlType
|
28
|
+
def self.operation_all(product)
|
29
|
+
"Datastore/operation/#{product.split(':')[0]}"
|
30
|
+
end
|
31
|
+
|
25
32
|
def self.product_suffixed_rollup(product, suffix)
|
26
33
|
"Datastore/#{product}/#{suffix}"
|
27
34
|
end
|
28
35
|
|
29
36
|
def self.product_rollup(product)
|
30
|
-
"Datastore
|
37
|
+
"Datastore//#{product}/all"
|
31
38
|
end
|
32
39
|
|
33
40
|
def self.suffixed_rollup(suffix)
|
34
41
|
"Datastore/#{suffix}"
|
35
42
|
end
|
36
43
|
|
44
|
+
#Datastore/statement/NoSqlType:10.128.6.240:27017/book/insert
|
45
|
+
def self.statement_metric_for(product, collection, operation)
|
46
|
+
"Datastore/statement/#{product}/#{collection}/#{operation}"
|
47
|
+
end
|
48
|
+
|
49
|
+
#Datastore/statement/NoSqlType:10.128.6.240:27017/book/insert
|
50
|
+
def self.statement_action_metric_for(product, operation)
|
51
|
+
"Datastore/statement/#{product}/#{operation}"
|
52
|
+
end
|
53
|
+
|
54
|
+
#Datastore/statement/NoSqlType:10.128.6.240:27017/all
|
55
|
+
def self.statement_all_metric_for(product)
|
56
|
+
"Datastore/statement/#{product}/all"
|
57
|
+
end
|
58
|
+
|
59
|
+
#Datastore/statement/NoSqlType
|
60
|
+
def self.statement_all(product)
|
61
|
+
"Datastore/statement/#{product.split(':')[0]}"
|
62
|
+
end
|
63
|
+
|
37
64
|
def self.all_suffix
|
38
65
|
if OneApm::Transaction.recording_web_transaction?
|
39
66
|
OA_ALL_WEB
|
@@ -53,6 +80,8 @@ module OneApm
|
|
53
80
|
# be treated as the scoped metric in a bunch of different cases.
|
54
81
|
metrics = [
|
55
82
|
operation_metric_for(product, operation),
|
83
|
+
operation_product_rollup(product),
|
84
|
+
operation_all(product),
|
56
85
|
product_suffixed_rollup(product, suffix),
|
57
86
|
product_rollup(product),
|
58
87
|
suffixed_rollup(suffix),
|
@@ -60,7 +89,9 @@ module OneApm
|
|
60
89
|
]
|
61
90
|
|
62
91
|
metrics.unshift statement_metric_for(product, collection, operation) if collection
|
63
|
-
|
92
|
+
metrics.unshift statement_action_metric_for(product,operation)
|
93
|
+
metrics.unshift statement_all_metric_for(product)
|
94
|
+
metrics.unshift statement_all(product)
|
64
95
|
metrics
|
65
96
|
end
|
66
97
|
|
@@ -5,7 +5,7 @@ require 'one_apm/agent/inbound_request_monitor'
|
|
5
5
|
module OneApm
|
6
6
|
module Agent
|
7
7
|
class SyntheticsMonitor < InboundRequestMonitor
|
8
|
-
OA_SYNTHETICS_HEADER_KEY = '
|
8
|
+
OA_SYNTHETICS_HEADER_KEY = 'HTTP_X_BLUEWARE_SYNTHETICS'.freeze
|
9
9
|
|
10
10
|
OA_SUPPORTED_VERSION = 1
|
11
11
|
OA_EXPECTED_PAYLOAD_LENGTH = 5
|
@@ -90,6 +90,8 @@ module OneApm
|
|
90
90
|
# It also handles translating metric names to IDs using our metric ID cache.
|
91
91
|
def build_metric_data_array(stats_hash)
|
92
92
|
metric_data_array = []
|
93
|
+
|
94
|
+
# OneApm::Manager.logger.info "---metric_id_cache--#{metric_id_cache.inspect}"
|
93
95
|
stats_hash.each do |metric_spec, stats|
|
94
96
|
# Omit empty stats as an optimization
|
95
97
|
unless stats.is_reset?
|
@@ -99,9 +101,11 @@ module OneApm
|
|
99
101
|
else
|
100
102
|
OneApm::MetricData.new(metric_spec, stats, nil)
|
101
103
|
end
|
102
|
-
|
104
|
+
|
105
|
+
metric_data_array << metric_data #unless metric_spec.name =~ /^Nested/
|
103
106
|
end
|
104
107
|
end
|
108
|
+
# OneApm::Manager.logger.info "--metric_data_array---#{metric_data_array}"
|
105
109
|
metric_data_array
|
106
110
|
end
|
107
111
|
|
@@ -6,8 +6,9 @@ module OneApm
|
|
6
6
|
# These include Errno connection errors, and all indicate that the
|
7
7
|
# underlying TCP connection may be in a bad state.
|
8
8
|
OA_CONNECTION_ERRORS = [Timeout::Error, EOFError, SystemCallError, SocketError].freeze
|
9
|
+
OA_API_VERSION = '1.0'.freeze
|
9
10
|
|
10
|
-
def invoke_remote(method, payload = [], options = {})
|
11
|
+
def invoke_remote(method, payload = [], options = {},query_params={})
|
11
12
|
start_ts = Time.now
|
12
13
|
|
13
14
|
data = nil
|
@@ -21,7 +22,7 @@ module OneApm
|
|
21
22
|
data, encoding = compress_request(data)
|
22
23
|
size = data.size
|
23
24
|
|
24
|
-
uri = remote_method_uri(method, @marshaller.format)
|
25
|
+
uri = remote_method_uri(method, @marshaller.format,query_params)
|
25
26
|
full_uri = "#{@collector}#{uri}"
|
26
27
|
|
27
28
|
@audit_logger.log_request(full_uri, payload, @marshaller)
|
@@ -29,7 +30,9 @@ module OneApm
|
|
29
30
|
:uri => uri,
|
30
31
|
:encoding => encoding,
|
31
32
|
:collector => @collector)
|
32
|
-
@marshaller.load(decompress_response(response))
|
33
|
+
response = @marshaller.load(decompress_response(response))
|
34
|
+
@audit_logger.log_response(response)
|
35
|
+
response
|
33
36
|
ensure
|
34
37
|
record_timing_supportability_metrics(method, start_ts, serialize_finish_ts)
|
35
38
|
if size
|
@@ -38,8 +41,8 @@ module OneApm
|
|
38
41
|
end
|
39
42
|
|
40
43
|
# The path on the server that we should post our data to
|
41
|
-
def remote_method_uri(method, format)
|
42
|
-
params = {'run_id' => @agent_id, 'marshal_format' => format}
|
44
|
+
def remote_method_uri(method, format, query_params={})
|
45
|
+
params = {'run_id' => @agent_id, 'marshal_format' => format}.merge(query_params)
|
43
46
|
uri = "/tpm/agent.do?PROTOCOL_VERSION=#{OA_PROTOCOL_VERSION}&license_key=#{@license_key}&method=#{method}"
|
44
47
|
uri << '&' + params.map do |k,v|
|
45
48
|
next unless v
|
@@ -59,11 +62,16 @@ module OneApm
|
|
59
62
|
# contact
|
60
63
|
# - :data => the data to send as the body of the request
|
61
64
|
def send_request(opts)
|
62
|
-
request = Net::HTTP::Post.new(opts[:uri],
|
65
|
+
request = Net::HTTP::Post.new(opts[:uri],
|
66
|
+
'CONTENT-ENCODING' => opts[:encoding],
|
67
|
+
'HOST' => opts[:collector].name,
|
68
|
+
'API-VERSION' => OA_API_VERSION)
|
63
69
|
request['user-agent'] = user_agent
|
70
|
+
request['_SKIP_CAT_'] = true
|
64
71
|
request.body = opts[:data]
|
65
|
-
|
66
|
-
|
72
|
+
#see http://jira.oneapm.me/browse/AI-3227
|
73
|
+
#old content_type is "multipart/form-data; boundary=-oneapm-#{request.object_id}-"
|
74
|
+
request.content_type = 'application/json'
|
67
75
|
response = nil
|
68
76
|
attempts = 0
|
69
77
|
max_attempts = 2
|