newrelic_rpm 3.16.0.318 → 3.16.1.320
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -4
- data/CHANGELOG +41 -2
- data/lib/new_relic/agent/database.rb +15 -4
- data/lib/new_relic/agent/database/explain_plan_helpers.rb +2 -1
- data/lib/new_relic/agent/datastores.rb +13 -13
- data/lib/new_relic/agent/datastores/metric_helper.rb +33 -2
- data/lib/new_relic/agent/datastores/mongo/metric_translator.rb +3 -9
- data/lib/new_relic/agent/error_collector.rb +2 -2
- data/lib/new_relic/agent/instrumentation/active_record.rb +9 -19
- data/lib/new_relic/agent/instrumentation/active_record_helper.rb +2 -6
- data/lib/new_relic/agent/instrumentation/active_record_subscriber.rb +49 -40
- data/lib/new_relic/agent/instrumentation/data_mapper.rb +29 -23
- data/lib/new_relic/agent/instrumentation/grape.rb +20 -11
- data/lib/new_relic/agent/instrumentation/memcache.rb +8 -10
- data/lib/new_relic/agent/instrumentation/mongo.rb +25 -16
- data/lib/new_relic/agent/instrumentation/mongodb_command_subscriber.rb +14 -19
- data/lib/new_relic/agent/method_tracer_helpers.rb +4 -8
- data/lib/new_relic/agent/sql_sampler.rb +14 -1
- data/lib/new_relic/agent/stats_engine/metric_stats.rb +18 -0
- data/lib/new_relic/agent/supported_versions.rb +2 -3
- data/lib/new_relic/agent/traced_method_stack.rb +7 -1
- data/lib/new_relic/agent/transaction.rb +6 -0
- data/lib/new_relic/agent/transaction/abstract_segment.rb +73 -0
- data/lib/new_relic/agent/transaction/datastore_segment.rb +49 -0
- data/lib/new_relic/agent/transaction/segment.rb +30 -0
- data/lib/new_relic/agent/transaction/tracing.rb +53 -0
- data/lib/new_relic/agent/transaction_sampler.rb +8 -1
- data/lib/new_relic/noticed_error.rb +3 -1
- data/lib/new_relic/version.rb +1 -1
- data/lib/sequel/extensions/newrelic_instrumentation.rb +22 -15
- data/lib/sequel/plugins/newrelic_instrumentation.rb +4 -3
- data/newrelic_rpm.gemspec +1 -9
- data/test/environments/lib/environments/runner.rb +6 -4
- data/test/environments/norails/Gemfile +9 -3
- data/test/environments/rails21/Gemfile +6 -3
- data/test/environments/rails22/Gemfile +5 -2
- data/test/environments/rails23/Gemfile +1 -1
- data/test/environments/rails30/Gemfile +1 -1
- data/test/environments/rails31/Gemfile +1 -1
- data/test/environments/rails32/Gemfile +1 -1
- data/test/environments/rails40/Gemfile +2 -2
- data/test/environments/rails41/Gemfile +2 -2
- data/test/environments/rails42/Gemfile +2 -2
- data/test/environments/rails50/Gemfile +2 -2
- data/test/helpers/mongo_metric_builder.rb +3 -4
- data/test/multiverse/lib/multiverse/shell_utils.rb +27 -0
- data/test/multiverse/lib/multiverse/suite.rb +47 -2
- data/test/multiverse/suites/active_record/Envfile +1 -1
- data/test/multiverse/suites/delayed_job/Envfile +2 -0
- data/test/multiverse/suites/grape/grape_versioning_test.rb +55 -1
- data/test/multiverse/suites/grape/grape_versioning_test_api.rb +61 -3
- data/test/multiverse/suites/mongo/mongo_instrumentation_test.rb +18 -0
- data/test/multiverse/suites/rails/Envfile +3 -3
- data/test/multiverse/suites/rails/error_tracing_test.rb +2 -2
- data/test/multiverse/suites/sequel/Envfile +7 -0
- data/test/multiverse/suites/sequel/sequel_extension_test.rb +1 -1
- data/test/new_relic/agent/database_test.rb +9 -0
- data/test/new_relic/agent/datastores/metric_helper_test.rb +76 -43
- data/test/new_relic/agent/datastores/mongo/metric_translator_test.rb +67 -117
- data/test/new_relic/agent/datastores_test.rb +17 -0
- data/test/new_relic/agent/error_collector_test.rb +21 -5
- data/test/new_relic/agent/instrumentation/active_record_helper_test.rb +40 -45
- data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +2 -3
- data/test/new_relic/agent/instrumentation/mongodb_command_subscriber_test.rb +2 -0
- data/test/new_relic/agent/method_tracer_test.rb +54 -52
- data/test/new_relic/agent/mock_scope_listener.rb +4 -1
- data/test/new_relic/agent/sql_sampler_test.rb +15 -0
- data/test/new_relic/agent/transaction/abstract_segment_test.rb +94 -0
- data/test/new_relic/agent/transaction/datastore_segment_test.rb +99 -0
- data/test/new_relic/agent/transaction/segment_test.rb +53 -0
- data/test/new_relic/agent/transaction/tracing_test.rb +121 -0
- data/test/new_relic/agent/transaction_sampler_test.rb +13 -0
- data/test/new_relic/noticed_error_test.rb +7 -0
- data/test/performance/suites/datastores.rb +59 -0
- data/test/performance/suites/trace_execution_scoped.rb +8 -9
- metadata +13 -46
@@ -0,0 +1,73 @@
|
|
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 Agent
|
7
|
+
class Transaction
|
8
|
+
class AbstractSegment
|
9
|
+
attr_reader :start_time, :end_time, :duration, :exclusive_duration
|
10
|
+
attr_accessor :name, :children_time, :transaction
|
11
|
+
|
12
|
+
def initialize name
|
13
|
+
@name = name
|
14
|
+
@children_time = 0.0
|
15
|
+
@record_metrics = true
|
16
|
+
@transaction = nil
|
17
|
+
end
|
18
|
+
|
19
|
+
def start
|
20
|
+
@start_time = Time.now
|
21
|
+
end
|
22
|
+
|
23
|
+
def finish
|
24
|
+
@end_time = Time.now
|
25
|
+
@duration = end_time.to_f - start_time.to_f
|
26
|
+
@exclusive_duration = duration - children_time
|
27
|
+
record_metrics if record_metrics?
|
28
|
+
segment_complete
|
29
|
+
@transaction.segment_complete self if transaction
|
30
|
+
rescue => e
|
31
|
+
# This rescue block was added for the benefit of this test:
|
32
|
+
# test/multiverse/suites/bare/standalone_instrumentation_test.rb
|
33
|
+
# See the top of the test for details.
|
34
|
+
NewRelic::Agent.logger.error "Exception finishing segment: #{name}", e
|
35
|
+
end
|
36
|
+
|
37
|
+
def record_metrics?
|
38
|
+
@record_metrics
|
39
|
+
end
|
40
|
+
|
41
|
+
def record_metrics= value
|
42
|
+
@record_metrics = value
|
43
|
+
end
|
44
|
+
|
45
|
+
def record_metrics
|
46
|
+
raise NotImplementedError, "Subclasses must implement record_metrics"
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
# callback for subclasses to override
|
52
|
+
def segment_complete
|
53
|
+
end
|
54
|
+
|
55
|
+
def metric_cache
|
56
|
+
if transaction
|
57
|
+
transaction.metrics
|
58
|
+
else
|
59
|
+
NewRelic::Agent.instance.stats_engine
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def transaction_state
|
64
|
+
@transaction_state ||= if @transaction
|
65
|
+
transaction.state
|
66
|
+
else
|
67
|
+
TransactionState.tl_get
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,49 @@
|
|
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/transaction/segment'
|
6
|
+
require 'new_relic/agent/datastores/metric_helper'
|
7
|
+
require 'new_relic/agent/database'
|
8
|
+
|
9
|
+
module NewRelic
|
10
|
+
module Agent
|
11
|
+
class Transaction
|
12
|
+
class DatastoreSegment < Segment
|
13
|
+
attr_reader :product, :operation, :collection, :sql_statement
|
14
|
+
|
15
|
+
def initialize product, operation, collection = nil
|
16
|
+
@product = product
|
17
|
+
@operation = operation
|
18
|
+
@collection = collection
|
19
|
+
@sql_statement = nil
|
20
|
+
super Datastores::MetricHelper.scoped_metric_for(product, operation, collection),
|
21
|
+
Datastores::MetricHelper.unscoped_metrics_for(product, operation, collection)
|
22
|
+
end
|
23
|
+
|
24
|
+
def notice_sql sql
|
25
|
+
_notice_sql sql
|
26
|
+
end
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
def _notice_sql sql, config=nil, explainer=nil, binds=nil, name=nil
|
30
|
+
return unless record_sql?
|
31
|
+
@sql_statement = Database::Statement.new sql, config, explainer, binds, name
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def segment_complete
|
37
|
+
return unless sql_statement
|
38
|
+
|
39
|
+
NewRelic::Agent.instance.transaction_sampler.notice_sql_statement(sql_statement, duration)
|
40
|
+
NewRelic::Agent.instance.sql_sampler.notice_sql_statement(sql_statement.dup, name, duration)
|
41
|
+
end
|
42
|
+
|
43
|
+
def record_sql?
|
44
|
+
transaction_state.is_sql_recorded?
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,30 @@
|
|
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/transaction/abstract_segment'
|
6
|
+
|
7
|
+
module NewRelic
|
8
|
+
module Agent
|
9
|
+
class Transaction
|
10
|
+
class Segment < AbstractSegment
|
11
|
+
# unscoped_metrics can be nil, a string, or array. we do this to save
|
12
|
+
# object allocations. if allocations weren't important then we would
|
13
|
+
# initialize it as an array that would be empty, have one item, or many items.
|
14
|
+
attr_reader :unscoped_metrics
|
15
|
+
|
16
|
+
def initialize name, unscoped_metrics=nil
|
17
|
+
@unscoped_metrics = unscoped_metrics
|
18
|
+
super name
|
19
|
+
end
|
20
|
+
|
21
|
+
def record_metrics
|
22
|
+
metric_cache.record_scoped_and_unscoped name, duration, exclusive_duration
|
23
|
+
if unscoped_metrics
|
24
|
+
metric_cache.record_unscoped unscoped_metrics, duration, exclusive_duration
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,53 @@
|
|
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/transaction/segment'
|
6
|
+
require 'new_relic/agent/transaction/datastore_segment'
|
7
|
+
|
8
|
+
module NewRelic
|
9
|
+
module Agent
|
10
|
+
class Transaction
|
11
|
+
module Tracing
|
12
|
+
module ClassMethods
|
13
|
+
def start_segment name, unscoped_metrics=nil
|
14
|
+
segment = Segment.new name, unscoped_metrics
|
15
|
+
segment.start
|
16
|
+
add_segment segment
|
17
|
+
segment
|
18
|
+
end
|
19
|
+
|
20
|
+
def start_datastore_segment product, operation, collection=nil
|
21
|
+
segment = DatastoreSegment.new product, operation, collection
|
22
|
+
segment.start
|
23
|
+
add_segment segment
|
24
|
+
segment
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def add_segment segment
|
30
|
+
state = NewRelic::Agent::TransactionState.tl_get
|
31
|
+
segment.record_metrics = state.is_execution_traced?
|
32
|
+
if (txn = state.current_transaction) && state.is_execution_traced?
|
33
|
+
txn.add_segment segment
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.included base
|
39
|
+
base.extend ClassMethods
|
40
|
+
end
|
41
|
+
|
42
|
+
def add_segment segment
|
43
|
+
segment.transaction = self
|
44
|
+
state.traced_method_stack.push_segment state, segment
|
45
|
+
end
|
46
|
+
|
47
|
+
def segment_complete segment
|
48
|
+
state.traced_method_stack.pop_frame(state, segment, segment.name, segment.end_time, segment.record_metrics?)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -183,7 +183,7 @@ module NewRelic
|
|
183
183
|
# @api public
|
184
184
|
# @deprecated Use {Datastores.notice_sql} instead.
|
185
185
|
#
|
186
|
-
def notice_sql(sql, config, duration, state=nil, explainer=nil, binds=
|
186
|
+
def notice_sql(sql, config, duration, state=nil, explainer=nil, binds=nil, name=nil) #THREAD_LOCAL_ACCESS sometimes
|
187
187
|
# some statements (particularly INSERTS with large BLOBS
|
188
188
|
# may be very large; we should trim them to a maximum usable length
|
189
189
|
state ||= TransactionState.tl_get
|
@@ -194,6 +194,13 @@ module NewRelic
|
|
194
194
|
end
|
195
195
|
end
|
196
196
|
|
197
|
+
|
198
|
+
def notice_sql_statement(statement, duration) #THREAD_LOCAL_ACCESS sometimes
|
199
|
+
state ||= TransactionState.tl_get
|
200
|
+
builder = state.transaction_sample_builder
|
201
|
+
notice_extra_data(builder, statement, duration, :sql)
|
202
|
+
end
|
203
|
+
|
197
204
|
# Attaches an additional non-SQL query parameter to the current
|
198
205
|
# transaction trace node.
|
199
206
|
#
|
@@ -30,7 +30,9 @@ class NewRelic::NoticedError
|
|
30
30
|
|
31
31
|
if exception.nil?
|
32
32
|
@message = '<no message>'
|
33
|
-
elsif exception.respond_to?(
|
33
|
+
elsif exception.respond_to?(:cause)
|
34
|
+
@message = (exception.cause || exception).to_s
|
35
|
+
elsif exception.respond_to?(:original_exception)
|
34
36
|
@message = (exception.original_exception || exception).to_s
|
35
37
|
else # exception is not nil, but does not respond to original_exception
|
36
38
|
@message = exception.to_s
|
data/lib/new_relic/version.rb
CHANGED
@@ -32,30 +32,37 @@ module Sequel
|
|
32
32
|
#
|
33
33
|
module NewRelicInstrumentation
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
NewRelic::Agent::MethodTracer.trace_execution_scoped(metrics) do
|
43
|
-
t0 = Time.now
|
44
|
-
begin
|
45
|
-
rval = super
|
46
|
-
ensure
|
47
|
-
notice_sql(sql, scoped_metric, args, t0, Time.now)
|
35
|
+
module Naming
|
36
|
+
def self.query_method_name
|
37
|
+
if Sequel::VERSION >= "4.35.0"
|
38
|
+
:log_connection_yield
|
39
|
+
else
|
40
|
+
:log_yield
|
48
41
|
end
|
49
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
define_method Naming.query_method_name do |*args, &blk| #THREAD_LOCAL_ACCESS
|
46
|
+
sql = args.first
|
50
47
|
|
51
|
-
|
48
|
+
product = NewRelic::Agent::Instrumentation::SequelHelper.product_name_from_adapter(self.class.adapter_scheme)
|
49
|
+
operation = NewRelic::Agent::Datastores::MetricHelper.operation_from_sql(sql)
|
50
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment product, operation
|
51
|
+
|
52
|
+
begin
|
53
|
+
super(*args, &blk)
|
54
|
+
ensure
|
55
|
+
notice_sql(sql, segment.name, segment.start_time, Time.now)
|
56
|
+
segment.finish
|
57
|
+
end
|
52
58
|
end
|
53
59
|
|
60
|
+
|
54
61
|
THREAD_SAFE_CONNECTION_POOL_CLASSES = [
|
55
62
|
(defined?(::Sequel::ThreadedConnectionPool) && ::Sequel::ThreadedConnectionPool)
|
56
63
|
].freeze
|
57
64
|
|
58
|
-
def notice_sql(sql, metric_name,
|
65
|
+
def notice_sql(sql, metric_name, start, finish)
|
59
66
|
state = NewRelic::Agent::TransactionState.tl_get
|
60
67
|
duration = finish - start
|
61
68
|
|
@@ -22,12 +22,13 @@ module Sequel
|
|
22
22
|
def wrap_sequel_method(method_name, operation_name=method_name)
|
23
23
|
define_method(method_name) do |*args, &block|
|
24
24
|
klass = self.is_a?(Class) ? self : self.class
|
25
|
-
|
26
25
|
product = NewRelic::Agent::Instrumentation::SequelHelper.product_name_from_adapter(db.adapter_scheme)
|
27
|
-
|
26
|
+
segment = NewRelic::Agent::Transaction.start_datastore_segment(product, operation_name, klass.name)
|
28
27
|
|
29
|
-
|
28
|
+
begin
|
30
29
|
NewRelic::Agent.disable_all_tracing { super(*args, &block) }
|
30
|
+
ensure
|
31
|
+
segment.finish
|
31
32
|
end
|
32
33
|
end
|
33
34
|
end
|
data/newrelic_rpm.gemspec
CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.version = NewRelic::VERSION::STRING
|
11
11
|
s.required_ruby_version = '>= 1.8.7'
|
12
12
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1") if s.respond_to? :required_rubygems_version=
|
13
|
-
s.authors = [ "Tim Krajcar", "Matthew Wear", "Katherine Wu", "
|
13
|
+
s.authors = [ "Tim Krajcar", "Matthew Wear", "Katherine Wu", "Caito Scherr", "Kenichi Nakamura" ]
|
14
14
|
s.date = Time.now.strftime('%Y-%m-%d')
|
15
15
|
s.licenses = ['New Relic', 'MIT', 'Ruby']
|
16
16
|
s.description = <<-EOS
|
@@ -49,14 +49,6 @@ EOS
|
|
49
49
|
s.add_development_dependency 'pry', '~> 0.9.12'
|
50
50
|
s.add_development_dependency 'hometown', '~> 0.2.5'
|
51
51
|
|
52
|
-
# Only let Guard run on newer Rubies
|
53
|
-
if RUBY_VERSION >= "1.9.3"
|
54
|
-
s.add_development_dependency 'guard'
|
55
|
-
s.add_development_dependency 'listen', '< 3.1' if RUBY_VERSION < "2.2.3"
|
56
|
-
s.add_development_dependency 'guard-minitest'
|
57
|
-
s.add_development_dependency 'rb-fsevent'
|
58
|
-
end
|
59
|
-
|
60
52
|
# rack-cache ~> 1.2 is specified by actionpack 3.2, but rack-cache 1.3.1 only works on Ruby 1.9.3 & newer. :(
|
61
53
|
# https://github.com/rtomayko/rack-cache/issues/124
|
62
54
|
if RUBY_VERSION < "1.9.3"
|
@@ -5,6 +5,7 @@
|
|
5
5
|
require 'bundler'
|
6
6
|
|
7
7
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'multiverse', 'lib', 'multiverse', 'color'))
|
8
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', '..', 'multiverse', 'lib', 'multiverse', 'shell_utils'))
|
8
9
|
|
9
10
|
module Environments
|
10
11
|
class Runner
|
@@ -94,14 +95,15 @@ module Environments
|
|
94
95
|
|
95
96
|
def bundle(dir)
|
96
97
|
puts "Bundling in #{dir}..."
|
97
|
-
|
98
|
+
result = `cd #{dir} && bundle install --local`
|
98
99
|
unless $?.success?
|
99
100
|
puts "Failed local bundle, trying again with full bundle..."
|
100
|
-
|
101
|
+
command = "cd #{dir} && bundle install --retry 3"
|
102
|
+
result = Multiverse::ShellUtils.try_command_n_times(command, 3)
|
101
103
|
end
|
102
104
|
|
103
|
-
|
104
|
-
puts
|
105
|
+
result = red(result) unless $?.success?
|
106
|
+
puts result
|
105
107
|
$?
|
106
108
|
end
|
107
109
|
|
@@ -4,14 +4,20 @@ gem 'rake', '~>10.1.1'
|
|
4
4
|
|
5
5
|
gem 'minitest', '~>4.7.5'
|
6
6
|
gem 'mocha', :require => false
|
7
|
-
|
7
|
+
|
8
|
+
if RUBY_VERSION < '2.2.2'
|
9
|
+
gem 'rack', '< 2.0.0'
|
10
|
+
else
|
11
|
+
gem 'rack'
|
12
|
+
end
|
13
|
+
|
8
14
|
gem 'rack-test'
|
9
|
-
gem 'json' if RUBY_VERSION == "1.8.7"
|
15
|
+
gem 'json', '< 2.0.0' if RUBY_VERSION == "1.8.7"
|
10
16
|
|
11
17
|
platforms :rbx do
|
12
18
|
gem "rubysl"
|
13
19
|
gem "rubysl-test-unit"
|
14
|
-
gem "json"
|
20
|
+
gem "json", '< 2.0.0'
|
15
21
|
gem "psych"
|
16
22
|
gem "racc" # https://github.com/rubinius/rubinius/issues/2632
|
17
23
|
end
|
@@ -7,8 +7,7 @@ gem 'minitest', '~>4.7.5'
|
|
7
7
|
gem "mocha", :require => false
|
8
8
|
gem "jeweler", "1.4.0"
|
9
9
|
gem "rdoc"
|
10
|
-
|
11
|
-
gem 'rack'
|
10
|
+
gem 'rack', '< 2.0.0'
|
12
11
|
gem 'rack-test'
|
13
12
|
gem 'newrelic_rpm', :path => "../../.."
|
14
13
|
|
@@ -24,4 +23,8 @@ end
|
|
24
23
|
gem 'pry', '~> 0.9.12'
|
25
24
|
gem 'hometown', '~> 0.2.5'
|
26
25
|
|
27
|
-
|
26
|
+
if RUBY_VERSION < '1.9'
|
27
|
+
gem 'git', '< 1.3' # git 1.3.0 requires Ruby version >= 1.9
|
28
|
+
gem 'json_pure', '< 2.0'
|
29
|
+
end
|
30
|
+
|
@@ -8,7 +8,7 @@ gem "mocha", :require => false
|
|
8
8
|
gem "jeweler", "1.4.0"
|
9
9
|
gem "rdoc"
|
10
10
|
|
11
|
-
gem 'rack'
|
11
|
+
gem 'rack', '< 2.0.0'
|
12
12
|
gem 'rack-test'
|
13
13
|
gem 'newrelic_rpm', :path => '../../..'
|
14
14
|
|
@@ -24,4 +24,7 @@ end
|
|
24
24
|
gem 'pry', '~> 0.9.12'
|
25
25
|
gem 'hometown', '~> 0.2.5'
|
26
26
|
|
27
|
-
|
27
|
+
if RUBY_VERSION < '1.9'
|
28
|
+
gem 'git', '< 1.3' # git 1.3.0 requires Ruby version >= 1.9
|
29
|
+
gem 'json_pure', '< 2.0'
|
30
|
+
end
|