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.
Files changed (74) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +3 -2
  3. data/Gemfile +1 -1
  4. data/lib/one_apm/agent.rb +17 -10
  5. data/lib/one_apm/agent/agent/connect.rb +9 -3
  6. data/lib/one_apm/agent/agent/container_data_manager.rb +20 -3
  7. data/lib/one_apm/agent/agent/cross_app_samples_sender.rb +22 -0
  8. data/lib/one_apm/agent/agent/rule_fetcher.rb +15 -0
  9. data/lib/one_apm/agent/agent/start.rb +15 -3
  10. data/lib/one_apm/agent/agent/start_worker_thread.rb +8 -2
  11. data/lib/one_apm/agent/cross_app/cross_app_monitor.rb +7 -6
  12. data/lib/one_apm/agent/cross_app/cross_app_tracing.rb +45 -9
  13. data/lib/one_apm/agent/cross_app/cross_app_tracing_message.rb +130 -0
  14. data/lib/one_apm/agent/database/active_record_helper.rb +104 -50
  15. data/lib/one_apm/agent/datastore.rb +8 -0
  16. data/lib/one_apm/agent/datastore/metric_helper.rb +37 -6
  17. data/lib/one_apm/agent/synthetics_monitor.rb +1 -1
  18. data/lib/one_apm/collector/collector/helper.rb +5 -1
  19. data/lib/one_apm/collector/collector/http_connection.rb +16 -8
  20. data/lib/one_apm/collector/collector_service.rb +6 -4
  21. data/lib/one_apm/collector/containers/transaction_event_aggregator.rb +52 -75
  22. data/lib/one_apm/collector/containers/transaction_sampler.rb +6 -2
  23. data/lib/one_apm/configuration.rb +8 -4
  24. data/lib/one_apm/configuration/default_source.rb +24 -3
  25. data/lib/one_apm/configuration/server_source.rb +1 -1
  26. data/lib/one_apm/inst/http_clients/curb.rb +4 -1
  27. data/lib/one_apm/inst/http_clients/thrift.rb +57 -20
  28. data/lib/one_apm/inst/nosql/memcache.rb +21 -2
  29. data/lib/one_apm/inst/nosql/mongo2.rb +11 -8
  30. data/lib/one_apm/inst/nosql/redis.rb +8 -3
  31. data/lib/one_apm/inst/orm/active_record.rb +13 -7
  32. data/lib/one_apm/inst/rails4/active_record_subscriber.rb +16 -13
  33. data/lib/one_apm/inst/transaction_base.rb +0 -1
  34. data/lib/one_apm/logger/audit_logger.rb +19 -2
  35. data/lib/one_apm/manager.rb +1 -0
  36. data/lib/one_apm/probe/instance_methods.rb +0 -1
  37. data/lib/one_apm/rack/middleware_tracing.rb +1 -0
  38. data/lib/one_apm/support/event_buffer/sampled_buffer.rb +4 -0
  39. data/lib/one_apm/support/helper.rb +16 -0
  40. data/lib/one_apm/support/http_clients/curb_wrappers.rb +20 -0
  41. data/lib/one_apm/support/http_clients/excon_wrappers.rb +25 -0
  42. data/lib/one_apm/support/http_clients/httpclient_wrappers.rb +20 -0
  43. data/lib/one_apm/support/http_clients/net_http_wrappers.rb +20 -0
  44. data/lib/one_apm/support/http_clients/thrift_tracer.rb +64 -0
  45. data/lib/one_apm/support/http_clients/typhoeus_wrappers.rb +21 -1
  46. data/lib/one_apm/support/http_clients/uri_util.rb +1 -0
  47. data/lib/one_apm/support/ip.rb +15 -0
  48. data/lib/one_apm/support/rename_rules_engine.rb +39 -0
  49. data/lib/one_apm/support/rename_rules_engine/external_rename_rule.rb +84 -0
  50. data/lib/one_apm/support/rename_rules_engine/match_expression/base.rb +46 -0
  51. data/lib/one_apm/support/rename_rules_engine/match_expression/engine.rb +35 -0
  52. data/lib/one_apm/support/rename_rules_engine/match_expression/method.rb +20 -0
  53. data/lib/one_apm/support/rename_rules_engine/match_expression/split_object.rb +19 -0
  54. data/lib/one_apm/support/rename_rules_engine/match_expression/url.rb +19 -0
  55. data/lib/one_apm/support/rename_rules_engine/rename/base.rb +25 -0
  56. data/lib/one_apm/support/rename_rules_engine/rename/engine.rb +36 -0
  57. data/lib/one_apm/support/rename_rules_engine/rename/header.rb +17 -0
  58. data/lib/one_apm/support/rename_rules_engine/rename/parameter.rb +18 -0
  59. data/lib/one_apm/support/rename_rules_engine/rename/segment.rb +41 -0
  60. data/lib/one_apm/transaction.rb +11 -2
  61. data/lib/one_apm/transaction/class_methods.rb +3 -3
  62. data/lib/one_apm/transaction/event_analytic_data.rb +51 -0
  63. data/lib/one_apm/transaction/event_analytic_sample.rb +35 -0
  64. data/lib/one_apm/transaction/instance_helpers.rb +1 -1
  65. data/lib/one_apm/transaction/sample_buffer/cross_sample_buffer.rb +47 -0
  66. data/lib/one_apm/transaction/segment.rb +2 -1
  67. data/lib/one_apm/transaction/transaction_finish_append.rb +4 -0
  68. data/lib/one_apm/transaction/transaction_name.rb +1 -1
  69. data/lib/one_apm/transaction/transaction_sample.rb +12 -7
  70. data/lib/one_apm/version.rb +2 -2
  71. data/lib/sequel/extensions/oneapm_instrumentation.rb +16 -9
  72. data/lib/sequel/plugins/oneapm_instrumentation.rb +3 -2
  73. data/oneapm_rpm.gemspec +2 -1
  74. 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
- def metric_for_name(name)
10
- return unless name && name.respond_to?(:split)
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
- if parts.size == 2
13
- model = parts.first
14
- operation = parts.last.downcase
15
- case operation
16
- when 'find', 'load', 'count', 'exists'
17
- op_name = 'select'
18
- when 'destroy'
19
- op_name = 'delete'
20
- when 'create'
21
- op_name = 'insert'
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
- op_name = 'update'
83
+ 'update'
84
+ when 'other'
85
+ 'other'
24
86
  else
25
- op_name = nil
87
+ nil
26
88
  end
27
- "Database/#{model}/#{op_name}" if op_name
28
- end
89
+ op_name
29
90
  end
30
91
 
31
- def metric_for_sql(sql)
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
- metric
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
- # Given a metric name such as "Database/model/action" this
47
- # returns an array of rollup metrics:
48
- # [ "Database/all", "Database/all", "Database/action" ]
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
- metrics
116
+ def database_type(product)
117
+ product.split(':')[0]
65
118
  end
66
119
 
67
- # Given a database adapter name and a database server host
68
- # this returns a metric name in the form:
69
- # "RemoteService/sql/adapter/host"
70
- # Host defaults to "localhost".
71
- def remote_service_metric(adapter, host)
72
- host ||= 'localhost'
73
- type = adapter.to_s.sub(/\d*/, '')
74
- "RemoteService/sql/#{type}/#{host}"
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
- def self.statement_metric_for(product, collection, operation)
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/#{product}/all"
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 = 'HTTP_X_ONEAPM_SYNTHETICS'.freeze
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
- metric_data_array << metric_data
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], 'CONTENT-ENCODING' => opts[:encoding], 'HOST' => opts[:collector].name)
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
- request.content_type = "multipart/form-data; boundary=-oneapm-#{request.object_id}-"
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