newrelic_rpm 3.7.0.177 → 3.7.1.180

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data.tar.gz.sig +0 -0
  2. data/CHANGELOG +28 -1
  3. data/lib/new_relic/agent.rb +1 -2
  4. data/lib/new_relic/agent/agent.rb +28 -10
  5. data/lib/new_relic/agent/agent_logger.rb +4 -3
  6. data/lib/new_relic/agent/audit_logger.rb +5 -8
  7. data/lib/new_relic/agent/configuration/default_source.rb +24 -0
  8. data/lib/new_relic/agent/cross_app_tracing.rb +21 -15
  9. data/lib/new_relic/agent/datastores/mongo.rb +25 -0
  10. data/lib/new_relic/agent/datastores/mongo/metric_generator.rb +25 -0
  11. data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +189 -0
  12. data/lib/new_relic/agent/datastores/mongo/obfuscator.rb +39 -0
  13. data/lib/new_relic/agent/datastores/mongo/statement_formatter.rb +52 -0
  14. data/lib/new_relic/agent/harvester.rb +55 -0
  15. data/lib/new_relic/agent/instrumentation/mongo.rb +139 -0
  16. data/lib/new_relic/agent/instrumentation/net.rb +6 -11
  17. data/lib/new_relic/agent/supported_versions.rb +9 -5
  18. data/lib/new_relic/agent/transaction_sampler.rb +4 -0
  19. data/lib/new_relic/version.rb +1 -1
  20. data/lib/tasks/versions.rake +1 -1
  21. data/test/agent_helper.rb +4 -0
  22. data/test/environments/norails/Gemfile +3 -0
  23. data/test/environments/rails40/Gemfile +5 -1
  24. data/test/flaky_proxy/Gemfile +3 -0
  25. data/test/flaky_proxy/README.md +82 -0
  26. data/test/flaky_proxy/lib/flaky_proxy.rb +22 -0
  27. data/test/flaky_proxy/lib/flaky_proxy/connection.rb +45 -0
  28. data/test/flaky_proxy/lib/flaky_proxy/http_message.rb +105 -0
  29. data/test/flaky_proxy/lib/flaky_proxy/proxy.rb +42 -0
  30. data/test/flaky_proxy/lib/flaky_proxy/rule.rb +75 -0
  31. data/test/flaky_proxy/lib/flaky_proxy/rule_set.rb +37 -0
  32. data/test/flaky_proxy/lib/flaky_proxy/server.rb +22 -0
  33. data/test/flaky_proxy/script/flaky_proxy +39 -0
  34. data/test/helpers/exceptions.rb +16 -0
  35. data/test/helpers/mongo_metric_builder.rb +29 -0
  36. data/test/multiverse/lib/multiverse/suite.rb +1 -0
  37. data/test/multiverse/suites/curb/curb_test.rb +0 -1
  38. data/test/multiverse/suites/deferred_instrumentation/sinatra_test.rb +4 -3
  39. data/test/multiverse/suites/excon/excon_test.rb +0 -1
  40. data/test/multiverse/suites/httpclient/httpclient_test.rb +0 -1
  41. data/test/multiverse/suites/mongo/Envfile +66 -0
  42. data/test/multiverse/suites/mongo/config/newrelic.yml +19 -0
  43. data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +418 -0
  44. data/test/multiverse/suites/mongo/mongo_unsupported_version_test.rb +36 -0
  45. data/test/multiverse/suites/net_http/net_http_test.rb +2 -4
  46. data/test/multiverse/suites/rails/Envfile +4 -4
  47. data/test/multiverse/suites/rails/config/newrelic.yml +1 -1
  48. data/test/multiverse/suites/rails/error_tracing_test.rb +7 -7
  49. data/test/multiverse/suites/sidekiq/Envfile +1 -1
  50. data/test/multiverse/suites/sidekiq/sidekiq_instrumentation_test.rb +0 -1
  51. data/test/multiverse/suites/sinatra/sinatra_classic_test.rb +5 -3
  52. data/test/multiverse/suites/sinatra/sinatra_modular_test.rb +5 -3
  53. data/test/multiverse/suites/typhoeus/typhoeus_test.rb +0 -1
  54. data/test/new_relic/agent/agent_logger_test.rb +9 -1
  55. data/test/new_relic/agent/agent_test.rb +66 -1
  56. data/test/new_relic/agent/agent_test_controller.rb +1 -2
  57. data/test/new_relic/agent/audit_logger_test.rb +12 -4
  58. data/test/new_relic/agent/configuration/orphan_configuration_test.rb +11 -2
  59. data/test/new_relic/agent/cpu_sampler_test.rb +1 -0
  60. data/test/new_relic/agent/cross_app_tracing_test.rb +60 -0
  61. data/test/new_relic/agent/datastores/mongo/metric_generator_test.rb +43 -0
  62. data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +301 -0
  63. data/test/new_relic/agent/datastores/mongo/obfuscator_test.rb +91 -0
  64. data/test/new_relic/agent/datastores/mongo/statement_formatter_test.rb +71 -0
  65. data/test/new_relic/agent/harvester_test.rb +85 -0
  66. data/test/new_relic/agent/transaction_sampler_test.rb +5 -0
  67. data/test/new_relic/agent/worker_loop_test.rb +3 -5
  68. data/test/new_relic/http_client_test_cases.rb +65 -81
  69. data/test/new_relic/noticed_error_test.rb +14 -16
  70. data/test/performance/lib/performance.rb +1 -0
  71. data/test/performance/lib/performance/console_reporter.rb +6 -2
  72. data/test/performance/lib/performance/instrumentor.rb +1 -15
  73. data/test/performance/lib/performance/platform.rb +35 -0
  74. data/test/performance/lib/performance/test_case.rb +16 -1
  75. data/test/performance/suites/marshalling.rb +73 -0
  76. metadata +48 -19
  77. metadata.gz.sig +1 -2
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ $: << File.expand_path(File.dirname(__FILE__))
6
+
7
+ require 'logger'
8
+
9
+ require 'flaky_proxy/server'
10
+ require 'flaky_proxy/connection'
11
+ require 'flaky_proxy/http_message'
12
+ require 'flaky_proxy/rule'
13
+ require 'flaky_proxy/rule_set'
14
+ require 'flaky_proxy/proxy'
15
+
16
+ module FlakyProxy
17
+ @logger = Logger.new($stderr)
18
+
19
+ def self.logger
20
+ @logger
21
+ end
22
+ end
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ module FlakyProxy
6
+ class Connection
7
+ def initialize(client_socket, server, rules)
8
+ @client_socket = client_socket
9
+ @server_socket = nil
10
+ @server = server
11
+ @rules = rules
12
+ end
13
+
14
+ def client_socket
15
+ @client_socket
16
+ end
17
+
18
+ def server_socket
19
+ @server_socket ||= @server.open_socket
20
+ end
21
+
22
+ def shutdown
23
+ @client_socket.close if @client_socket && !@client_socket.closed?
24
+ @server_socket.close if @server_socket && !@server_socket.closed?
25
+ @shutdown = true
26
+ end
27
+
28
+ def service
29
+ loop do
30
+ service_one
31
+ break if @shutdown
32
+ end
33
+ end
34
+
35
+ def service_one
36
+ request = Request.read_from(client_socket)
37
+ if request.complete?
38
+ rule = @rules.match(request)
39
+ rule.evaluate(request, self)
40
+ else
41
+ shutdown
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'http/parser'
6
+ require 'webrick'
7
+
8
+ module FlakyProxy
9
+ MAXBUF = 10 * 4096 # 40KB
10
+
11
+ class HttpMessage
12
+ def self.read_from(io)
13
+ msg = self.new
14
+ msg.read(io)
15
+ msg
16
+ end
17
+
18
+ attr_reader :raw_data
19
+
20
+ def initialize
21
+ @parser = Http::Parser.new
22
+ @raw_data = ''
23
+ @complete = false
24
+ @parser.on_message_complete = proc do |env|
25
+ @complete = true
26
+ end
27
+ end
28
+
29
+ def request_url
30
+ @parser.request_url if complete?
31
+ end
32
+
33
+ def request_path
34
+ @parser.request_path if complete?
35
+ end
36
+
37
+ def <<(data)
38
+ @raw_data << data
39
+ @parser << data
40
+ end
41
+
42
+ def read(io)
43
+ loop do
44
+ return if complete? || io.closed?
45
+ ready = select([io])
46
+ if ready && ready.first.include?(io)
47
+ if io.eof?
48
+ return
49
+ else
50
+ self << io.readpartial(MAXBUF)
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ def complete?
57
+ @complete
58
+ end
59
+
60
+ def relay_to(io)
61
+ io.write(@raw_data)
62
+ end
63
+ end
64
+
65
+ class Request < HttpMessage
66
+ def request_method
67
+ @parser.http_method
68
+ end
69
+ end
70
+
71
+ class Response < HttpMessage
72
+ def self.build(options={})
73
+ defaults = {
74
+ :status => 200,
75
+ :headers => {},
76
+ :body => ''
77
+ }
78
+ options = defaults.merge(options)
79
+ status_line = build_status_line(options[:status])
80
+ headers = build_headers(options[:body], options[:headers])
81
+
82
+ rsp = self.new
83
+ rsp << status_line
84
+ rsp << headers
85
+ rsp << "\r\n"
86
+ rsp << options[:body]
87
+ rsp
88
+ end
89
+
90
+ def self.build_status_line(status)
91
+ status_text = WEBrick::HTTPStatus::StatusMessage[status]
92
+ "HTTP/1.1 #{status} #{status_text}\r\n"
93
+ end
94
+
95
+ def self.build_headers(body, headers)
96
+ default_headers = {
97
+ 'Content-Length' => body.bytesize
98
+ }
99
+ headers = default_headers.merge(headers)
100
+ headers.map do |key, value|
101
+ "#{key}: #{value}\r\n"
102
+ end.join
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'socket'
6
+
7
+ module FlakyProxy
8
+ class Proxy
9
+ def initialize(options)
10
+ @listen_host = options.fetch(:listen_host)
11
+ @listen_port = options.fetch(:listen_port)
12
+ @backend_server = Server.new(options.fetch(:target_host), options.fetch(:target_port))
13
+ @rules = RuleSet.build('')
14
+ @rules_path = options[:rules_path]
15
+ @listen_socket = nil
16
+ end
17
+
18
+ def reload_rules_file
19
+ if @rules_path
20
+ mtime = File.stat(@rules_path).mtime
21
+ if @last_rules_mtime.nil? || mtime > @last_rules_mtime
22
+ FlakyProxy.logger.info("Reloading rules file at #{@rules_path}")
23
+ @rules = RuleSet.build(File.read(@rules_path))
24
+ @last_rules_mtime = mtime
25
+ end
26
+ end
27
+ end
28
+
29
+ def run
30
+ FlakyProxy.logger.info("Starting FlakyProxy on #{@listen_host}:#{@listen_port} -> #{@backend_server.to_s}")
31
+ @listen_socket = TCPServer.new(@listen_host, @listen_port)
32
+ loop do
33
+ client_socket = @listen_socket.accept
34
+ reload_rules_file
35
+ FlakyProxy.logger.info("Accepted connection from #{client_socket}")
36
+ connection = Connection.new(client_socket, @backend_server, @rules)
37
+ connection.service
38
+ FlakyProxy.logger.info("Finished servicing connection from #{client_socket}")
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,75 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ module FlakyProxy
6
+ class Rule
7
+ class ActionBuilder
8
+ def initialize(rule)
9
+ @actions = []
10
+ @rule = rule
11
+ end
12
+
13
+ def pass
14
+ @rule.actions << [:pass]
15
+ end
16
+
17
+ def respond(response_spec)
18
+ @rule.actions << [:respond, response_spec]
19
+ end
20
+
21
+ def delay(amount)
22
+ @rule.actions << [:delay, amount]
23
+ end
24
+
25
+ def close
26
+ @rule.actions << [:close]
27
+ end
28
+ end
29
+
30
+ attr_reader :actions
31
+
32
+ def initialize(url_regex=nil, &blk)
33
+ @url_regex = url_regex
34
+ @actions = []
35
+ ActionBuilder.new(self).instance_eval(&blk)
36
+ end
37
+
38
+ def match?(request)
39
+ @url_regex.nil? || @url_regex.match(request.request_url)
40
+ end
41
+
42
+ def next_action
43
+ if @actions.size > 1
44
+ @actions.shift
45
+ else
46
+ @actions.last
47
+ end
48
+ end
49
+
50
+ def relay(request, connection)
51
+ request.relay_to(connection.server_socket)
52
+ response = Response.read_from(connection.server_socket)
53
+ response.relay_to(connection.client_socket)
54
+ end
55
+
56
+ def evaluate(request, connection)
57
+ action, *params = next_action
58
+ FlakyProxy.logger.info(" [#{action.upcase}] #{request.request_method} #{request.request_url}")
59
+ case action
60
+ when :pass
61
+ relay(request, connection)
62
+ when :respond
63
+ response_spec = params.first
64
+ response = Response.build(response_spec)
65
+ response.relay_to(connection.client_socket)
66
+ when :delay
67
+ amount = params.first
68
+ sleep(amount)
69
+ relay(request, connection)
70
+ when :close
71
+ connection.client_socket.close
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ module FlakyProxy
6
+ class RuleSet
7
+ class Builder
8
+ attr_reader :rules
9
+
10
+ def initialize(ruleset, &blk)
11
+ @ruleset = ruleset
12
+ @rules = []
13
+ end
14
+
15
+ def match(criteria, &blk)
16
+ @ruleset.rules << Rule.new(criteria, &blk)
17
+ end
18
+ end
19
+
20
+ def self.build(text=nil, &blk)
21
+ ruleset = self.new
22
+ Builder.new(ruleset).instance_eval(text, &blk)
23
+ ruleset
24
+ end
25
+
26
+ attr_accessor :rules
27
+
28
+ def initialize
29
+ @rules = []
30
+ @default_rule = Rule.new { pass }
31
+ end
32
+
33
+ def match(request)
34
+ @rules.detect { |rule| rule.match?(request) } || @default_rule
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ module FlakyProxy
6
+ class Server
7
+ attr_reader :host, :port
8
+
9
+ def initialize(host, port)
10
+ @host = host
11
+ @port = port
12
+ end
13
+
14
+ def open_socket
15
+ TCPSocket.new(@host, @port)
16
+ end
17
+
18
+ def to_s
19
+ "#{@host}:#{@port}"
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,39 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'flaky_proxy')
5
+
6
+ DEFAULTS = {
7
+ :listen_host => 'localhost',
8
+ :listen_port => 8888,
9
+ :target_host => 'localhost',
10
+ :target_port => 8081
11
+ }
12
+
13
+ options = DEFAULTS.dup
14
+ parser = OptionParser.new do |opts|
15
+ opts.banner = "Usage: #{$0} [options] [<rules file>]"
16
+
17
+ opts.on("-l", "--listen [<HOST>:]<PORT>", "Specify the host and port to listen on") do |listen_spec|
18
+ if listen_spec =~ /^([^:]+):(\d+)$/
19
+ options[:listen_host] = $1
20
+ options[:listen_port] = $2.to_i
21
+ else
22
+ options[:listen_port] = listen_spec.to_i
23
+ end
24
+ end
25
+
26
+ opts.on("-t", "--target [<HOST>:]<PORT>", "Specify the host and port to forward to") do |target_spec|
27
+ if target_spec =~ /^([^:]+):(\d+)$/
28
+ options[:target_host] = $1
29
+ options[:target_port] = $2
30
+ else
31
+ options[:target_port] = target_spec.to_i
32
+ end
33
+ end
34
+ end
35
+ parser.parse!
36
+
37
+ options[:rules_path] = ARGV[0] if ARGV[0]
38
+
39
+ FlakyProxy::Proxy.new(options).run
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ module NewRelic
6
+ module TestHelpers
7
+ module Exceptions
8
+ class TestError < StandardError; end
9
+ class IgnoredError < StandardError; end
10
+ class ServerIgnoredError < StandardError; end
11
+ class TestRuntimeError < RuntimeError; end
12
+ class ParentException < Exception; end
13
+ class ChildException < ParentException; end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,29 @@
1
+ # encoding: utf-8
2
+ # This file is distributed under New Relic's license terms.
3
+ # See https://github.com/newrelic/rpm/blob/master/LICENSE for complete details.
4
+
5
+ require 'new_relic/agent/datastores/mongo/metric_translator'
6
+
7
+ module NewRelic
8
+ module TestHelpers
9
+ module MongoMetricBuilder
10
+ def build_test_metrics(name, request_type = :web)
11
+ NewRelic::Agent::Datastores::Mongo::MetricTranslator.build_metrics(
12
+ name,
13
+ @collection_name,
14
+ request_type
15
+ )
16
+ end
17
+
18
+ def metrics_with_attributes(metrics, attributes)
19
+ metric_attributes = {}
20
+
21
+ metrics.each do |metric|
22
+ metric_attributes[metric] = attributes
23
+ end
24
+
25
+ metric_attributes
26
+ end
27
+ end
28
+ end
29
+ end