-
-
Notifications
You must be signed in to change notification settings - Fork 494
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Generalize size limits based on envelope item type (#2421)
* Fix spec file location * Extract Envelope::Item to its own file * Add Envelope::Item#size_limit * Make Envelope::Item#{headers,payload} just readers We don't set headers and payloads after initializing an item, so these accessors were not needed. * Memoize Envelope::Item#type in the constructor It's faster like that given that we rely on type value in multiple places * Memoize Envelope::Item#data_category Same as with type, we rely on this value in multiple places so it makes no sense to keep calculating it multiple times * Add custom size limit for profile items * Update CHANGELOG
- Loading branch information
Showing
5 changed files
with
127 additions
and
85 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
# frozen_string_literal: true | ||
|
||
module Sentry | ||
# @api private | ||
class Envelope::Item | ||
STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD = 500 | ||
MAX_SERIALIZED_PAYLOAD_SIZE = 1024 * 1000 | ||
|
||
SIZE_LIMITS = Hash.new(MAX_SERIALIZED_PAYLOAD_SIZE).update( | ||
"profile" => 1024 * 1000 * 50 | ||
) | ||
|
||
attr_reader :size_limit, :headers, :payload, :type, :data_category | ||
|
||
# rate limits and client reports use the data_category rather than envelope item type | ||
def self.data_category(type) | ||
case type | ||
when "session", "attachment", "transaction", "profile", "span" then type | ||
when "sessions" then "session" | ||
when "check_in" then "monitor" | ||
when "statsd", "metric_meta" then "metric_bucket" | ||
when "event" then "error" | ||
when "client_report" then "internal" | ||
else "default" | ||
end | ||
end | ||
|
||
def initialize(headers, payload) | ||
@headers = headers | ||
@payload = payload | ||
@type = headers[:type] || "event" | ||
@data_category = self.class.data_category(type) | ||
@size_limit = SIZE_LIMITS[type] | ||
end | ||
|
||
def to_s | ||
[JSON.generate(@headers), @payload.is_a?(String) ? @payload : JSON.generate(@payload)].join("\n") | ||
end | ||
|
||
def serialize | ||
result = to_s | ||
|
||
if result.bytesize > size_limit | ||
remove_breadcrumbs! | ||
result = to_s | ||
end | ||
|
||
if result.bytesize > size_limit | ||
reduce_stacktrace! | ||
result = to_s | ||
end | ||
|
||
[result, result.bytesize > size_limit] | ||
end | ||
|
||
def size_breakdown | ||
payload.map do |key, value| | ||
"#{key}: #{JSON.generate(value).bytesize}" | ||
end.join(", ") | ||
end | ||
|
||
private | ||
|
||
def remove_breadcrumbs! | ||
if payload.key?(:breadcrumbs) | ||
payload.delete(:breadcrumbs) | ||
elsif payload.key?("breadcrumbs") | ||
payload.delete("breadcrumbs") | ||
end | ||
end | ||
|
||
def reduce_stacktrace! | ||
if exceptions = payload.dig(:exception, :values) || payload.dig("exception", "values") | ||
exceptions.each do |exception| | ||
# in most cases there is only one exception (2 or 3 when have multiple causes), so we won't loop through this double condition much | ||
traces = exception.dig(:stacktrace, :frames) || exception.dig("stacktrace", "frames") | ||
|
||
if traces && traces.size > STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD | ||
size_on_both_ends = STACKTRACE_FRAME_LIMIT_ON_OVERSIZED_PAYLOAD / 2 | ||
traces.replace( | ||
traces[0..(size_on_both_ends - 1)] + traces[-size_on_both_ends..-1], | ||
) | ||
end | ||
end | ||
end | ||
end | ||
end | ||
end |
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters