newrelic_rpm 3.12.1.298 → 3.13.0.299

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG +37 -0
  3. data/GUIDELINES_FOR_CONTRIBUTING.md +1 -1
  4. data/LICENSE +4 -4
  5. data/README.md +3 -3
  6. data/lib/new_relic/agent/agent.rb +27 -0
  7. data/lib/new_relic/agent/commands/thread_profiler_session.rb +2 -0
  8. data/lib/new_relic/agent/configuration/default_source.rb +51 -1
  9. data/lib/new_relic/agent/configuration/high_security_source.rb +1 -0
  10. data/lib/new_relic/agent/database.rb +12 -2
  11. data/lib/new_relic/agent/database/obfuscator.rb +4 -3
  12. data/lib/new_relic/agent/datastores.rb +1 -1
  13. data/lib/new_relic/agent/datastores/redis.rb +131 -0
  14. data/lib/new_relic/agent/error_collector.rb +2 -2
  15. data/lib/new_relic/agent/instrumentation/action_controller_subscriber.rb +1 -0
  16. data/lib/new_relic/agent/instrumentation/controller_instrumentation.rb +1 -0
  17. data/lib/new_relic/agent/instrumentation/rails/action_controller.rb +2 -0
  18. data/lib/new_relic/agent/instrumentation/rails3/action_controller.rb +2 -0
  19. data/lib/new_relic/agent/instrumentation/rake.rb +170 -0
  20. data/lib/new_relic/agent/instrumentation/redis.rb +71 -0
  21. data/lib/new_relic/agent/instrumentation/sinatra.rb +1 -0
  22. data/lib/new_relic/agent/new_relic_service.rb +4 -0
  23. data/lib/new_relic/agent/sql_sampler.rb +14 -13
  24. data/lib/new_relic/agent/stats_engine/gc_profiler.rb +1 -0
  25. data/lib/new_relic/agent/transaction.rb +2 -0
  26. data/lib/new_relic/agent/transaction/attributes.rb +1 -1
  27. data/lib/new_relic/agent/transaction/trace.rb +2 -1
  28. data/lib/new_relic/agent/transaction/trace_node.rb +3 -2
  29. data/lib/new_relic/agent/transaction_sampler.rb +4 -15
  30. data/lib/new_relic/agent/transaction_state.rb +1 -0
  31. data/lib/new_relic/agent/vm/rubinius_vm.rb +27 -19
  32. data/lib/new_relic/language_support.rb +7 -0
  33. data/lib/new_relic/version.rb +2 -2
  34. data/lib/tasks/newrelic.rb +9 -0
  35. data/newrelic_rpm.gemspec +1 -1
  36. data/test/multiverse/README.md +1 -1
  37. data/test/multiverse/lib/multiverse/runner.rb +2 -2
  38. data/test/multiverse/suites/active_record/active_record_test.rb +6 -6
  39. data/test/multiverse/suites/agent_only/agent_attributes_test.rb +11 -0
  40. data/test/multiverse/suites/agent_only/script/warnings.rb +15 -0
  41. data/test/multiverse/suites/agent_only/start_up_test.rb +12 -4
  42. data/test/multiverse/suites/rake/Envfile +37 -0
  43. data/test/multiverse/suites/rake/Rakefile +54 -0
  44. data/test/multiverse/suites/rake/config/newrelic.yml +18 -0
  45. data/test/multiverse/suites/rake/multitask_test.rb +40 -0
  46. data/test/multiverse/suites/rake/rake_test.rb +209 -0
  47. data/test/multiverse/suites/rake/rake_test_helper.rb +66 -0
  48. data/test/multiverse/suites/rake/unsupported_rake_test.rb +19 -0
  49. data/test/multiverse/suites/redis/Envfile +14 -0
  50. data/test/multiverse/suites/redis/config/newrelic.yml +19 -0
  51. data/test/multiverse/suites/redis/redis_instrumentation_test.rb +212 -0
  52. data/test/multiverse/suites/redis/redis_unsupported_version_test.rb +20 -0
  53. data/test/multiverse/suites/resque/resque_marshalling_test.rb +9 -1
  54. data/test/new_relic/agent/agent_test.rb +78 -1
  55. data/test/new_relic/agent/configuration/high_security_source_test.rb +9 -0
  56. data/test/new_relic/agent/database/sql_obfuscation_test.rb +1 -3
  57. data/test/new_relic/agent/datastores/redis_test.rb +128 -0
  58. data/test/new_relic/agent/instrumentation/active_record_subscriber_test.rb +1 -1
  59. data/test/new_relic/agent/sql_sampler_test.rb +64 -52
  60. data/test/new_relic/agent/transaction/trace_node_test.rb +1 -1
  61. data/test/new_relic/agent/transaction/trace_test.rb +1 -1
  62. data/test/new_relic/agent/transaction_sampler_test.rb +9 -11
  63. data/test/new_relic/agent/vm/rubinius_vm_test.rb +1 -1
  64. data/test/new_relic/fake_collector.rb +18 -1
  65. data/test/new_relic/multiverse_helpers.rb +6 -0
  66. data/test/performance/suites/redis.rb +45 -0
  67. data/ui/views/newrelic/_sql_row.rhtml +1 -1
  68. data/ui/views/newrelic/explain_sql.rhtml +1 -1
  69. metadata +21 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0798cd154bf943c9a4fc467ef1c36e427b72fa69
4
- data.tar.gz: cd97b3eeb7c08207ef647fab453450d9c4e012b2
3
+ metadata.gz: 6a66f2339d582713549cd887c6c249a1e167060a
4
+ data.tar.gz: 340be0c604f5a041c013c02118bc1f83bfae2fd1
5
5
  SHA512:
6
- metadata.gz: 1a28882d587c9633022b7f0192d9a309a084abcf9610a3b3a86e506bcb313068db9583839290c4ca367942c2aba89e8aff42fa045b1dae8384e33195e8d8a1e6
7
- data.tar.gz: 5055fa5929114caa4fecc07e9e76268dfb7187de30df4551e808254326dfd7e16fbd9a259c03e6c494e30f711d2f63969efb4a895d89700b4021800aed046208
6
+ metadata.gz: f09c1d8499f23aa1659c2a7622f7655b94644493cca9401f9ba663c69c8ff6394c06ef9238b7bb0fc8a62f10be9dd099d27a45e80403810d801ab55ade84d5f0
7
+ data.tar.gz: 6c325a570205de1ce13fe012203255fbd413684f9f387149f3a967d959064965f1284e4c50820f5499d37f29ab8cae39018f3ff60aab0580256283569923f037
data/CHANGELOG CHANGED
@@ -1,5 +1,42 @@
1
1
  # New Relic Ruby Agent Release Notes #
2
2
 
3
+ ## v3.13.0 ##
4
+
5
+ * Bugfix for uninitialized constant NewRelic::Agent::ParameterFiltering
6
+
7
+ Users in some environments encountered a NameError: uninitialized constant NewRelic::Agent::ParameterFiltering from the Rails instrumentation while
8
+ running v3.12.x of the Ruby agent. This issue has been fixed.
9
+
10
+ * Rake task instrumentation
11
+
12
+ The Ruby agent now provides opt-in tracing for Rake tasks. If you run
13
+ long jobs via Rake, you can get all the visibility and goodness of New Relic
14
+ that your other background jobs have. To enable this, see
15
+ https://docs.newrelic.com/docs/agents/ruby-agent/frameworks/rake
16
+
17
+ * Redis instrumentation
18
+
19
+ Redis operations will now show up on the Databases tab and in transaction
20
+ traces. By default, only command names will be captured; to capture command
21
+ arguments, set `transaction_tracer.record_redis_arguments` to `true` in
22
+ your configuration.
23
+
24
+ * Fix for over-obfuscated SQL Traces and PostgreSQL
25
+
26
+ An issue with the agent obfuscating column and table names from Slow SQL
27
+ Traces when using PostgreSQL has been resolved.
28
+
29
+ * Rubinius 2.5.8 VM metric renaming support
30
+
31
+ Rubinius 2.5.8 changed some VM metric names and eliminated support for
32
+ total allocated object counters. The agent has been updated accordingly.
33
+
34
+ * Fix agent attributes with a value of false not being stored
35
+
36
+ An issue introduced in v3.12.1 prevented attributes (like those added with
37
+ `add_custom_attributes`) from being stored if their value was false. This has
38
+ been fixed.
39
+
3
40
  ## v3.12.1 ##
4
41
 
5
42
  * More granular Database metrics for ActiveRecord 3 and 4
@@ -73,7 +73,7 @@ More details are available in
73
73
  You are welcome to send pull requests to us - however, by doing so you agree
74
74
  that you are granting New Relic a non-exclusive, non-revokable, no-cost license
75
75
  to use the code, algorithms, patents, and ideas in that code in our products if
76
- we so choose. You also agree the code is provided as-is and you provide no
76
+ we so choose. Fortunately, you also agree the code is provided as-is and you provide no
77
77
  warranties as to its fitness or correctness for any purpose.
78
78
 
79
79
  If you have any feedback on how we can make contributing easier, please get in
data/LICENSE CHANGED
@@ -1,8 +1,8 @@
1
- This product includes jquery written by John Resig
1
+ This product includes jquery 1.4.2, written by John Resig
2
2
  and distributed under an MIT license.
3
- See https://github.com/jquery/jquery/blob/master/MIT-LICENSE.txt
3
+ See https://github.com/jquery/jquery/blob/1.4.2/MIT-LICENSE.txt
4
4
 
5
- Copyright (c) 2011 John Resig, http://jquery.com/
5
+ Copyright (c) 2010 John Resig, http://jquery.com/
6
6
 
7
7
  Permission is hereby granted, free of charge, to any person obtaining
8
8
  a copy of this software and associated documentation files (the
@@ -112,7 +112,7 @@ the software.
112
112
 
113
113
 
114
114
  All other components of this product are
115
- Copyright (c) 2008-2014 New Relic, Inc. All rights reserved.
115
+ Copyright (c) 2008-2015 New Relic, Inc. All rights reserved.
116
116
 
117
117
  Certain inventions disclosed in this file may be claimed within
118
118
  patents owned or patent applications filed by New Relic, Inc. or third
data/README.md CHANGED
@@ -59,8 +59,8 @@ To monitor your applications in production, create an account at
59
59
  http://newrelic.com/ . There you can
60
60
  sign up for a free Lite account or one of our paid subscriptions.
61
61
 
62
- Once you receive the welcome e-mail with a license key and
63
- `newrelic.yml` file. You can copy the `newrelic.yml` file into your app config
62
+ Once you receive the welcome email with a license key and
63
+ `newrelic.yml` file, you can copy the `newrelic.yml` file into your app config
64
64
  directory OR can generate the file manually with command:
65
65
 
66
66
  newrelic install --license_key="YOUR_KEY" "My application"
@@ -193,7 +193,7 @@ Also available is community support on IRC: we generally use #newrelic
193
193
  on irc.freenode.net
194
194
 
195
195
  Find a bug? Contact us via [support.newrelic.com](http://support.newrelic.com/),
196
- or e-mail support @ newrelic.com.
196
+ or email support@newrelic.com.
197
197
 
198
198
  Thank you, and may your application scale to infinity plus one.
199
199
 
@@ -71,6 +71,8 @@ module NewRelic
71
71
  @connect_attempts = 0
72
72
  @environment_report = nil
73
73
 
74
+ @wait_on_connect_reader, @wait_on_connect_writer = IO.pipe
75
+
74
76
  @obfuscator = lambda {|sql| NewRelic::Agent::Database.default_sql_obfuscator(sql) }
75
77
 
76
78
  setup_attribute_filter
@@ -867,6 +869,30 @@ module NewRelic
867
869
  # use Agent.instance.events.subscribe(:finished_configuring) callback instead!
868
870
  end
869
871
 
872
+ class WaitOnConnectTimeout < StandardError
873
+ end
874
+
875
+ # Used for testing to let us know we've actually started to wait
876
+ def waited_on_connect?
877
+ @waited_on_connect
878
+ end
879
+
880
+ def signal_connected
881
+ @wait_on_connect_writer << "."
882
+ end
883
+
884
+ def wait_on_connect(timeout)
885
+ return if connected?
886
+
887
+ @waited_on_connect = true
888
+ NewRelic::Agent.logger.debug("Waiting on connect to complete.")
889
+ IO.select([@wait_on_connect_reader], nil, nil, timeout)
890
+
891
+ unless connected?
892
+ raise WaitOnConnectTimeout, "Agent was unable to connect in #{timeout} seconds."
893
+ end
894
+ end
895
+
870
896
  # Logs when we connect to the server, for debugging purposes
871
897
  # - makes sure we know if an agent has not connected
872
898
  def log_connection!(config_data)
@@ -936,6 +962,7 @@ module NewRelic
936
962
  query_server_for_configuration
937
963
  @connected_pid = $$
938
964
  @connect_state = :connected
965
+ signal_connected
939
966
  rescue NewRelic::Agent::ForceDisconnectException => e
940
967
  handle_force_disconnect(e)
941
968
  rescue NewRelic::Agent::LicenseException => e
@@ -14,6 +14,8 @@ module NewRelic
14
14
 
15
15
  def initialize(backtrace_service)
16
16
  @backtrace_service = backtrace_service
17
+ @started_at = nil
18
+ @finished_profile = nil
17
19
  end
18
20
 
19
21
  def handle_start_command(agent_command)
@@ -409,6 +409,35 @@ module NewRelic
409
409
  :allowed_from_server => false,
410
410
  :description => 'Defines a comma-delimited list of rake tasks that should not be instrumented by the agent (e.g. \'assets:precompile,db:migrate\').'
411
411
  },
412
+ :disable_rake => {
413
+ :default => false,
414
+ :public => true,
415
+ :type => Boolean,
416
+ :allowed_from_server => false,
417
+ :description => 'Enable or disable rake instrumentation.'
418
+ },
419
+ :disable_rake_instrumentation => {
420
+ :default => false,
421
+ :public => false,
422
+ :type => Boolean,
423
+ :allowed_from_server => false,
424
+ :description => 'Enable or disable rake instrumentation. Preferred key is `disable_rake`'
425
+ },
426
+ :'rake.tasks' => {
427
+ :default => [],
428
+ :public => true,
429
+ :type => Array,
430
+ :allowed_from_server => false,
431
+ :transform => DefaultSource.method(:convert_to_regexp_list),
432
+ :description => 'List of Rake tasks to automatically instrument'
433
+ },
434
+ :'rake.connect_timeout' => {
435
+ :default => 10,
436
+ :public => true,
437
+ :type => Fixnum,
438
+ :allowed_from_server => false,
439
+ :description => 'Timeout for waiting on connect to complete before a rake task'
440
+ },
412
441
  :'profiling.available' => {
413
442
  :default => DefaultSource.profiling_available,
414
443
  :public => false,
@@ -762,6 +791,13 @@ module NewRelic
762
791
  :allowed_from_server => true,
763
792
  :description => 'Obfuscation level for SQL queries reported in transaction trace nodes. Valid options are <code>obfuscated</code>, <code>raw</code>, <code>none</code>.'
764
793
  },
794
+ :'transaction_tracer.record_redis_arguments' => {
795
+ :default => false,
796
+ :public => true,
797
+ :type => Boolean,
798
+ :allowed_from_server => false,
799
+ :description => 'Determines whether Redis command arguments should be recorded within Transaction Traces'
800
+ },
765
801
  :'transaction_tracer.capture_attributes' => {
766
802
  :default => true,
767
803
  :public => true,
@@ -821,6 +857,20 @@ module NewRelic
821
857
  :dynamic_name => true,
822
858
  :description => 'Defines whether the agent will install <a href="/docs/agents/ruby-agent/frameworks/mongo-instrumentation">instrumentation for the Mongo gem</a>.'
823
859
  },
860
+ :disable_redis => {
861
+ :default => false,
862
+ :public => true,
863
+ :type => Boolean,
864
+ :allowed_from_server => false,
865
+ :description => 'Defines whether the agent will install <a href="/docs/agents/ruby-agent/frameworks/redis-instrumentation">instrumentation for Redis</a>.'
866
+ },
867
+ :disable_redis_instrumentation => {
868
+ :default => false,
869
+ :public => false,
870
+ :type => Boolean,
871
+ :allowed_from_server => false,
872
+ :description => 'Disables installation of Redis instrumentation. Standard key to use is disable_redis.'
873
+ },
824
874
  :'slow_sql.enabled' => {
825
875
  :default => value_of(:'transaction_tracer.enabled'),
826
876
  :public => true,
@@ -1309,7 +1359,7 @@ module NewRelic
1309
1359
  },
1310
1360
  :disable_grape_instrumentation => {
1311
1361
  :default => false,
1312
- :public => true,
1362
+ :public => false,
1313
1363
  :type => Boolean,
1314
1364
  :allowed_from_server => false,
1315
1365
  :description => 'Disables installation of Grape instrumentation.'
@@ -19,6 +19,7 @@ module NewRelic
19
19
  :'transaction_tracer.record_sql' => record_sql_setting(local_settings, :'transaction_tracer.record_sql'),
20
20
  :'slow_sql.record_sql' => record_sql_setting(local_settings, :'slow_sql.record_sql'),
21
21
  :'mongo.obfuscate_queries' => true,
22
+ :'transaction_tracer.record_redis_arguments' => false,
22
23
 
23
24
  :'custom_insights_events.enabled' => false,
24
25
  :'strip_exception_messages.enabled' => true
@@ -317,8 +317,18 @@ module NewRelic
317
317
  end
318
318
  end
319
319
 
320
- class Statement < String
321
- attr_accessor :adapter, :config, :explainer
320
+ class Statement
321
+ attr_accessor :sql, :config, :explainer
322
+
323
+ def initialize(sql, config={}, explainer=nil)
324
+ @sql = Database.capture_query(sql)
325
+ @config = config
326
+ @explainer = explainer
327
+ end
328
+
329
+ def adapter
330
+ config && config[:adapter]
331
+ end
322
332
  end
323
333
  end
324
334
  end
@@ -48,14 +48,15 @@ module NewRelic
48
48
  end
49
49
 
50
50
  def default_sql_obfuscator(sql)
51
- if sql[-3,3] == '...'
51
+ stmt = sql.kind_of?(Statement) ? sql : Statement.new(sql)
52
+
53
+ if stmt.sql[-3,3] == '...'
52
54
  return QUERY_TOO_LARGE_MESSAGE
53
55
  end
54
56
 
55
- stmt = sql.kind_of?(Statement) ? sql : Statement.new(sql)
56
57
  obfuscate_double_quotes = stmt.adapter.to_s !~ /postgres|sqlite/
57
58
 
58
- obfuscated = obfuscate_numeric_literals(stmt)
59
+ obfuscated = obfuscate_numeric_literals(stmt.sql)
59
60
 
60
61
  if obfuscate_double_quotes
61
62
  obfuscated = obfuscate_quoted_literals(obfuscated)
@@ -106,7 +106,7 @@ module NewRelic
106
106
  metrics = MetricHelper.metrics_for(product, operation, collection)
107
107
  scoped_metric = metrics.first
108
108
  NewRelic::Agent::MethodTracer.trace_execution_scoped(metrics) do
109
- t0 = Time.now
109
+ t0 = Time.now if callback
110
110
  begin
111
111
  result = yield
112
112
  ensure
@@ -0,0 +1,131 @@
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
+ module Datastores
8
+ module Redis
9
+ MULTI_OPERATION = 'multi'
10
+ PIPELINE_OPERATION = 'pipeline'
11
+ BINARY_DATA_PLACEHOLDER = "<binary data>"
12
+ PRODUCT_NAME = 'Redis'
13
+ CONNECT = 'connect'
14
+
15
+ MAXIMUM_COMMAND_LENGTH = 1000
16
+ MAXIMUM_ARGUMENT_LENGTH = 64
17
+ CHUNK_SIZE = (MAXIMUM_ARGUMENT_LENGTH - 5) / 2
18
+ PREFIX_RANGE = (0...CHUNK_SIZE)
19
+ SUFFIX_RANGE = (-CHUNK_SIZE..-1)
20
+
21
+ OBFUSCATE_ARGS = ' ?'
22
+ ELLIPSES = '...'
23
+ NEWLINE = "\n"
24
+ SPACE = ' '
25
+ QUOTE = '"'
26
+ ALL_BUT_FIRST = (1..-1)
27
+
28
+ STRINGS_SUPPORT_ENCODING = SPACE.respond_to?(:encoding)
29
+
30
+ def self.format_command(command_with_args)
31
+ if Agent.config[:'transaction_tracer.record_redis_arguments']
32
+ result = ""
33
+
34
+ append_command_with_args(result, command_with_args)
35
+
36
+ trim_result(result) if result.length >= MAXIMUM_COMMAND_LENGTH
37
+ result.strip!
38
+ result
39
+ else
40
+ nil
41
+ end
42
+ end
43
+
44
+ def self.format_pipeline_commands(commands_with_args)
45
+ result = ""
46
+
47
+ commands_with_args.each do |command|
48
+ if result.length >= MAXIMUM_COMMAND_LENGTH
49
+ trim_result(result)
50
+ break
51
+ end
52
+
53
+ append_pipeline_command(result, command)
54
+ result << NEWLINE
55
+ end
56
+
57
+ result.strip!
58
+ result
59
+ end
60
+
61
+ def self.append_pipeline_command(result, command_with_args)
62
+ if Agent.config[:'transaction_tracer.record_redis_arguments']
63
+ append_command_with_args(result, command_with_args)
64
+ else
65
+ append_command_with_no_args(result, command_with_args)
66
+ end
67
+
68
+ result
69
+ end
70
+
71
+ def self.append_command_with_args(result, command_with_args)
72
+ result << command_with_args.first.to_s
73
+
74
+ if command_with_args.size > 1
75
+ command_with_args[ALL_BUT_FIRST].each do |arg|
76
+ ellipsize(result, arg)
77
+
78
+ break if result.length >= MAXIMUM_COMMAND_LENGTH
79
+ end
80
+ end
81
+
82
+ result
83
+ end
84
+
85
+ def self.append_command_with_no_args(result, command_with_args)
86
+ result << command_with_args.first.to_s
87
+ result << OBFUSCATE_ARGS if command_with_args.size > 1
88
+ result
89
+ end
90
+
91
+ def self.is_supported_version?
92
+ ::NewRelic::VersionNumber.new(::Redis::VERSION) >= ::NewRelic::VersionNumber.new("3.0.0")
93
+ end
94
+
95
+ def self.ellipsize(result, string)
96
+ result << SPACE
97
+ if !string.is_a?(String)
98
+ result << string.to_s
99
+ elsif STRINGS_SUPPORT_ENCODING && string.encoding == Encoding::ASCII_8BIT
100
+ result << BINARY_DATA_PLACEHOLDER
101
+ elsif string.length > MAXIMUM_ARGUMENT_LENGTH
102
+ result << QUOTE
103
+ result << string[PREFIX_RANGE]
104
+ result << ELLIPSES
105
+ result << string[SUFFIX_RANGE]
106
+ result << QUOTE
107
+ else
108
+ result << QUOTE
109
+ result << string
110
+ result << QUOTE
111
+ end
112
+ end
113
+
114
+ def self.safe_from_third_party_gem?
115
+ if NewRelic::LanguageSupport.bundled_gem?("newrelic-redis")
116
+ ::NewRelic::Agent.logger.info("Not installing New Relic supported Redis instrumentation because the third party newrelic-redis gem is present")
117
+ false
118
+ else
119
+ true
120
+ end
121
+ end
122
+
123
+ def self.trim_result(result)
124
+ result.slice!((MAXIMUM_COMMAND_LENGTH-ELLIPSES.length)..-1)
125
+ result.strip!
126
+ result << ELLIPSES
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -70,7 +70,7 @@ module NewRelic
70
70
  if block
71
71
  define_method(:ignore_filter_proc, &block)
72
72
  elsif method_defined?(:ignore_filter_proc)
73
- undef :ignore_filter_proc
73
+ remove_method :ignore_filter_proc
74
74
  end
75
75
  @ignore_filter
76
76
  end
@@ -121,7 +121,7 @@ module NewRelic
121
121
 
122
122
  def exception_tagged?(exception)
123
123
  return false if exception_is_java_object?(exception)
124
- exception.instance_variable_get(EXCEPTION_TAG_IVAR)
124
+ exception.instance_variable_defined?(EXCEPTION_TAG_IVAR)
125
125
  end
126
126
 
127
127
  def tag_exception(exception)