Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Up limits on payload lengths, more focussed trimming #431

Merged
merged 23 commits into from
Jun 2, 2018

Conversation

Cawllec
Copy link
Contributor

@Cawllec Cawllec commented Feb 21, 2018

Changes how payload trimming is implemented to favour keeping longer stacktraces in place rather than limiting them to 40 items.

Namely:

  • Ups max payload length to 512000 bytes (~0.5 Mb)
  • Ups max metadata array length to 80
  • Ups max other array length (namely stacktraces) to 160
  • Changes order of payload trimming to:
    1. Trimming strings to max length (3072)
    2. Trimming metadata arrays to max length (80)
    3. Trimming all other arrays (including stacktraces) to max length (160)
    4. Removing metadata from the payload
    5. Remove :code from stacktrace items, oldest first, until within limits
    6. Remove stacktrace items, oldest first, until within limits

WIP:

  1. I need to write performance tests to compare with the older version to see if extra performance time is within acceptable limits
  2. Review of how iteration is performed over payload to ensure performing optimally
  3. Review of tests to ensure all cases are covered
  4. Refactoring of more complex functions to be more readable will probably be required

Copy link
Contributor

@kattrali kattrali left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fairly complex solution to the problem and expensive for what it does. Serializing the payload is relatively costly and shouldn't be done for every stacktrace line, for example. Added more inline.

@@ -1,3 +1,5 @@
require 'pp'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this from debugging?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I'll remove that.

@@ -171,6 +172,111 @@ def to_s
expect(trimmed_value[:events].first[:metaData]).to be_nil
end
end

context "and new trimming priorities are in place" do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be a new context because no conditions are being changed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's mostly a readability context for me at the moment before the tests are concreted.

return payload unless payload.is_a?(Hash) and payload[:events].respond_to?(:map)
payload[:events].map do |event|
event[:exceptions].map do |exception|
initial_size = get_payload_length(exception[:stacktrace])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just do exception[:stacktrace].each and pop the code from each entry. No need for all of these checks and breaks or using downto.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

initial_size = get_payload_length(exception[:stacktrace])
(exception[:stacktrace].length - 1).downto(0).each do |i|
break unless (initial_size - get_payload_length(exception[:stacktrace])) < threshold
exception[:stacktrace][i].delete(:code) if exception[:stacktrace][i].include?(:code)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to check for inclusion before deletion.

def self.trim_stacktrace_functions(payload, threshold)
return payload unless payload.is_a?(Hash) and payload[:events].respond_to?(:map)
payload[:events].map do |event|
event[:exceptions].map do |exception|
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same changes as above ☝️

@snmaynard
Copy link
Contributor

Can you ping me on this when it's ready for a second review.

@Cawllec
Copy link
Contributor Author

Cawllec commented May 2, 2018

I've updated this to more closely match the original spec for trimming payloads.
Logic is as stated in the ticket:

  1. Bump the payload limit to 512kb
  2. in the case where the payload is too large try to shorten metadata
  3. if that doesnt work enough strip the code out from the oldest called functions.
  4. If that doesnt work strip out all the code
  5. then shorten the stacktrace.
    There are a number of places where efficiencies could be made, such as block deletion of older stacktrace entries if it's too long, but I think it's worth another review.
    Would you mind taking another look @snmaynard @kattrali ?

@Cawllec Cawllec changed the base branch from master to next May 11, 2018 14:23
@@ -60,21 +70,74 @@ def self.deep_merge!(l_hash, r_hash)

TRUNCATION_INFO = '[TRUNCATED]'

##
# Trim stacktrace code out if they're too large, oldest functions first
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than checking the length for every line, just delete the code from every frame.

- # Trim stacktrace code out if they're too large, oldest functions first
+ # Remove all code from stacktraces

# Shorten array until it fits within the payload size limit when serialized
def self.truncate_array(array)
def self.truncate_array(array, limit = MAX_ARRAY_LENGTH)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If limit is just a constant value everywhere and never modified, just use it directly instead of passing it from one method to the next.

@kattrali kattrali force-pushed the cawllec/payload-trimmer-redux branch from 34e9c35 to 8662014 Compare June 2, 2018 00:20
@kattrali kattrali merged commit ae02477 into next Jun 2, 2018
@kattrali kattrali deleted the cawllec/payload-trimmer-redux branch June 2, 2018 01:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants