Skip to content

Commit

Permalink
Merge pull request #1694 from ruby-agent/RUBY-1530_truncate_stack_traces
Browse files Browse the repository at this point in the history
Add truncate_trace method and tests
  • Loading branch information
Erin Dees authored and GitHub Enterprise committed Apr 12, 2018
2 parents ecb7497 + b049ce8 commit 89a6423
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
18 changes: 17 additions & 1 deletion lib/new_relic/agent/error_collector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class ErrorCollector
# made configurable in the future. This is a tradeoff between
# memory and data retention
MAX_ERROR_QUEUE_LENGTH = 20
# Maximum number of frames in backtraces. May be made configurable
# in the future.
MAX_BACKTRACE_FRAMES = 50
EXCEPTION_TAG_IVAR = :'@__nr_seen_exception'

attr_reader :error_trace_aggregator, :error_event_aggregator
Expand Down Expand Up @@ -213,6 +216,19 @@ def notice_error(exception, options={}) #THREAD_LOCAL_ACCESS
nil
end

def truncate_trace(trace, keep_frames=MAX_BACKTRACE_FRAMES)
return trace if trace.length < keep_frames || trace.length == 0

# If keep_frames is odd, we will split things up favoring the top of the trace
keep_top = (keep_frames / 2.0).ceil
keep_bottom = (keep_frames / 2.0).floor

truncate_frames = trace.length - keep_frames

truncated_trace = trace[0...keep_top].concat(["<truncated #{truncate_frames.to_s} additional frames>"]).concat(trace[-keep_bottom..-1])
truncated_trace
end

EMPTY_STRING = ''.freeze

def create_noticed_error(exception, options)
Expand All @@ -225,7 +241,7 @@ def create_noticed_error(exception, options)

noticed_error.file_name = sense_method(exception, :file_name)
noticed_error.line_number = sense_method(exception, :line_number)
noticed_error.stack_trace = extract_stack_trace(exception)
noticed_error.stack_trace = truncate_trace(extract_stack_trace(exception))

noticed_error.expected = !! options.delete(:expected)

Expand Down
20 changes: 20 additions & 0 deletions test/new_relic/agent/error_collector_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,26 @@ def test_extract_stack_trace
assert_equal('<no stack trace>', @error_collector.extract_stack_trace(Exception.new))
end

def test_short_trace_not_truncated
trace = @error_collector.truncate_trace(['error', 'error', 'error'], 6)
assert_equal trace.length, 3
end

def test_empty_trace_not_truncated
trace = @error_collector.truncate_trace([], 7)
assert_equal trace.length, 0
end

def test_keeps_correct_frames_if_keep_frames_is_even
trace = @error_collector.truncate_trace(['error1', 'error2', 'error3', 'error4'], 2)
assert_equal ['error1', '<truncated 2 additional frames>', 'error4'], trace
end

def test_keeps_correct_frames_if_keep_frames_is_odd
trace = @error_collector.truncate_trace(['error1', 'error2', 'error3', 'error4'], 3)
assert_equal ['error1', 'error2', '<truncated 1 additional frames>', 'error4'], trace
end

if defined?(Rails::VERSION::MAJOR) && Rails::VERSION::MAJOR < 5
def test_extract_stack_trace_from_original_exception
orig = mock('original', :backtrace => "STACK STACK STACK")
Expand Down

0 comments on commit 89a6423

Please sign in to comment.