Skip to content

Commit

Permalink
encode statsd format and sanitization
Browse files Browse the repository at this point in the history
  • Loading branch information
sl0thentr0py committed Feb 22, 2024
1 parent 675292b commit 73e5e04
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
1 change: 0 additions & 1 deletion sentry-ruby/lib/sentry-ruby.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,6 @@ def close
end

if @metrics_aggregator
# TODO-neel-metrics force flush?
@metrics_aggregator.flush(force: true)
@metrics_aggregator.kill
@metrics_aggregator = nil

Check warning on line 256 in sentry-ruby/lib/sentry-ruby.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry-ruby.rb#L254-L256

Added lines #L254 - L256 were not covered by tests
Expand Down
53 changes: 49 additions & 4 deletions sentry-ruby/lib/sentry/metrics/aggregator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ class Aggregator
FLUSH_INTERVAL = 5
ROLLUP_IN_SECONDS = 10

KEY_SANITIZATION_REGEX = /[^a-zA-Z0-9_\/.-]+/
VALUE_SANITIZATION_REGEX = /[^[[:word:]][[:digit:]][[:space:]]_:\/@\.{}\[\]$-]+/

METRIC_TYPES = {
c: CounterMetric,
d: DistributionMetric,
Expand Down Expand Up @@ -61,10 +64,14 @@ def add(type,
end

def flush(force: false)
@mutex.synchronize do
log_debug("[Metrics::Aggregator] current bucket state: #{@buckets}")
# TODO
end
log_debug("[Metrics::Aggregator] current bucket state: #{@buckets}")

Check warning on line 67 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L67

Added line #L67 was not covered by tests

flushable_buckets = get_flushable_buckets!(force)
return if flushable_buckets.empty?

Check warning on line 70 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L69-L70

Added lines #L69 - L70 were not covered by tests

payload = serialize_buckets(flushable_buckets)
log_debug("[Metrics::Aggregator] flushing buckets: #{flushable_buckets}")
log_debug("[Metrics::Aggregator] payload: #{payload}")

Check warning on line 74 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L72-L74

Added lines #L72 - L74 were not covered by tests
end

def kill
Expand Down Expand Up @@ -105,6 +112,44 @@ def serialize_tags(tags)
end
end.sort
end

def get_flushable_buckets!(force)
@mutex.synchronize do
flushable_buckets = {}

Check warning on line 118 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L117-L118

Added lines #L117 - L118 were not covered by tests

if force
flushable_buckets = @buckets
@buckets = {}

Check warning on line 122 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L120-L122

Added lines #L120 - L122 were not covered by tests
else
cutoff = Sentry.utc_now.to_i - ROLLUP_IN_SECONDS - @flush_shift
flushable_buckets = @buckets.select { |k, _| k <= cutoff }
@buckets.reject! { |k, _| k <= cutoff }

Check warning on line 126 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L124-L126

Added lines #L124 - L126 were not covered by tests
end

flushable_buckets

Check warning on line 129 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L129

Added line #L129 was not covered by tests
end
end

# serialize buckets to statsd format
def serialize_buckets(buckets)
buckets.map do |timestamp, timestamp_buckets|
timestamp_buckets.map do |metric_key, metric|
type, key, unit, tags = metric_key
values = metric.serialize.join(':')
sanitized_tags = tags.map { |k, v| "#{sanitize_key(k)}:#{sanitize_value(v)}"}.join(',')

Check warning on line 139 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L135-L139

Added lines #L135 - L139 were not covered by tests

"#{sanitize_key(key)}@#{unit}:#{values}|#{type}|\##{sanitized_tags}|T#{timestamp}"

Check warning on line 141 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L141

Added line #L141 was not covered by tests
end
end.flatten.join("\n")
end

def sanitize_key(key)
key.gsub(KEY_SANITIZATION_REGEX, '_')

Check warning on line 147 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L147

Added line #L147 was not covered by tests
end

def sanitize_value(value)
value.gsub(VALUE_SANITIZATION_REGEX, '')

Check warning on line 151 in sentry-ruby/lib/sentry/metrics/aggregator.rb

View check run for this annotation

Codecov / codecov/patch

sentry-ruby/lib/sentry/metrics/aggregator.rb#L151

Added line #L151 was not covered by tests
end
end
end
end

0 comments on commit 73e5e04

Please sign in to comment.