sidekiq 6.5.10 → 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 (177) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +568 -18
  3. data/README.md +66 -38
  4. data/bin/kiq +17 -0
  5. data/bin/lint-herb +13 -0
  6. data/bin/multi_queue_bench +271 -0
  7. data/bin/sidekiq +3 -8
  8. data/bin/sidekiqload +215 -118
  9. data/bin/sidekiqmon +3 -0
  10. data/bin/webload +69 -0
  11. data/lib/active_job/queue_adapters/sidekiq_adapter.rb +124 -0
  12. data/lib/generators/sidekiq/job_generator.rb +17 -3
  13. data/lib/generators/sidekiq/templates/job.rb.erb +1 -1
  14. data/lib/sidekiq/api.rb +526 -218
  15. data/lib/sidekiq/capsule.rb +135 -0
  16. data/lib/sidekiq/cli.rb +88 -96
  17. data/lib/sidekiq/client.rb +114 -47
  18. data/lib/sidekiq/component.rb +71 -4
  19. data/lib/sidekiq/config.rb +316 -0
  20. data/lib/sidekiq/deploy.rb +64 -0
  21. data/lib/sidekiq/embedded.rb +64 -0
  22. data/lib/sidekiq/fetch.rb +12 -14
  23. data/lib/sidekiq/iterable_job.rb +56 -0
  24. data/lib/sidekiq/job/interrupt_handler.rb +24 -0
  25. data/lib/sidekiq/job/iterable/active_record_enumerator.rb +53 -0
  26. data/lib/sidekiq/job/iterable/csv_enumerator.rb +47 -0
  27. data/lib/sidekiq/job/iterable/enumerators.rb +135 -0
  28. data/lib/sidekiq/job/iterable.rb +322 -0
  29. data/lib/sidekiq/job.rb +397 -10
  30. data/lib/sidekiq/job_logger.rb +14 -11
  31. data/lib/sidekiq/job_retry.rb +78 -28
  32. data/lib/sidekiq/job_util.rb +58 -16
  33. data/lib/sidekiq/launcher.rb +86 -70
  34. data/lib/sidekiq/loader.rb +57 -0
  35. data/lib/sidekiq/logger.rb +25 -94
  36. data/lib/sidekiq/manager.rb +11 -13
  37. data/lib/sidekiq/metrics/query.rb +84 -48
  38. data/lib/sidekiq/metrics/shared.rb +29 -14
  39. data/lib/sidekiq/metrics/tracking.rb +49 -30
  40. data/lib/sidekiq/middleware/chain.rb +19 -18
  41. data/lib/sidekiq/middleware/current_attributes.rb +78 -21
  42. data/lib/sidekiq/middleware/i18n.rb +2 -0
  43. data/lib/sidekiq/middleware/modules.rb +2 -0
  44. data/lib/sidekiq/monitor.rb +15 -5
  45. data/lib/sidekiq/paginator.rb +26 -4
  46. data/lib/sidekiq/processor.rb +78 -65
  47. data/lib/sidekiq/profiler.rb +73 -0
  48. data/lib/sidekiq/rails.rb +45 -60
  49. data/lib/sidekiq/redis_client_adapter.rb +35 -72
  50. data/lib/sidekiq/redis_connection.rb +54 -114
  51. data/lib/sidekiq/ring_buffer.rb +3 -0
  52. data/lib/sidekiq/scheduled.rb +28 -30
  53. data/lib/sidekiq/systemd.rb +2 -0
  54. data/lib/sidekiq/test_api.rb +331 -0
  55. data/lib/sidekiq/testing/inline.rb +2 -30
  56. data/lib/sidekiq/testing.rb +2 -342
  57. data/lib/sidekiq/transaction_aware_client.rb +23 -9
  58. data/lib/sidekiq/tui/controls.rb +53 -0
  59. data/lib/sidekiq/tui/filtering.rb +53 -0
  60. data/lib/sidekiq/tui/tabs/base_tab.rb +230 -0
  61. data/lib/sidekiq/tui/tabs/busy.rb +104 -0
  62. data/lib/sidekiq/tui/tabs/dead.rb +14 -0
  63. data/lib/sidekiq/tui/tabs/home.rb +115 -0
  64. data/lib/sidekiq/tui/tabs/metrics.rb +114 -0
  65. data/lib/sidekiq/tui/tabs/queues.rb +83 -0
  66. data/lib/sidekiq/tui/tabs/retries.rb +14 -0
  67. data/lib/sidekiq/tui/tabs/scheduled.rb +14 -0
  68. data/lib/sidekiq/tui/tabs/set_tab.rb +91 -0
  69. data/lib/sidekiq/tui/tabs.rb +15 -0
  70. data/lib/sidekiq/tui.rb +390 -0
  71. data/lib/sidekiq/version.rb +6 -1
  72. data/lib/sidekiq/web/action.rb +149 -64
  73. data/lib/sidekiq/web/application.rb +379 -281
  74. data/lib/sidekiq/web/config.rb +117 -0
  75. data/lib/sidekiq/web/helpers.rb +190 -71
  76. data/lib/sidekiq/web/router.rb +62 -75
  77. data/lib/sidekiq/web.rb +68 -101
  78. data/lib/sidekiq/worker_compatibility_alias.rb +13 -0
  79. data/lib/sidekiq.rb +85 -269
  80. data/sidekiq.gemspec +15 -11
  81. data/web/assets/images/logo.png +0 -0
  82. data/web/assets/images/status.png +0 -0
  83. data/web/assets/javascripts/application.js +84 -24
  84. data/web/assets/javascripts/base-charts.js +120 -0
  85. data/web/assets/javascripts/chartjs-adapter-date-fns.min.js +7 -0
  86. data/web/assets/javascripts/dashboard-charts.js +194 -0
  87. data/web/assets/javascripts/dashboard.js +18 -234
  88. data/web/assets/javascripts/metrics.js +138 -120
  89. data/web/assets/stylesheets/style.css +776 -0
  90. data/web/locales/ar.yml +72 -70
  91. data/web/locales/cs.yml +64 -62
  92. data/web/locales/da.yml +62 -53
  93. data/web/locales/de.yml +67 -65
  94. data/web/locales/el.yml +4 -7
  95. data/web/locales/en.yml +89 -71
  96. data/web/locales/es.yml +91 -68
  97. data/web/locales/fa.yml +67 -65
  98. data/web/locales/fr.yml +82 -67
  99. data/web/locales/gd.yml +110 -0
  100. data/web/locales/he.yml +67 -64
  101. data/web/locales/hi.yml +95 -59
  102. data/web/locales/it.yml +94 -54
  103. data/web/locales/ja.yml +69 -70
  104. data/web/locales/ko.yml +54 -52
  105. data/web/locales/lt.yml +68 -66
  106. data/web/locales/nb.yml +63 -61
  107. data/web/locales/nl.yml +54 -52
  108. data/web/locales/pl.yml +47 -45
  109. data/web/locales/{pt-br.yml → pt-BR.yml} +81 -70
  110. data/web/locales/pt.yml +53 -51
  111. data/web/locales/ru.yml +69 -66
  112. data/web/locales/sv.yml +55 -53
  113. data/web/locales/ta.yml +100 -64
  114. data/web/locales/tr.yml +102 -0
  115. data/web/locales/uk.yml +87 -61
  116. data/web/locales/ur.yml +66 -64
  117. data/web/locales/vi.yml +69 -67
  118. data/web/locales/zh-CN.yml +107 -0
  119. data/web/locales/{zh-tw.yml → zh-TW.yml} +13 -3
  120. data/web/views/_footer.html.erb +32 -0
  121. data/web/views/_job_info.html.erb +115 -0
  122. data/web/views/_metrics_period_select.html.erb +15 -0
  123. data/web/views/_nav.html.erb +45 -0
  124. data/web/views/_paging.html.erb +26 -0
  125. data/web/views/_poll_link.html.erb +4 -0
  126. data/web/views/_summary.html.erb +40 -0
  127. data/web/views/busy.html.erb +155 -0
  128. data/web/views/dashboard.html.erb +104 -0
  129. data/web/views/dead.html.erb +38 -0
  130. data/web/views/filtering.html.erb +6 -0
  131. data/web/views/layout.html.erb +26 -0
  132. data/web/views/metrics.html.erb +85 -0
  133. data/web/views/metrics_for_job.html.erb +58 -0
  134. data/web/views/morgue.html.erb +69 -0
  135. data/web/views/profiles.html.erb +43 -0
  136. data/web/views/queue.html.erb +57 -0
  137. data/web/views/queues.html.erb +46 -0
  138. data/web/views/retries.html.erb +77 -0
  139. data/web/views/retry.html.erb +39 -0
  140. data/web/views/scheduled.html.erb +64 -0
  141. data/web/views/{scheduled_job_info.erb → scheduled_job_info.html.erb} +3 -3
  142. metadata +113 -70
  143. data/lib/sidekiq/delay.rb +0 -43
  144. data/lib/sidekiq/extensions/action_mailer.rb +0 -48
  145. data/lib/sidekiq/extensions/active_record.rb +0 -43
  146. data/lib/sidekiq/extensions/class_methods.rb +0 -43
  147. data/lib/sidekiq/extensions/generic_proxy.rb +0 -33
  148. data/lib/sidekiq/metrics/deploy.rb +0 -47
  149. data/lib/sidekiq/web/csrf_protection.rb +0 -180
  150. data/lib/sidekiq/worker.rb +0 -370
  151. data/web/assets/javascripts/graph.js +0 -16
  152. data/web/assets/stylesheets/application-dark.css +0 -143
  153. data/web/assets/stylesheets/application-rtl.css +0 -242
  154. data/web/assets/stylesheets/application.css +0 -999
  155. data/web/assets/stylesheets/bootstrap-rtl.min.css +0 -9
  156. data/web/assets/stylesheets/bootstrap.css +0 -5
  157. data/web/locales/zh-cn.yml +0 -93
  158. data/web/views/_footer.erb +0 -20
  159. data/web/views/_job_info.erb +0 -89
  160. data/web/views/_nav.erb +0 -52
  161. data/web/views/_paging.erb +0 -23
  162. data/web/views/_poll_link.erb +0 -4
  163. data/web/views/_status.erb +0 -4
  164. data/web/views/_summary.erb +0 -40
  165. data/web/views/busy.erb +0 -137
  166. data/web/views/dashboard.erb +0 -84
  167. data/web/views/dead.erb +0 -34
  168. data/web/views/layout.erb +0 -42
  169. data/web/views/metrics.erb +0 -69
  170. data/web/views/metrics_for_job.erb +0 -87
  171. data/web/views/morgue.erb +0 -78
  172. data/web/views/queue.erb +0 -59
  173. data/web/views/queues.erb +0 -38
  174. data/web/views/retries.erb +0 -83
  175. data/web/views/retry.erb +0 -34
  176. data/web/views/scheduled.erb +0 -57
  177. /data/{LICENSE → LICENSE.txt} +0 -0
data/web/views/busy.erb DELETED
@@ -1,137 +0,0 @@
1
- <div class="row header">
2
- <div class="col-sm-4 pull-left flip">
3
- <h3><%= t('Status') %></h3>
4
- </div>
5
- </div>
6
-
7
- <div class="stats-wrapper">
8
- <div class="stats-container">
9
- <div class="stat">
10
- <h3><%= s = processes.size; number_with_delimiter(s) %></h3>
11
- <p><%= t('Processes') %></p>
12
- </div>
13
- <div class="stat">
14
- <h3><%= x = processes.total_concurrency; number_with_delimiter(x) %></h3>
15
- <p><%= t('Threads') %></p>
16
- </div>
17
- <div class="stat">
18
- <h3><%= ws = workset.size; number_with_delimiter(ws) %></h3>
19
- <p><%= t('Busy') %></p>
20
- </div>
21
- <div class="stat">
22
- <h3><%= x == 0 ? 0 : ((ws / x.to_f) * 100).round(0) %>%</h3>
23
- <p><%= t('Utilization') %></p>
24
- </div>
25
- <div class="stat">
26
- <h3><%= format_memory(processes.total_rss) %></h3>
27
- <p><%= t('RSS') %></p>
28
- </div>
29
- </div>
30
- </div>
31
-
32
- <div class="row header">
33
- <div class="col-sm-4 pull-left flip">
34
- <h3><%= t('Processes') %></h3>
35
- </div>
36
- <div class="col-sm-3 pull-right flip">
37
- <form method="POST" class="warning-messages">
38
- <%= csrf_tag %>
39
- <div class="btn-group pull-right flip">
40
- <button class="btn btn-warn" type="submit" name="quiet" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('QuietAll') %></button>
41
- <button class="btn btn-danger" type="submit" name="stop" value="1" data-confirm="<%= t('AreYouSure') %>"><%= t('StopAll') %></button>
42
- </div>
43
- </form>
44
- </div>
45
- </div>
46
- <div class="table_container">
47
- <table class="processes table table-hover table-bordered table-striped">
48
- <thead>
49
- <th><%= t('Name') %></th>
50
- <th><%= t('Started') %></th>
51
- <th class="col-sm-1"><%= t('RSS') %><a target="blank" href="https://github.com/mperham/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></th>
52
- <th class="col-sm-1"><%= t('Threads') %></th>
53
- <th class="col-sm-1"><%= t('Busy') %></th>
54
- <th>&nbsp;</th>
55
- </thead>
56
- <% lead = processes.leader %>
57
- <% sorted_processes.each do |process| %>
58
- <tr>
59
- <td class="box">
60
- <%= "#{process['hostname']}:#{process['pid']}" %>
61
- <span class="label label-success"><%= process.tag %></span>
62
- <% process.labels.each do |label| %>
63
- <span class="label label-info"><%= label %></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
- <%= process.queues.join(", ") %>
74
- </td>
75
- <td><%= relative_time(Time.at(process['started_at'])) %></td>
76
- <td><%= format_memory(process['rss'].to_i) %></td>
77
- <td><%= process['concurrency'] %></td>
78
- <td><%= process['busy'] %></td>
79
- <td>
80
- <form method="POST">
81
- <%= csrf_tag %>
82
- <input type="hidden" name="identity" value="<%= process['identity'] %>"/>
83
-
84
- <div class="btn-group pull-right flip">
85
- <% unless process.stopping? %><button class="btn btn-xs btn-warn" type="submit" name="quiet" value="1"><%= t('Quiet') %></button><% end %>
86
- <button class="btn btn-xs btn-danger" type="submit" name="stop" value="1"><%= t('Stop') %></button>
87
- </div>
88
- </form>
89
- </td>
90
- </tr>
91
- <% end %>
92
- </table>
93
- </div>
94
-
95
- <div class="row header">
96
- <div class="col-sm-7">
97
- <h3><%= t('Jobs') %></h3>
98
- </div>
99
- <% if @workset.size > 0 && @total_size > @count %>
100
- <div class="col-sm-4">
101
- <%= erb :_paging, locals: { url: "#{root_path}busy" } %>
102
- </div>
103
- <% end %>
104
- </div>
105
-
106
- <div class="table_container">
107
- <table class="workers table table-hover table-bordered table-striped">
108
- <thead>
109
- <th><%= t('Process') %></th>
110
- <th><%= t('TID') %></th>
111
- <th><%= t('JID') %></th>
112
- <th><%= t('Queue') %></th>
113
- <th><%= t('Job') %></th>
114
- <th><%= t('Arguments') %></th>
115
- <th><%= t('Started') %></th>
116
- </thead>
117
- <% @workset.each do |process, thread, msg| %>
118
- <% job = Sidekiq::JobRecord.new(msg['payload']) %>
119
- <tr>
120
- <td><%= process %></td>
121
- <td><%= thread %></td>
122
- <td><%= job.jid %></td>
123
- <td>
124
- <a href="<%= root_path %>queues/<%= msg['queue'] %>"><%= msg['queue'] %></a>
125
- </td>
126
- <td>
127
- <%= job.display_class %>
128
- <%= display_tags(job, nil) %>
129
- </td>
130
- <td>
131
- <div class="args"><%= display_args(job.display_args) %></div>
132
- </td>
133
- <td><%= relative_time(Time.at(msg['run_at'])) %></td>
134
- </tr>
135
- <% end %>
136
- </table>
137
- </div>
@@ -1,84 +0,0 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/graph.js"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js"></script>
3
- <div class= "dashboard clearfix">
4
- <h3 >
5
- <%= t('Dashboard') %>
6
- <span id="beacon" class="beacon">
7
- <span class="ring"></span>
8
- <span class="dot"></span>
9
- </span>
10
- </h3>
11
- <div class="interval-slider ltr">
12
- <span class="interval-slider-label"><%= t('PollingInterval') %>:</span>
13
- <span id="sldr-text" class="current-interval">5 sec</span>
14
- <br/>
15
- <input id="sldr" type="range" min="2000" max="20000" step="1000" value="5000"/>
16
- </div>
17
- </div>
18
-
19
- <div class="row chart">
20
- <div id="realtime" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>"></div>
21
- <div id="realtime-legend"></div>
22
- </div>
23
-
24
- <div class="row header">
25
- <div class="col-sm-4 pull-left flip">
26
- <h3><%= t('History') %></h3>
27
- </div>
28
- </div>
29
- <div class="row chart">
30
- <div>
31
- <a href="<%= root_path %>?days=7" class="history-graph <%= "active" if params[:days] == "7" %>"><%= t('OneWeek') %></a>
32
- <a href="<%= root_path %>" class="history-graph <%= "active" if params[:days].nil? || params[:days] == "30" %>"><%= t('OneMonth') %></a>
33
- <a href="<%= root_path %>?days=90" class="history-graph <%= "active" if params[:days] == "90" %>"><%= t('ThreeMonths') %></a>
34
- <a href="<%= root_path %>?days=180" class="history-graph <%= "active" if params[:days] == "180" %>"><%= t('SixMonths') %></a>
35
- </div>
36
-
37
- <div id="history" data-processed-label="<%= t('Processed') %>" data-failed-label="<%= t('Failed') %>" data-processed="<%= h Sidekiq.dump_json(@processed_history) %>" data-failed="<%= h Sidekiq.dump_json(@failed_history) %>" data-update-url="<%= root_path %>stats"></div>
38
- <div id="history-legend"></div>
39
- </div>
40
-
41
- <br/>
42
- <div class="row header">
43
- <div class="col-sm-4 pull-left flip">
44
- <h3>Redis</h3>
45
- </div>
46
- </div>
47
- <div class="stats-wrapper">
48
- <div class="stats-container">
49
- <% if @redis_info.fetch("redis_version", nil) %>
50
- <div class="stat">
51
- <h3 id="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
52
- <p><%= t('Version') %></p>
53
- </div>
54
- <% end %>
55
-
56
- <% if @redis_info.fetch("uptime_in_days", nil) %>
57
- <div class="stat">
58
- <h3 id="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
59
- <p><%= t('Uptime') %></p>
60
- </div>
61
- <% end %>
62
-
63
- <% if @redis_info.fetch("connected_clients", nil) %>
64
- <div class="stat">
65
- <h3 id="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
66
- <p><%= t('Connections') %></p>
67
- </div>
68
- <% end %>
69
-
70
- <% if @redis_info.fetch("used_memory_human", nil) %>
71
- <div class="stat">
72
- <h3 id="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
73
- <p><%= t('MemoryUsage') %></p>
74
- </div>
75
- <% end %>
76
-
77
- <% if @redis_info.fetch("used_memory_peak_human", nil) %>
78
- <div class="stat">
79
- <h3 id="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
80
- <p><%= t('PeakMemoryUsage') %></p>
81
- </div>
82
- <% end %>
83
- </div>
84
- </div>
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>
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" />
9
- <% if rtl? %>
10
- <link href="<%= root_path %>stylesheets/bootstrap-rtl.min.css" media="screen" rel="stylesheet" type="text/css"/>
11
- <% end %>
12
-
13
- <link href="<%= root_path %>stylesheets/application.css" media="screen" rel="stylesheet" type="text/css" />
14
- <link href="<%= root_path %>stylesheets/application-dark.css" media="screen and (prefers-color-scheme: dark)" rel="stylesheet" type="text/css" />
15
- <% if rtl? %>
16
- <link href="<%= root_path %>stylesheets/application-rtl.css" media="screen" rel="stylesheet" type="text/css" />
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"></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,69 +0,0 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
3
- <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></script>
4
-
5
- <h2>Total execution time</h2>
6
-
7
- <%
8
- table_limit = 20
9
- chart_limit = 5
10
- job_results = @query_result.job_results.sort_by { |(kls, jr)| jr.totals["s"] }.reverse.first(table_limit)
11
- visible_kls = job_results.first(chart_limit).map(&:first)
12
- %>
13
-
14
- <canvas id="job-metrics-overview-chart"></canvas>
15
-
16
- <script>
17
- window.jobMetricsChart = new JobMetricsOverviewChart(
18
- "job-metrics-overview-chart",
19
- <%= Sidekiq.dump_json({
20
- series: job_results.map { |(kls, jr)| [kls, jr.dig("series", "s")] }.to_h,
21
- marks: @query_result.marks.map { |m| [m.bucket, m.label] },
22
- visible: visible_kls,
23
- labels: @query_result.buckets,
24
- }) %>
25
- )
26
- </script>
27
-
28
- <h2>Most Time-Consuming Jobs</h2>
29
-
30
- <div class="table_container">
31
- <table class="table table-bordered table-striped table-hover">
32
- <tbody>
33
- <tr>
34
- <th><%= t('Name') %></th>
35
- <th><%= t('Processed') %></th>
36
- <th><%= t('Failed') %></th>
37
- <th><%= t('ExecutionTime') %></th>
38
- <th><%= t('AvgExecutionTime') %></th>
39
- </tr>
40
- <% if job_results.any? %>
41
- <% job_results.each_with_index do |(kls, jr), i| %>
42
- <tr>
43
- <td>
44
- <div class="metrics-swatch-wrapper">
45
- <% id = "metrics-swatch-#{kls}" %>
46
- <input
47
- type="checkbox"
48
- id="<%= id %>"
49
- class="metrics-swatch"
50
- value="<%= kls %>"
51
- />
52
- <code><a href="<%= root_path %>metrics/<%= kls %>"><%= kls %></a></code>
53
- </div>
54
- <script>jobMetricsChart.registerSwatch("<%= id %>")</script>
55
- </td>
56
- <td><%= jr.dig("totals", "p") %></td>
57
- <td><%= jr.dig("totals", "f") %></td>
58
- <td><%= jr.dig("totals", "s").round(2) %> seconds</td>
59
- <td><%= jr.total_avg("s").round(2) %> seconds</td>
60
- </tr>
61
- <% end %>
62
- <% else %>
63
- <tr><td colspan=5><%= t("NoDataFound") %></td></tr>
64
- <% end %>
65
- </tbody>
66
- </table>
67
- </div>
68
-
69
- <p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p>
@@ -1,87 +0,0 @@
1
- <script type="text/javascript" src="<%= root_path %>javascripts/chart.min.js"></script>
2
- <script type="text/javascript" src="<%= root_path %>javascripts/chartjs-plugin-annotation.min.js"></script>
3
- <script type="text/javascript" src="<%= root_path %>javascripts/metrics.js"></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)
8
- bucket_labels =Sidekiq::Metrics::Histogram::LABELS
9
- bucket_intervals =Sidekiq::Metrics::Histogram::BUCKET_INTERVALS.reverse
10
-
11
- # Replace INFINITY since it can't be represented as JSON
12
- bucket_intervals[0] = bucket_intervals[1] * 2
13
- %>
14
-
15
- <% if job_result.totals["s"] > 0 %>
16
- <div class="header-with-subheader">
17
- <h1>
18
- <a href="<%= root_path %>/metrics"><%= t(:metrics).to_s.titleize %></a> /
19
- <%= h @name %>
20
- </h1>
21
- <h2>Histogram summary</h2>
22
- </div>
23
-
24
- <canvas id="hist-totals-chart"></canvas>
25
-
26
- <script>
27
- window.histTotalsChart = new HistTotalsChart(
28
- "hist-totals-chart",
29
- <%= Sidekiq.dump_json({
30
- series: hist_totals,
31
- labels: bucket_labels,
32
- }) %>
33
- )
34
- </script>
35
-
36
- <h2>Performance over time</h2>
37
-
38
- <canvas id="hist-bubble-chart"></canvas>
39
-
40
- <script>
41
- window.histBubbleChart = new HistBubbleChart(
42
- "hist-bubble-chart",
43
- <%= Sidekiq.dump_json({
44
- hist: job_result.hist,
45
- marks: @query_result.marks.map { |m| [m.bucket, m.label] },
46
- labels: @query_result.buckets,
47
- histIntervals: bucket_intervals,
48
- }) %>
49
- )
50
- </script>
51
-
52
- <div class="table_container">
53
- <table class="table table-bordered table-striped table-hover">
54
- <tbody>
55
- <tr>
56
- <th><%= t('Time') %></th>
57
- <th><%= t('Processed') %></th>
58
- <th><%= t('Failed') %></th>
59
- <th><%= t('ExecutionTime') %></th>
60
- <th><%= t('AvgExecutionTime') %></th>
61
- </tr>
62
- <% @query_result.buckets.reverse.each do |bucket| %>
63
- <tr>
64
- <td><%= bucket %></td>
65
- <td><%= job_result.series.dig("p", bucket) %></td>
66
- <td><%= job_result.series.dig("f", bucket) %></td>
67
- <% if (total_sec = job_result.series.dig("s", bucket)) > 0 %>
68
- <td><%= total_sec.round(2) %> seconds</td>
69
- <td><%= job_result.series_avg("s")[bucket].round(2) %> seconds</td>
70
- <% else %>
71
- <td>&mdash;</td>
72
- <td>&mdash;</td>
73
- <% end %>
74
- </tr>
75
- <% end %>
76
- </tbody>
77
- </table>
78
- </div>
79
- <p><small>Data from <%= @query_result.starts_at %> to <%= @query_result.ends_at %></small></p>
80
- <% else %>
81
- <h1>
82
- <a href="<%= root_path %>/metrics"><%= t(:metrics).to_s.titleize %></a> /
83
- <%= h @name %>
84
- </h1>
85
-
86
- <div class="alert alert-success"><%= t('NoJobMetricsFound') %></div>
87
- <% end %>
data/web/views/morgue.erb DELETED
@@ -1,78 +0,0 @@
1
- <header class="row">
2
- <div class="col-sm-5">
3
- <h3><%= t('DeadJobs') %></h3>
4
- </div>
5
- <% if @dead.size > 0 && @total_size > @count %>
6
- <div class="col-sm-4">
7
- <%= erb :_paging, locals: { url: "#{root_path}morgue" } %>
8
- </div>
9
- <% end %>
10
- <%= filtering('dead') %>
11
- </header>
12
-
13
- <% if @dead.size > 0 %>
14
- <form action="<%= root_path %>morgue" method="post">
15
- <%= csrf_tag %>
16
- <div class="table_container">
17
- <table class="table table-striped table-bordered table-hover">
18
- <thead>
19
- <tr>
20
- <th class="table-checkbox checkbox-column">
21
- <label>
22
- <input type="checkbox" class="check_all" />
23
- </label>
24
- </th>
25
- <th><%= t('LastRetry') %></th>
26
- <th><%= t('Queue') %></th>
27
- <th><%= t('Job') %></th>
28
- <th><%= t('Arguments') %></th>
29
- <th><%= t('Error') %></th>
30
- </tr>
31
- </thead>
32
- <% @dead.each do |entry| %>
33
- <tr>
34
- <td class="table-checkbox">
35
- <label>
36
- <input type='checkbox' name='key[]' value='<%= job_params(entry.item, entry.score) %>' />
37
- </label>
38
- </td>
39
- <td>
40
- <a href="<%= root_path %>morgue/<%= job_params(entry.item, entry.score) %>"><%= relative_time(entry.at) %></a>
41
- </td>
42
- <td>
43
- <a href="<%= root_path %>queues/<%= entry.queue %>"><%= entry.queue %></a>
44
- </td>
45
- <td>
46
- <%= entry.display_class %>
47
- <%= display_tags(entry, "dead") %>
48
- </td>
49
- <td>
50
- <div class="args"><%= display_args(entry.display_args) %></div>
51
- </td>
52
- <td>
53
- <% if entry.error? %>
54
- <div><%= h truncate("#{entry['error_class']}: #{entry['error_message']}", 200) %></div>
55
- <% end %>
56
- </td>
57
- </tr>
58
- <% end %>
59
- </table>
60
- </div>
61
- <input class="btn btn-primary pull-left flip" type="submit" name="retry" value="<%= t('RetryNow') %>" />
62
- <input class="btn btn-danger pull-left flip" type="submit" name="delete" value="<%= t('Delete') %>" />
63
- </form>
64
-
65
- <% unfiltered? do %>
66
- <form action="<%= root_path %>morgue/all/delete" method="post">
67
- <%= csrf_tag %>
68
- <input class="btn btn-danger pull-right flip" type="submit" name="delete" value="<%= t('DeleteAll') %>" data-confirm="<%= t('AreYouSure') %>" />
69
- </form>
70
- <form action="<%= root_path %>morgue/all/retry" method="post">
71
- <%= csrf_tag %>
72
- <input class="btn btn-danger pull-right flip" type="submit" name="retry" value="<%= t('RetryAll') %>" data-confirm="<%= t('AreYouSure') %>" />
73
- </form>
74
- <% end %>
75
-
76
- <% else %>
77
- <div class="alert alert-success"><%= t('NoDeadJobsFound') %></div>
78
- <% end %>
data/web/views/queue.erb DELETED
@@ -1,59 +0,0 @@
1
- <header class="row">
2
- <div class="col-sm-5">
3
- <h3>
4
- <%= t('CurrentMessagesInQueue', :queue => h(@name)) %>
5
- <% if @queue.paused? %>
6
- <span class="label label-danger"><%= t('Paused') %></span>
7
- <% end %>
8
- <span class="badge badge-secondary"><%= number_with_delimiter(@total_size) %></span>
9
- </h3>
10
- </div>
11
- <div class="col-sm-4 pull-right flip">
12
- <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
13
- </div>
14
- </header>
15
- <div class="table_container">
16
- <table class="queue table table-hover table-bordered table-striped">
17
- <thead>
18
- <th><a href="<%= url %>?direction=<%= params[:direction] == 'asc' ? 'desc' : 'asc' %>"># <%= sort_direction_label %></a></th>
19
- <th><%= t('Job') %></th>
20
- <th><%= t('Arguments') %></th>
21
- <th><%= t('Context') %></th>
22
- <th></th>
23
- </thead>
24
- <% @jobs.each_with_index do |job, index| %>
25
- <tr title="<%= job.jid %>">
26
- <% if params[:direction] == 'asc' %>
27
- <td><%= @count * (@current_page - 1) + index + 1 %></td>
28
- <% else %>
29
- <td><%= @total_size - (@count * (@current_page - 1) + index) %></td>
30
- <% end %>
31
- <td>
32
- <%= h(job.display_class) %>
33
- <%= display_tags(job, nil) %>
34
- </td>
35
- <td>
36
- <% a = job.display_args %>
37
- <% if a.inspect.size > 100 %>
38
- <span id="job_<%= index %>"><%= h(a.inspect[0..100]) + "... " %></span>
39
- <button data-toggle="job_<%= index %>_full" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
40
- <div class="toggle" id="job_<%= index %>_full"><%= display_args(a) %></div>
41
- <% else %>
42
- <%= display_args(job.display_args) %>
43
- <% end %>
44
- </td>
45
- <td>
46
- <%= h(job["cattr"].inspect) if job["cattr"]&.any? %>
47
- </td>
48
- <td>
49
- <form action="<%= root_path %>queues/<%= CGI.escape(@name) %>/delete" method="post">
50
- <%= csrf_tag %>
51
- <input name="key_val" value="<%= h job.value %>" type="hidden" />
52
- <input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
53
- </form>
54
- </td>
55
- </tr>
56
- <% end %>
57
- </table>
58
- </div>
59
- <%= erb :_paging, locals: { url: "#{root_path}queues/#{CGI.escape(@name)}" } %>
data/web/views/queues.erb DELETED
@@ -1,38 +0,0 @@
1
- <h3><%= t('Queues') %></h3>
2
-
3
- <div class="table_container">
4
- <table class="queues table table-hover table-bordered table-striped">
5
- <thead>
6
- <th><%= t('Queue') %></th>
7
- <th><%= t('Size') %></th>
8
- <th><%= t('Latency') %></th>
9
- <th><%= t('Actions') %></th>
10
- </thead>
11
- <% @queues.each do |queue| %>
12
- <tr>
13
- <td>
14
- <a href="<%= root_path %>queues/<%= CGI.escape(queue.name) %>"><%= h queue.name %></a>
15
- <% if queue.paused? %>
16
- <span class="label label-danger"><%= t('Paused') %></span>
17
- <% end %>
18
- </td>
19
- <td><%= number_with_delimiter(queue.size) %> </td>
20
- <td><% queue_latency = queue.latency %><%= number_with_delimiter(queue_latency.round(2)) %><%= (queue_latency < 60) ? '' : " (#{relative_time(Time.at(Time.now.to_f - queue_latency))})" %> </td>
21
- <td class="delete-confirm">
22
- <form action="<%=root_path %>queues/<%= CGI.escape(queue.name) %>" method="post">
23
- <%= csrf_tag %>
24
- <input class="btn btn-danger" type="submit" name="delete" title="This will delete all jobs within the queue, it will reappear if you push more jobs to it in the future." value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>" />
25
-
26
- <% if Sidekiq.pro? %>
27
- <% if queue.paused? %>
28
- <input class="btn btn-danger" type="submit" name="unpause" value="<%= t('Unpause') %>" />
29
- <% else %>
30
- <input class="btn btn-danger" type="submit" name="pause" value="<%= t('Pause') %>" />
31
- <% end %>
32
- <% end %>
33
- </form>
34
- </td>
35
- </tr>
36
- <% end %>
37
- </table>
38
- </div>