Class: RoundhouseUi::ErrorsController

Inherits:
ApplicationController show all
Defined in:
app/controllers/roundhouse_ui/errors_controller.rb

Overview

Groups failing jobs across the retry + dead sets by a fingerprint of (job class + error class) — so one bad deploy reads as a single issue with a count, not five thousand identical rows. The aggregation Sidekiq Web lacks.

Constant Summary collapse

FILTER_KEYS =

The facets a GROUP can be narrowed by. No queue=: a klass|error group spans every queue its jobs were enqueued on, so there is nothing here for it to apply to — and a pill that filters nothing is the phantom filter the bar exists to prevent. The parser refuses it and says which page it works on.

%w[class error tag text].freeze

Constants inherited from ApplicationController

ApplicationController::AUDIT_VERBS

Instance Method Summary collapse

Methods inherited from ApplicationController

allow_in_read_only, guard_in_read_only, #redirect_to, requires_capability

Instance Method Details

#indexObject



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
# File 'app/controllers/roundhouse_ui/errors_controller.rb', line 12

def index
  @filter = FilterQuery.from_params(params, keys: FILTER_KEYS)
  @query = @filter.text
  @scan_limit = ErrorGroups::DEFAULT_SCAN_LIMIT
  result = ErrorGroups.new(query: @query).call
  @groups, @scanned, @truncated = result.groups, result.scanned, result.truncated

  # Tags resolve per group rather than per entry: every row in a
  # klass|error group shares a class, so a class-derived tag is constant
  # for the group. Counted before filtering, so the quick-filter strip
  # keeps showing every squad's total while one of them is selected.
  @group_tags = @groups.to_h { |g| [ g[:klass], Tags.for(klass: g[:klass], item: {}, cache: tag_cache) ] }
  @tag_counts = tag_counts(@groups)
  @tag = tag_filter
  @groups = @groups.select { |g| group_tagged?(g, *@tag) } if @tag

  # class= and error= match EXACTLY, the same as on the job sets, so a funnel
  # clicked there and a facet typed here mean one thing. Filtered in memory:
  # grouping has already read the entries, so this costs no extra Redis work.
  #
  # A refused query selects nothing rather than everything — the same direction
  # the job sets fail in. Errors has no destructive action, but "nothing matched"
  # must not read as "no such failures exist", which is why the banner renders.
  @groups = [] if @filter.invalid?
  @groups = @groups.select { |g| @filter.matches_facet?(:klass, g[:klass]) }
  @groups = @groups.select { |g| @filter.matches_facet?(:error, g[:error]) }
end