sidekiq 7.3.9 → 8.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (155) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +225 -0
  3. data/README.md +34 -14
  4. data/bin/kiq +17 -0
  5. data/bin/lint-herb +13 -0
  6. data/bin/sidekiqload +12 -10
  7. data/bin/webload +69 -0
  8. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +107 -58
  9. data/lib/generators/sidekiq/job_generator.rb +15 -3
  10. data/lib/generators/sidekiq/templates/job.rb.erb +1 -1
  11. data/lib/sidekiq/api.rb +310 -83
  12. data/lib/sidekiq/capsule.rb +10 -7
  13. data/lib/sidekiq/cli.rb +31 -24
  14. data/lib/sidekiq/client.rb +36 -18
  15. data/lib/sidekiq/component.rb +45 -3
  16. data/lib/sidekiq/config.rb +35 -30
  17. data/lib/sidekiq/embedded.rb +2 -1
  18. data/lib/sidekiq/fetch.rb +1 -0
  19. data/lib/sidekiq/iterable_job.rb +1 -0
  20. data/lib/sidekiq/job/iterable.rb +46 -18
  21. data/lib/sidekiq/job.rb +18 -3
  22. data/lib/sidekiq/job_logger.rb +8 -6
  23. data/lib/sidekiq/job_retry.rb +45 -18
  24. data/lib/sidekiq/job_util.rb +5 -1
  25. data/lib/sidekiq/launcher.rb +22 -12
  26. data/lib/sidekiq/loader.rb +57 -0
  27. data/lib/sidekiq/logger.rb +25 -69
  28. data/lib/sidekiq/manager.rb +2 -2
  29. data/lib/sidekiq/metrics/query.rb +77 -46
  30. data/lib/sidekiq/metrics/shared.rb +8 -5
  31. data/lib/sidekiq/metrics/tracking.rb +12 -7
  32. data/lib/sidekiq/middleware/current_attributes.rb +11 -19
  33. data/lib/sidekiq/middleware/i18n.rb +2 -0
  34. data/lib/sidekiq/monitor.rb +4 -8
  35. data/lib/sidekiq/paginator.rb +18 -2
  36. data/lib/sidekiq/processor.rb +26 -18
  37. data/lib/sidekiq/profiler.rb +73 -0
  38. data/lib/sidekiq/rails.rb +46 -67
  39. data/lib/sidekiq/redis_client_adapter.rb +6 -3
  40. data/lib/sidekiq/redis_connection.rb +16 -5
  41. data/lib/sidekiq/ring_buffer.rb +1 -0
  42. data/lib/sidekiq/scheduled.rb +6 -7
  43. data/lib/sidekiq/test_api.rb +331 -0
  44. data/lib/sidekiq/testing/inline.rb +2 -30
  45. data/lib/sidekiq/testing.rb +2 -333
  46. data/lib/sidekiq/transaction_aware_client.rb +13 -5
  47. data/lib/sidekiq/tui/controls.rb +53 -0
  48. data/lib/sidekiq/tui/filtering.rb +53 -0
  49. data/lib/sidekiq/tui/tabs/base_tab.rb +230 -0
  50. data/lib/sidekiq/tui/tabs/busy.rb +104 -0
  51. data/lib/sidekiq/tui/tabs/dead.rb +14 -0
  52. data/lib/sidekiq/tui/tabs/home.rb +115 -0
  53. data/lib/sidekiq/tui/tabs/metrics.rb +114 -0
  54. data/lib/sidekiq/tui/tabs/queues.rb +83 -0
  55. data/lib/sidekiq/tui/tabs/retries.rb +14 -0
  56. data/lib/sidekiq/tui/tabs/scheduled.rb +14 -0
  57. data/lib/sidekiq/tui/tabs/set_tab.rb +91 -0
  58. data/lib/sidekiq/tui/tabs.rb +15 -0
  59. data/lib/sidekiq/tui.rb +390 -0
  60. data/lib/sidekiq/version.rb +2 -2
  61. data/lib/sidekiq/web/action.rb +146 -83
  62. data/lib/sidekiq/web/application.rb +372 -328
  63. data/lib/sidekiq/web/config.rb +117 -0
  64. data/lib/sidekiq/web/helpers.rb +102 -44
  65. data/lib/sidekiq/web/router.rb +61 -77
  66. data/lib/sidekiq/web.rb +65 -151
  67. data/lib/sidekiq.rb +13 -1
  68. data/sidekiq.gemspec +9 -8
  69. data/web/assets/images/logo.png +0 -0
  70. data/web/assets/images/status.png +0 -0
  71. data/web/assets/javascripts/application.js +43 -27
  72. data/web/assets/javascripts/base-charts.js +30 -16
  73. data/web/assets/javascripts/chartjs-adapter-date-fns.min.js +7 -0
  74. data/web/assets/javascripts/dashboard.js +1 -1
  75. data/web/assets/javascripts/metrics.js +16 -34
  76. data/web/assets/stylesheets/style.css +776 -0
  77. data/web/locales/ar.yml +3 -1
  78. data/web/locales/cs.yml +2 -0
  79. data/web/locales/da.yml +2 -0
  80. data/web/locales/de.yml +2 -0
  81. data/web/locales/el.yml +2 -0
  82. data/web/locales/en.yml +8 -0
  83. data/web/locales/es.yml +25 -2
  84. data/web/locales/fa.yml +3 -1
  85. data/web/locales/fr.yml +3 -1
  86. data/web/locales/gd.yml +13 -1
  87. data/web/locales/he.yml +3 -1
  88. data/web/locales/hi.yml +36 -0
  89. data/web/locales/it.yml +9 -0
  90. data/web/locales/ja.yml +2 -0
  91. data/web/locales/ko.yml +2 -0
  92. data/web/locales/lt.yml +2 -0
  93. data/web/locales/nb.yml +2 -0
  94. data/web/locales/nl.yml +2 -0
  95. data/web/locales/pl.yml +2 -0
  96. data/web/locales/{pt-br.yml → pt-BR.yml} +3 -1
  97. data/web/locales/pt.yml +2 -0
  98. data/web/locales/ru.yml +2 -0
  99. data/web/locales/sv.yml +2 -0
  100. data/web/locales/ta.yml +83 -47
  101. data/web/locales/tr.yml +2 -0
  102. data/web/locales/uk.yml +7 -5
  103. data/web/locales/ur.yml +3 -1
  104. data/web/locales/vi.yml +2 -0
  105. data/web/locales/{zh-cn.yml → zh-CN.yml} +86 -73
  106. data/web/locales/{zh-tw.yml → zh-TW.yml} +3 -1
  107. data/web/views/_footer.html.erb +32 -0
  108. data/web/views/_job_info.html.erb +115 -0
  109. data/web/views/_metrics_period_select.html.erb +15 -0
  110. data/web/views/_nav.html.erb +45 -0
  111. data/web/views/_paging.html.erb +26 -0
  112. data/web/views/_poll_link.html.erb +4 -0
  113. data/web/views/{_summary.erb → _summary.html.erb} +16 -16
  114. data/web/views/busy.html.erb +155 -0
  115. data/web/views/dashboard.html.erb +104 -0
  116. data/web/views/dead.html.erb +38 -0
  117. data/web/views/filtering.html.erb +6 -0
  118. data/web/views/layout.html.erb +26 -0
  119. data/web/views/metrics.html.erb +85 -0
  120. data/web/views/metrics_for_job.html.erb +58 -0
  121. data/web/views/morgue.html.erb +69 -0
  122. data/web/views/profiles.html.erb +43 -0
  123. data/web/views/queue.html.erb +57 -0
  124. data/web/views/queues.html.erb +46 -0
  125. data/web/views/retries.html.erb +77 -0
  126. data/web/views/retry.html.erb +39 -0
  127. data/web/views/scheduled.html.erb +64 -0
  128. data/web/views/{scheduled_job_info.erb → scheduled_job_info.html.erb} +3 -3
  129. metadata +65 -47
  130. data/lib/sidekiq/web/csrf_protection.rb +0 -183
  131. data/web/assets/stylesheets/application-dark.css +0 -147
  132. data/web/assets/stylesheets/application-rtl.css +0 -163
  133. data/web/assets/stylesheets/application.css +0 -759
  134. data/web/assets/stylesheets/bootstrap-rtl.min.css +0 -9
  135. data/web/assets/stylesheets/bootstrap.css +0 -5
  136. data/web/views/_footer.erb +0 -34
  137. data/web/views/_job_info.erb +0 -105
  138. data/web/views/_metrics_period_select.erb +0 -12
  139. data/web/views/_nav.erb +0 -52
  140. data/web/views/_paging.erb +0 -25
  141. data/web/views/_poll_link.erb +0 -4
  142. data/web/views/_status.erb +0 -4
  143. data/web/views/busy.erb +0 -148
  144. data/web/views/dashboard.erb +0 -108
  145. data/web/views/dead.erb +0 -34
  146. data/web/views/filtering.erb +0 -6
  147. data/web/views/layout.erb +0 -42
  148. data/web/views/metrics.erb +0 -90
  149. data/web/views/metrics_for_job.erb +0 -59
  150. data/web/views/morgue.erb +0 -74
  151. data/web/views/queue.erb +0 -55
  152. data/web/views/queues.erb +0 -44
  153. data/web/views/retries.erb +0 -79
  154. data/web/views/retry.erb +0 -34
  155. data/web/views/scheduled.erb +0 -56
data/web/views/busy.erb DELETED
@@ -1,148 +0,0 @@
1
- <div class="header-container">
2
- <h1><%= t('Status') %></h1>
3
- </div>
4
-
5
- <div class="stats-wrapper">
6
- <div class="stats-container">
7
- <div class="stat">
8
- <h3><%= s = processes.size; number_with_delimiter(s) %></h3>
9
- <p><%= t('Processes') %></p>
10
- </div>
11
- <div class="stat">
12
- <h3><%= x = processes.total_concurrency; number_with_delimiter(x) %></h3>
13
- <p><%= t('Threads') %></p>
14
- </div>
15
- <div class="stat">
16
- <h3><%= ws = workset.size; number_with_delimiter(ws) %></h3>
17
- <p><%= t('Busy') %></p>
18
- </div>
19
- <div class="stat">
20
- <h3><%= x == 0 ? 0 : ((ws / x.to_f) * 100).round(0) %>%</h3>
21
- <p><%= t('Utilization') %></p>
22
- </div>
23
- <div class="stat">
24
- <h3><%= format_memory(processes.total_rss) %></h3>
25
- <p><%= t('RSS') %></p>
26
- </div>
27
- </div>
28
- </div>
29
-
30
- <div class="header-container">
31
- <h1><%= t('Processes') %></h1>
32
- <div>
33
- <form method="POST" class="warning-messages">
34
- <%= csrf_tag %>
35
- <div class="btn-group pull-right flip">
36
- <input class="btn btn-warn" type="submit" name="quiet" value="<%= t('QuietAll') %>" data-confirm="<%= t('AreYouSure') %>"/>
37
- <input class="btn btn-danger" type="submit" name="stop" value="<%= t('StopAll') %>" data-confirm="<%= t('AreYouSure') %>"/>
38
- </div>
39
- </form>
40
- </div>
41
- </div>
42
-
43
- <div class="table_container">
44
- <table class="processes table table-hover table-bordered table-striped">
45
- <thead>
46
- <th><%= t('Name') %></th>
47
- <th><%= t('Started') %></th>
48
- <th class="col-sm-1"><%= t('RSS') %><a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
49
- <th class="col-sm-1"><%= t('Threads') %></th>
50
- <th class="col-sm-1"><%= t('Busy') %></th>
51
- <th>&nbsp;</th>
52
- </thead>
53
- <% lead = processes.leader %>
54
- <% sorted_processes.each do |process| %>
55
- <tr>
56
- <td class="box">
57
- <%= "#{process['hostname']}:#{process['pid']}" %>
58
- <span class="label label-success"><%= process.tag %></span>
59
- <% process.labels.each do |label| %>
60
- <span class="label label-info"><%= label %></span>
61
- <% end %>
62
- <% if process.embedded? %>
63
- <span class="label label-default">embedded</span>
64
- <% end %>
65
- <% if process.stopping? %>
66
- <span class="label label-danger">quiet</span>
67
- <% end %>
68
- <% if process.identity == lead %>
69
- <span class="label label-warning">leader</span>
70
- <% end %>
71
- <br>
72
- <b><%= "#{t('Queues')}: " %></b>
73
- <% if process.weights %>
74
- <%= busy_weights(process.weights) %>
75
- <% else %>
76
- <%= process.queues.sort.join(", ") %>
77
- <% end %>
78
- <% if process.version != Sidekiq::VERSION %>
79
- <br>
80
- <b><%= "#{t('Version')}: " %></b>
81
- <% if process.version %>
82
- <%= process.version %>
83
- <% else %>
84
- <%= t('Unknown') %>
85
- <% end %>
86
- <% end %>
87
- </td>
88
- <td><%= relative_time(Time.at(process['started_at'])) %></td>
89
- <td class="num"><%= format_memory(process['rss'].to_i) %></td>
90
- <td class="num"><%= number_with_delimiter(process['concurrency']) %></td>
91
- <td class="num"><%= number_with_delimiter(process['busy']) %></td>
92
- <td>
93
- <% unless process.embedded? %>
94
- <form method="POST">
95
- <%= csrf_tag %>
96
- <input type="hidden" name="identity" value="<%= process['identity'] %>"/>
97
-
98
- <div class="btn-group pull-right flip">
99
- <% unless process.stopping? %><button class="btn btn-xs btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button><% end %>
100
- <button class="btn btn-xs btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
101
- </div>
102
- </form>
103
- <% end %>
104
- </td>
105
- </tr>
106
- <% end %>
107
- </table>
108
- </div>
109
-
110
- <div class="header-container">
111
- <h1><%= t('Jobs') %></h1>
112
- <% if @workset.size > 0 && @total_size > @count %>
113
- <%= erb :_paging, locals: { url: "#{root_path}busy" } %>
114
- <% end %>
115
- </div>
116
-
117
- <div class="table_container">
118
- <table class="workers table table-hover table-bordered table-striped">
119
- <thead>
120
- <th><%= t('Process') %></th>
121
- <th><%= t('TID') %></th>
122
- <th><%= t('JID') %></th>
123
- <th><%= t('Queue') %></th>
124
- <th><%= t('Job') %></th>
125
- <th><%= t('Arguments') %></th>
126
- <th><%= t('Started') %></th>
127
- </thead>
128
- <% @workset.each do |process, thread, work| %>
129
- <% job = work.job %>
130
- <tr>
131
- <td><%= process %></td>
132
- <td><%= thread %></td>
133
- <td><%= job.jid %></td>
134
- <td>
135
- <a href="<%= root_path %>queues/<%= work.queue %>"><%= work.queue %></a>
136
- </td>
137
- <td>
138
- <%= job.display_class %>
139
- <%= display_tags(job, nil) %>
140
- </td>
141
- <td>
142
- <div class="args"><%= display_args(job.display_args) %></div>
143
- </td>
144
- <td><%= relative_time(work.run_at) %></td>
145
- </tr>
146
- <% end %>
147
- </table>
148
- </div>
@@ -1,108 +0,0 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js" nonce="<%= csp_nonce %>"></script>
2
- <div class= "dashboard clearfix">
3
- <h3 >
4
- <%= t('Dashboard') %>
5
- <span id="beacon" class="beacon">
6
- <span class="ring"></span>
7
- <span class="dot"></span>
8
- </span>
9
- </h3>
10
- <div class="interval-slider ltr">
11
- <span class="interval-slider-label"><%= t('PollingInterval') %>:</span>
12
- <span id="sldr-text" class="current-interval">5 s</span>
13
- <br/>
14
- <input id="sldr" aria-label="<%= t("PollingIntervalMilliseconds") %>" type="range" min="2000" max="20000" step="1000" value="5000"/>
15
- </div>
16
- </div>
17
-
18
- <div class="row chart">
19
- <span id="sr-last-dashboard-update-template" hidden="hidden"><%= t("LastDashboardUpdateTemplateLiteral") %></span>
20
- <span id="sr-last-dashboard-update" class="sr-only" role="status"></span>
21
-
22
- <canvas id="realtime-chart">
23
- <%= to_json({
24
- processedLabel: t('Processed'),
25
- failedLabel: t('Failed'),
26
- labels: Array.new(50, ""),
27
- processed: Array.new(50),
28
- failed: Array.new(50),
29
- updateUrl: "#{root_path}stats",
30
- }) %>
31
- </canvas>
32
-
33
- <!-- start with a space in the legend so the height doesn't change when we add content dynamically -->
34
- <div id="realtime-legend">&nbsp;</div>
35
- </div>
36
-
37
- <div class="row header">
38
- <div class="col-sm-4 pull-left flip">
39
- <h3><%= t('History') %></h3>
40
- </div>
41
- </div>
42
- <div class="row chart">
43
- <div>
44
- <a href="<%= root_path %>?days=7" class="history-graph <%= "active" if params[:days] == "7" %>"><%= t('OneWeek') %></a>
45
- <a href="<%= root_path %>" class="history-graph <%= "active" if params[:days].nil? || params[:days] == "30" %>"><%= t('OneMonth') %></a>
46
- <a href="<%= root_path %>?days=90" class="history-graph <%= "active" if params[:days] == "90" %>"><%= t('ThreeMonths') %></a>
47
- <a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
48
- </div>
49
-
50
- <canvas id="history-chart">
51
- <%= to_json({
52
- processedLabel: t('Processed'),
53
- failedLabel: t('Failed'),
54
- processed: @processed_history.to_a.reverse,
55
- failed: @failed_history.to_a.reverse,
56
- }) %>
57
- </canvas>
58
- </div>
59
-
60
- <br/>
61
- <div class="row header">
62
- <div class="col-sm-4 pull-left flip">
63
- <h3>Redis</h3>
64
- </div>
65
- </div>
66
- <div class="stats-wrapper">
67
- <div class="stats-container">
68
- <% if @redis_info.fetch("redis_version", nil) %>
69
- <div class="stat">
70
- <h3 id="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
71
- <p><%= t('Version') %></p>
72
- </div>
73
- <% end %>
74
-
75
- <% if @redis_info.fetch("uptime_in_days", nil) %>
76
- <div class="stat">
77
- <h3 id="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
78
- <p><%= t('Uptime') %></p>
79
- </div>
80
- <% end %>
81
-
82
- <% if @redis_info.fetch("connected_clients", nil) %>
83
- <div class="stat">
84
- <h3 id="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
85
- <p><%= t('Connections') %></p>
86
- </div>
87
- <% end %>
88
-
89
- <% if @redis_info.fetch("used_memory_human", nil) %>
90
- <div class="stat">
91
- <h3 id="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
92
- <p><%= t('MemoryUsage') %></p>
93
- </div>
94
- <% end %>
95
-
96
- <% if @redis_info.fetch("used_memory_peak_human", nil) %>
97
- <div class="stat">
98
- <h3 id="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
99
- <p><%= t('PeakMemoryUsage') %></p>
100
- </div>
101
- <% end %>
102
- </div>
103
- </div>
104
-
105
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js" nonce="<%= csp_nonce %>"></script>
106
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js" nonce="<%= csp_nonce %>"></script>
107
- <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js" nonce="<%= csp_nonce %>"></script>
108
- <script type="text/javascript" src="<%= root_path %>javascripts/dashboard-charts.js" nonce="<%= csp_nonce %>"></script>
data/web/views/dead.erb DELETED
@@ -1,34 +0,0 @@
1
- <%= erb :_job_info, locals: { job: @dead, type: :dead } %>
2
-
3
- <h3><%= t('Error') %></h3>
4
- <div class="table_container">
5
- <table class="error table table-bordered table-striped table-hover">
6
- <tbody>
7
- <tr>
8
- <th><%= t('ErrorClass') %></th>
9
- <td>
10
- <code><%= @dead['error_class'] %></code>
11
- </td>
12
- </tr>
13
- <tr>
14
- <th><%= t('ErrorMessage') %></th>
15
- <td><%= h(@dead['error_message']) %></td>
16
- </tr>
17
- <% if @dead.error_backtrace %>
18
- <tr>
19
- <th><%= t('ErrorBacktrace') %></th>
20
- <td>
21
- <code><%= @dead.error_backtrace.join("<br/>") %></code>
22
- </td>
23
- </tr>
24
- <% end %>
25
- </tbody>
26
- </table>
27
- </div>
28
-
29
- <form class="form-horizontal" action="<%= root_path %>morgue/<%= job_params(@dead, @dead.score) %>" method="post">
30
- <%= csrf_tag %>
31
- <a class="btn btn-default" href="<%= root_path %>morgue"><%= t('GoBack') %></a>
32
- <input class="btn btn-primary" type="submit" name="retry" value="<%= t('RetryNow') %>" />
33
- <input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" />
34
- </form>
@@ -1,6 +0,0 @@
1
- <div>
2
- <form method="get" class="form-inline" action='<%= root_path %><%= which %>'>
3
- <label for="substr"><%= t('Filter') %></label>
4
- <input class="search form-control" type="search" name="substr" value="<%= h params[:substr] %>" placeholder="<%= t('AnyJobContent') %>"/>
5
- </form>
6
- </div>
data/web/views/layout.erb DELETED
@@ -1,42 +0,0 @@
1
- <!doctype html>
2
- <html dir="<%= text_direction %>">
3
- <head>
4
- <title><%= environment_title_prefix %><%= Sidekiq::NAME %></title>
5
- <meta charset="utf-8" />
6
- <meta name="viewport" content="width=device-width,initial-scale=1.0" />
7
-
8
- <link href="<%= root_path %>stylesheets/bootstrap.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
9
- <% if rtl? %>
10
- <link href="<%= root_path %>stylesheets/bootstrap-rtl.min.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>"/>
11
- <% end %>
12
-
13
- <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
14
- <link href="<%= root_path %>stylesheets/application-dark.css" media="screen and (prefers-color-scheme: dark)" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
15
- <% if rtl? %>
16
- <link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" nonce="<%= csp_nonce %>" />
17
- <% end %>
18
-
19
- <link rel="apple-touch-icon" href="<%= root_path %>images/apple-touch-icon.png">
20
- <link rel="shortcut icon" type="image/ico" href="<%= root_path %>images/favicon.ico" />
21
- <script type="text/javascript" src="<%= root_path %>javascripts/application.js" nonce="<%= csp_nonce %>"></script>
22
- <meta name="google" content="notranslate" />
23
- <%= display_custom_head %>
24
- </head>
25
- <body class="admin" data-locale="<%= locale %>">
26
- <%= erb :_nav %>
27
- <div id="page">
28
- <div class="container">
29
- <div class="row">
30
- <div class="col-sm-12 summary_bar">
31
- <%= erb :_summary %>
32
- </div>
33
-
34
- <div class="col-sm-12">
35
- <%= yield %>
36
- </div>
37
- </div>
38
- </div>
39
- </div>
40
- <%= erb :_footer %>
41
- </body>
42
- </html>
@@ -1,90 +0,0 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js" nonce="<%= csp_nonce %>"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js" nonce="<%= csp_nonce %>"></script>
3
- <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js" nonce="<%= csp_nonce %>"></script>
4
-
5
- <div class="header-container">
6
- <div class="page-title-container">
7
- <h1><%= t('Metrics') %></h1>
8
- <a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
9
- </div>
10
-
11
- <div>
12
- <form id="metrics-form" class="form-inline" action="<%= root_path %>metrics" method="get">
13
- <label for="substr"><%= t('Filter') %></label>
14
- <input id="class-filter" class="form-control" type="text" name="substr" placeholder="<%= t('Name') %>" value="<%= h params[:substr] %>">
15
- <select id="period-selector" class="form-control" name="period">
16
- <% @periods.each_key do |code| %>
17
- <% if code == @period %>
18
- <option selected value="<%= code %>"><%= code %></option>
19
- <% else %>
20
- <option value="<%= code %>"><%= code %></option>
21
- <% end %>
22
- <% end %>
23
- </select>
24
- </form>
25
- </div>
26
- </div>
27
-
28
- <%
29
- table_limit = 20
30
- chart_limit = 5
31
- job_results = @query_result.job_results.sort_by { |(kls, jr)| jr.totals["s"] }.reverse.first(table_limit)
32
- visible_kls = job_results.first(chart_limit).map(&:first)
33
- %>
34
-
35
- <% if job_results.any? %>
36
- <canvas id="job-metrics-overview-chart">
37
- <%= to_json({
38
- series: job_results.map { |(kls, jr)| [kls, jr.dig("series", "s")] }.to_h,
39
- marks: @query_result.marks.map { |m| [m.bucket, m.label] },
40
- labels: @query_result.buckets,
41
- visibleKls: visible_kls,
42
- yLabel: t('TotalExecutionTime'),
43
- units: t('Seconds').downcase,
44
- markLabel: t('Deploy'),
45
- }) %>
46
- </canvas>
47
- <% end %>
48
-
49
- <div class="table_container">
50
- <table class="table table-bordered table-striped table-hover">
51
- <tbody>
52
- <tr>
53
- <th><%= t('Name') %></th>
54
- <th><%= t('Success') %></th>
55
- <th><%= t('Failure') %></th>
56
- <th><%= t('TotalExecutionTime') %> (<%= t('Seconds') %>)</th>
57
- <th><%= t('AvgExecutionTime') %> (<%= t('Seconds') %>)</th>
58
- </tr>
59
- <% if job_results.any? %>
60
- <% job_results.each_with_index do |(kls, jr), i| %>
61
- <tr>
62
- <td>
63
- <div class="metrics-swatch-wrapper">
64
- <% id = "metrics-swatch-#{kls}" %>
65
- <input
66
- type="checkbox"
67
- id="<%= id %>"
68
- class="metrics-swatch"
69
- value="<%= kls %>"
70
- <%= visible_kls.include?(kls) ? 'checked' : '' %>
71
- />
72
- <code><a href="<%= root_path %>metrics/<%= kls %>?period=<%= @period %>"><%= kls %></a></code>
73
- </div>
74
- </td>
75
- <td class="num"><%= number_with_delimiter(jr.dig("totals", "p") - jr.dig("totals", "f")) %></td>
76
- <td class="num"><%= number_with_delimiter(jr.dig("totals", "f")) %></td>
77
- <td class="num"><%= number_with_delimiter(jr.dig("totals", "s"), precision: 2) %></td>
78
- <td class="num"><%= number_with_delimiter(jr.total_avg("s"), precision: 2) %></td>
79
- </tr>
80
- <% end %>
81
- <% else %>
82
- <tr><td colspan=5><%= t("NoDataFound") %></td></tr>
83
- <% end %>
84
- </tbody>
85
- </table>
86
- </div>
87
-
88
- <!--p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p-->
89
-
90
- <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js" nonce="<%= csp_nonce %>"></script>
@@ -1,59 +0,0 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js" nonce="<%= csp_nonce %>"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js" nonce="<%= csp_nonce %>"></script>
3
- <script type="text/javascript" src="<%= root_path %>javascripts/base-charts.js" nonce="<%= csp_nonce %>"></script>
4
-
5
- <%
6
- job_result = @query_result.job_results[@name]
7
- hist_totals = job_result.hist.values.first.zip(*job_result.hist.values[1..-1]).map(&:sum).reverse
8
- bucket_labels = Sidekiq::Metrics::Histogram::LABELS
9
- bucket_intervals = Sidekiq::Metrics::Histogram::BUCKET_INTERVALS
10
- %>
11
-
12
- <% if job_result.totals["s"] > 0 %>
13
- <div class="header-container">
14
- <div class="page-title-container">
15
- <h1>
16
- <a href="<%= root_path %>metrics?period=<%= @period %>"><%= t('Metrics') %></a> /
17
- <%= h @name %>
18
- </h1>
19
-
20
- <a target="blank" href="https://github.com/sidekiq/sidekiq/wiki/Metrics"><span class="info-circle" title="Click to learn more about metrics">?</span></a>
21
- </div>
22
-
23
- <%= erb :_metrics_period_select, locals: { periods: @periods, period: @period, path: "#{root_path}metrics/#{@name}" } %>
24
- </div>
25
-
26
- <canvas id="hist-totals-chart">
27
- <%= to_json({
28
- series: hist_totals,
29
- labels: bucket_labels,
30
- xLabel: t('ExecutionTime'),
31
- yLabel: t('Jobs'),
32
- units: t('Jobs').downcase,
33
- }) %>
34
- </canvas>
35
-
36
- <canvas id="hist-bubble-chart">
37
- <%= to_json({
38
- hist: job_result.hist,
39
- marks: @query_result.marks.map { |m| [m.bucket, m.label] },
40
- labels: @query_result.buckets,
41
- histIntervals: bucket_intervals,
42
- yLabel: t('ExecutionTime'),
43
- markLabel: t('Deploy'),
44
- yUnits: t('Seconds').downcase,
45
- zUnits: t('Jobs').downcase,
46
- }) %>
47
- </canvas>
48
-
49
- <!--p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p-->
50
- <% else %>
51
- <h1>
52
- <a href="<%= root_path %>/metrics"><%= t('Metrics') %></a> /
53
- <%= h @name %>
54
- </h1>
55
-
56
- <div class="alert alert-success"><%= t('NoJobMetricsFound') %></div>
57
- <% end %>
58
-
59
- <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js" nonce="<%= csp_nonce %>"></script>
data/web/views/morgue.erb DELETED
@@ -1,74 +0,0 @@
1
- <div class="header-container">
2
- <h1><%= t('DeadJobs') %></h1>
3
- <% if @dead.size > 0 && @total_size > @count %>
4
- <%= erb :_paging, locals: { url: "#{root_path}morgue" } %>
5
- <% end %>
6
- <%= filtering('morgue') %>
7
- </div>
8
-
9
- <% if @dead.size > 0 %>
10
- <form action="<%= root_path %>morgue" method="post">
11
- <%= csrf_tag %>
12
- <div class="table_container">
13
- <table class="table table-striped table-bordered table-hover">
14
- <thead>
15
- <tr>
16
- <th class="table-checkbox checkbox-column">
17
- <label>
18
- <input type="checkbox" class="check_all" />
19
- </label>
20
- </th>
21
- <th><%= t('LastRetry') %></th>
22
- <th><%= t('Queue') %></th>
23
- <th><%= t('Job') %></th>
24
- <th><%= t('Arguments') %></th>
25
- <th><%= t('Error') %></th>
26
- </tr>
27
- </thead>
28
- <% @dead.each do |entry| %>
29
- <tr>
30
- <td class="table-checkbox">
31
- <label>
32
- <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' class='shift_clickable' />
33
- </label>
34
- </td>
35
- <td>
36
- <a href="<%= root_path %>morgue/<%= job_params(entry.item, entry.score) %>"><%= relative_time(entry.at) %></a>
37
- </td>
38
- <td>
39
- <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
40
- </td>
41
- <td>
42
- <%= entry.display_class %>
43
- <%= display_tags(entry, "morgue") %>
44
- </td>
45
- <td>
46
- <div class="args"><%= display_args(entry.display_args) %></div>
47
- </td>
48
- <td>
49
- <% if entry.error? %>
50
- <div><%= h truncate("#{entry['error_class']}: #{entry['error_message']}", 200) %></div>
51
- <% end %>
52
- </td>
53
- </tr>
54
- <% end %>
55
- </table>
56
- </div>
57
- <input class="btn btn-primary pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
58
- <input class="btn btn-danger pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
59
- </form>
60
-
61
- <% unfiltered? do %>
62
- <form action="<%= root_path %>morgue/all/delete" method="post">
63
- <%= csrf_tag %>
64
- <input class="btn btn-danger pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
65
- </form>
66
- <form action="<%= root_path %>morgue/all/retry" method="post">
67
- <%= csrf_tag %>
68
- <input class="btn btn-danger pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
69
- </form>
70
- <% end %>
71
-
72
- <% else %>
73
- <div class="alert alert-success"><%= t('NoDeadJobsFound') %></div>
74
- <% end %>
data/web/views/queue.erb DELETED
@@ -1,55 +0,0 @@
1
- <div class="header-container">
2
- <h1><%= t('CurrentMessagesInQueue', :queue => h(@name)) %>
3
- <% if @queue.paused? %>
4
- <span class="label label-danger"><%= t('Paused') %></span>
5
- <% end %>
6
- <span class="badge badge-secondary"><%= number_with_delimiter(@total_size) %></span>
7
- </h1>
8
- <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
9
- </div>
10
-
11
- <div class="table_container">
12
- <table class="queue table table-hover table-bordered table-striped">
13
- <thead>
14
- <th><a href="<%= url %>?direction=<%= params[:direction] == 'asc' ? 'desc' : 'asc' %>"># <%= sort_direction_label %></a></th>
15
- <th><%= t('Job') %></th>
16
- <th><%= t('Arguments') %></th>
17
- <th><%= t('Context') %></th>
18
- <th><%= t('Actions') %></th>
19
- </thead>
20
- <% @jobs.each_with_index do |job, index| %>
21
- <tr title="<%= job.jid %>">
22
- <% if params[:direction] == 'asc' %>
23
- <td><%= @count * (@current_page - 1) + index + 1 %></td>
24
- <% else %>
25
- <td><%= @total_size - (@count * (@current_page - 1) + index) %></td>
26
- <% end %>
27
- <td>
28
- <%= h(job.display_class) %>
29
- <%= display_tags(job, nil) %>
30
- </td>
31
- <td>
32
- <% a = job.display_args %>
33
- <% if a.inspect.size > 100 %>
34
- <span id="job_<%= index %>"><%= h(a.inspect[0..100]) + "... " %></span>
35
- <button data-toggle="job_<%= index %>_full" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
36
- <div class="toggle" id="job_<%= index %>_full"><%= display_args(a) %></div>
37
- <% else %>
38
- <%= display_args(job.display_args) %>
39
- <% end %>
40
- </td>
41
- <td>
42
- <%= h(job["cattr"].inspect) if job["cattr"]&.any? %>
43
- </td>
44
- <td>
45
- <form action="<%= root_path %>queues/<%= CGI.escape(@name) %>/delete" method="post">
46
- <%= csrf_tag %>
47
- <input name="key_val" value="<%= h job.value %>" type="hidden" />
48
- <input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
49
- </form>
50
- </td>
51
- </tr>
52
- <% end %>
53
- </table>
54
- </div>
55
- <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>