File: context_filter.rb

package info (click to toggle)
ruby-sentry-sidekiq 5.18.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 152 kB
  • sloc: ruby: 324; makefile: 10; sh: 4
file content (76 lines) | stat: -rw-r--r-- 2,244 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
module Sentry
  module Sidekiq
    class ContextFilter
      ACTIVEJOB_RESERVED_PREFIX_REGEX = /^_aj_/.freeze
      SIDEKIQ_NAME = "Sidekiq".freeze

      attr_reader :context

      def initialize(context)
        @context = context
        @has_global_id = defined?(GlobalID)
      end

      # Once an ActiveJob is queued, ActiveRecord references get serialized into
      # some internal reserved keys, such as _aj_globalid.
      #
      # The problem is, if this job in turn gets queued back into ActiveJob with
      # these magic reserved keys, ActiveJob will throw up and error. We want to
      # capture these and mutate the keys so we can sanely report it.
      def filtered
        filtered_context = filter_context(context)

        if job_entry = filtered_context.delete(:job)
          job_entry.each do |k, v|
            filtered_context[k] = v
          end
        end

        # Sidekiq 7.0 started adding `_config` to the context, which is not easily serialisable
        # And it's presence could be confusing so it's better to remove it until we decided to add it for a reason
        filtered_context.delete(:_config)
        filtered_context
      end

      def transaction_name
        class_name = (context["wrapped"] || context["class"] ||
                      (context[:job] && (context[:job]["wrapped"] || context[:job]["class"]))
                    )

        if class_name
          "#{SIDEKIQ_NAME}/#{class_name}"
        elsif context[:event]
          "#{SIDEKIQ_NAME}/#{context[:event]}"
        else
          SIDEKIQ_NAME
        end
      end

      private

      def filter_context(hash)
        case hash
        when Array
          hash.map { |arg| filter_context(arg) }
        when Hash
          Hash[hash.map { |key, value| filter_context_hash(key, value) }]
        else
          if has_global_id? && hash.is_a?(GlobalID)
            hash.to_s
          else
            hash
          end
        end
      end

      def filter_context_hash(key, value)
        key = key.to_s.sub(ACTIVEJOB_RESERVED_PREFIX_REGEX, "") if key.match(ACTIVEJOB_RESERVED_PREFIX_REGEX)
        [key, filter_context(value)]
      end

      def has_global_id?
        @has_global_id
      end
    end
  end
end