sidekiq 6.2.2 → 6.5.5

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of sidekiq might be problematic. Click here for more details.

Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/Changes.md +150 -1
  3. data/LICENSE +3 -3
  4. data/README.md +9 -4
  5. data/bin/sidekiq +3 -3
  6. data/bin/sidekiqload +70 -66
  7. data/bin/sidekiqmon +1 -1
  8. data/lib/generators/sidekiq/job_generator.rb +57 -0
  9. data/lib/generators/sidekiq/templates/{worker.rb.erb → job.rb.erb} +2 -2
  10. data/lib/generators/sidekiq/templates/{worker_spec.rb.erb → job_spec.rb.erb} +1 -1
  11. data/lib/generators/sidekiq/templates/{worker_test.rb.erb → job_test.rb.erb} +1 -1
  12. data/lib/sidekiq/api.rb +232 -94
  13. data/lib/sidekiq/cli.rb +60 -40
  14. data/lib/sidekiq/client.rb +46 -66
  15. data/lib/sidekiq/{util.rb → component.rb} +12 -42
  16. data/lib/sidekiq/delay.rb +3 -1
  17. data/lib/sidekiq/extensions/generic_proxy.rb +1 -1
  18. data/lib/sidekiq/fetch.rb +22 -19
  19. data/lib/sidekiq/job.rb +8 -3
  20. data/lib/sidekiq/job_logger.rb +15 -27
  21. data/lib/sidekiq/job_retry.rb +78 -55
  22. data/lib/sidekiq/job_util.rb +71 -0
  23. data/lib/sidekiq/launcher.rb +62 -54
  24. data/lib/sidekiq/logger.rb +8 -18
  25. data/lib/sidekiq/manager.rb +35 -34
  26. data/lib/sidekiq/metrics/deploy.rb +47 -0
  27. data/lib/sidekiq/metrics/query.rb +153 -0
  28. data/lib/sidekiq/metrics/shared.rb +94 -0
  29. data/lib/sidekiq/metrics/tracking.rb +134 -0
  30. data/lib/sidekiq/middleware/chain.rb +82 -38
  31. data/lib/sidekiq/middleware/current_attributes.rb +63 -0
  32. data/lib/sidekiq/middleware/i18n.rb +6 -4
  33. data/lib/sidekiq/middleware/modules.rb +21 -0
  34. data/lib/sidekiq/monitor.rb +1 -1
  35. data/lib/sidekiq/paginator.rb +8 -8
  36. data/lib/sidekiq/processor.rb +47 -41
  37. data/lib/sidekiq/rails.rb +22 -4
  38. data/lib/sidekiq/redis_client_adapter.rb +154 -0
  39. data/lib/sidekiq/redis_connection.rb +85 -54
  40. data/lib/sidekiq/ring_buffer.rb +29 -0
  41. data/lib/sidekiq/scheduled.rb +54 -30
  42. data/lib/sidekiq/testing/inline.rb +4 -4
  43. data/lib/sidekiq/testing.rb +37 -36
  44. data/lib/sidekiq/transaction_aware_client.rb +45 -0
  45. data/lib/sidekiq/version.rb +1 -1
  46. data/lib/sidekiq/web/action.rb +3 -3
  47. data/lib/sidekiq/web/application.rb +25 -9
  48. data/lib/sidekiq/web/csrf_protection.rb +2 -2
  49. data/lib/sidekiq/web/helpers.rb +30 -18
  50. data/lib/sidekiq/web.rb +8 -4
  51. data/lib/sidekiq/worker.rb +136 -13
  52. data/lib/sidekiq.rb +114 -31
  53. data/sidekiq.gemspec +2 -2
  54. data/web/assets/javascripts/application.js +113 -60
  55. data/web/assets/javascripts/chart.min.js +13 -0
  56. data/web/assets/javascripts/chartjs-plugin-annotation.min.js +7 -0
  57. data/web/assets/javascripts/dashboard.js +50 -67
  58. data/web/assets/javascripts/graph.js +16 -0
  59. data/web/assets/javascripts/metrics.js +262 -0
  60. data/web/assets/stylesheets/application-dark.css +19 -23
  61. data/web/assets/stylesheets/application-rtl.css +0 -4
  62. data/web/assets/stylesheets/application.css +55 -109
  63. data/web/locales/el.yml +43 -19
  64. data/web/locales/en.yml +8 -1
  65. data/web/locales/pt-br.yml +27 -9
  66. data/web/views/_footer.erb +1 -1
  67. data/web/views/_nav.erb +1 -1
  68. data/web/views/_poll_link.erb +2 -5
  69. data/web/views/_summary.erb +7 -7
  70. data/web/views/busy.erb +4 -4
  71. data/web/views/dashboard.erb +9 -8
  72. data/web/views/layout.erb +1 -1
  73. data/web/views/metrics.erb +69 -0
  74. data/web/views/metrics_for_job.erb +87 -0
  75. data/web/views/queue.erb +14 -10
  76. data/web/views/queues.erb +1 -1
  77. metadata +27 -12
  78. data/lib/generators/sidekiq/worker_generator.rb +0 -57
  79. data/lib/sidekiq/exception_handler.rb +0 -27
data/web/locales/el.yml CHANGED
@@ -6,11 +6,12 @@ el: # <---- change this to your locale code
6
6
  Namespace: Namespace
7
7
  Realtime: Τρέχουσα Κατάσταση
8
8
  History: Ιστορικό
9
- Busy: Απασχολημένο
10
- Processed: Επεξεργάστηκε
11
- Failed: Απέτυχε
12
- Scheduled: Προγραματίστηκε
13
- Retries: Προσπάθειες
9
+ Busy: Υπό επεξεργασία
10
+ Utilization: Σε χρήση
11
+ Processed: Επεξεργάστηκαν
12
+ Failed: Απέτυχαν
13
+ Scheduled: Προγραμματισμένα
14
+ Retries: Επαναλήψεις
14
15
  Enqueued: Μπήκαν στην στοίβα
15
16
  Worker: Εργάτης
16
17
  LivePoll: Τρέχουσα Κατάσταση
@@ -20,40 +21,42 @@ el: # <---- change this to your locale code
20
21
  Job: Εργασία
21
22
  Arguments: Ορίσματα
22
23
  Extras: Extras
23
- Started: Ξεκίνησαν
24
+ Started: Ξεκίνησε
24
25
  ShowAll: Εμφάνιση Όλων
25
26
  CurrentMessagesInQueue: Τρέχουσες εργασίες <span class='title'>%{queue}</span>
26
27
  Delete: Διαγραφή
27
28
  AddToQueue: Προσθήκη στην στοίβα
28
- AreYouSureDeleteJob: Θέλετε να διαγράψετε την εργασία αυτη;
29
- AreYouSureDeleteQueue: Θέλετε να διαγράψετε την %{queue} στοίβα?
29
+ AreYouSureDeleteJob: Θέλετε να διαγράψετε αυτή την εργασία;
30
+ AreYouSureDeleteQueue: Θέλετε να διαγράψετε την στοίβα %{queue}; Αυτό θα διαγράψει όλες τις εργασίες εντός της στοίβας, θα εμφανιστεί ξανά εάν προωθήσετε περισσότερες εργασίες σε αυτήν στο μέλλον.
30
31
  Queues: Στοίβες
31
32
  Size: Μέγεθος
32
33
  Actions: Ενέργειες
33
- NextRetry: Επόμενη προσπάθεια
34
- RetryCount: Αριθμός προσπαθειών
35
- RetryNow: Προσπάθησε τώρα
36
- LastRetry: Τελευταία προσπάθεια
34
+ NextRetry: Επόμενη Προσπάθεια
35
+ RetryCount: Αριθμός Προσπαθειών
36
+ RetryNow: Επανάληψη Τώρα
37
+ # Kill: Kill
38
+ LastRetry: Τελευταία Προσπάθεια
37
39
  OriginallyFailed: Αρχικές Αποτυχίες
38
- AreYouSure: Είστε σίγουρος?
39
- DeleteAll: Διαγραφή όλων
40
+ AreYouSure: Είστε σίγουρος;
41
+ DeleteAll: Διαγραφή Όλων
40
42
  RetryAll: Επανάληψη Όλων
41
- NoRetriesFound: Δεν βρέθηκαν προσπάθειες
43
+ # KillAll: Kill All
44
+ NoRetriesFound: Δεν βρέθηκαν εργασίες προς επαναλήψη
42
45
  Error: Σφάλμα
43
46
  ErrorClass: Κλάση σφάλματος
44
47
  ErrorMessage: Μήνυμα Σφάλματος
45
- ErrorBacktrace: Σφάλμα Backtrace
48
+ ErrorBacktrace: Backtrace Σφάλματος
46
49
  GoBack: ← Πίσω
47
50
  NoScheduledFound: Δεν βρέθηκαν προγραμματισμένες εργασίες
48
51
  When: Πότε
49
52
  ScheduledJobs: Προγραμματισμένες Εργασίες
50
- idle: αδρανής
51
- active: ενεργή
53
+ idle: αδρανές
54
+ active: ενεργό
52
55
  Version: Έκδοση
53
56
  Connections: Συνδέσεις
54
57
  MemoryUsage: Χρήση Μνήμης
55
58
  PeakMemoryUsage: Μέγιστη Χρήση Μνήμης
56
- Uptime: Διάρκεια Λειτουργείας (ημέρες)
59
+ Uptime: Ημέρες Λειτουργίας
57
60
  OneWeek: 1 εβδομάδα
58
61
  OneMonth: 1 μήνας
59
62
  ThreeMonths: 3 μήνες
@@ -62,7 +65,28 @@ el: # <---- change this to your locale code
62
65
  DeadJobs: Αδρανείς Εργασίες
63
66
  NoDeadJobsFound: Δεν βρέθηκαν αδρανείς εργασίες
64
67
  Dead: Αδρανείς
68
+ Process: Διεργασία
65
69
  Processes: Διεργασίες
70
+ Name: Όνομα
66
71
  Thread: Νήμα
67
72
  Threads: Νήματα
68
73
  Jobs: Εργασίες
74
+ Paused: Σε παύση
75
+ Stop: Διακοπή
76
+ Quiet: Σίγαση
77
+ StopAll: Διακοπή Όλων
78
+ QuietAll: Σίγαση Όλων
79
+ PollingInterval: Συχνότητα Ανανέωσης
80
+ Plugins: Πρόσθετα
81
+ NotYetEnqueued: Δεν προστέθηκε στην στοίβα ακόμη
82
+ CreatedAt: Δημιουργήθηκε στις
83
+ BackToApp: Πίσω στην Εφαρμογή
84
+ Latency: Καθυστέρηση
85
+ Pause: Παύση
86
+ Unpause: Κατάργηση Παύσης
87
+ Metrics: Μετρήσεις
88
+ NoDataFound: Δεν βρέθηκαν δεδομένα
89
+ ExecutionTime: Συνολικός Χρόνος Εκτέλεσης
90
+ AvgExecutionTime: Μέσος Χρόνος Εκτέλεσης
91
+ # Context: Context
92
+
data/web/locales/en.yml CHANGED
@@ -27,7 +27,7 @@ en: # <---- change this to your locale code
27
27
  Delete: Delete
28
28
  AddToQueue: Add to queue
29
29
  AreYouSureDeleteJob: Are you sure you want to delete this job?
30
- AreYouSureDeleteQueue: Are you sure you want to delete the %{queue} queue?
30
+ AreYouSureDeleteQueue: Are you sure you want to delete the %{queue} queue? This will delete all jobs within the queue, it will reappear if you push more jobs to it in the future.
31
31
  Queues: Queues
32
32
  Size: Size
33
33
  Actions: Actions
@@ -84,3 +84,10 @@ en: # <---- change this to your locale code
84
84
  Latency: Latency
85
85
  Pause: Pause
86
86
  Unpause: Unpause
87
+ Metrics: Metrics
88
+ NoDataFound: No data found
89
+ ExecutionTime: Total Execution Time
90
+ AvgExecutionTime: Average Execution Time
91
+ Context: Context
92
+ Bucket: Bucket
93
+ NoJobMetricsFound: No recent job metrics were found
@@ -8,6 +8,7 @@
8
8
  History: Histórico
9
9
  Busy: Ocupados
10
10
  Processed: Processados
11
+ Utilization: Utilização
11
12
  Failed: Falhas
12
13
  Scheduled: Agendados
13
14
  Retries: Tentativas
@@ -26,18 +27,20 @@
26
27
  Delete: Apagar
27
28
  AddToQueue: Adicionar à fila
28
29
  AreYouSureDeleteJob: Deseja deletar esta tarefa?
29
- AreYouSureDeleteQueue: Deseja deletar a %{queue} fila?
30
+ AreYouSureDeleteQueue: Deseja deletar a fila %{queue}? Isso irá deletar todas as tarefas desta fila.
30
31
  Queues: Filas
31
32
  Size: Tamanho
32
33
  Actions: Ações
33
34
  NextRetry: Próxima Tentativa
34
35
  RetryCount: Número de Tentativas
35
36
  RetryNow: Tentar novamente agora
37
+ Kill: Matar
36
38
  LastRetry: Última tentativa
37
39
  OriginallyFailed: Falhou originalmente
38
40
  AreYouSure: Tem certeza?
39
41
  DeleteAll: Apagar tudo
40
42
  RetryAll: Tentar tudo novamente
43
+ KillAll: Matar todas
41
44
  NoRetriesFound: Nenhuma tentativa encontrada
42
45
  Error: Erro
43
46
  ErrorClass: Classe de erro
@@ -58,11 +61,26 @@
58
61
  OneMonth: 1 mês
59
62
  ThreeMonths: 3 meses
60
63
  SixMonths: 6 meses
61
- Failures : Falhas
62
- DeadJobs : Tarefas mortas
63
- NoDeadJobsFound : Nenhuma tarefa morta foi encontrada
64
- Dead : Morta
65
- Processes : Processos
66
- Thread : Thread
67
- Threads : Threads
68
- Jobs : Tarefas
64
+ Failures: Falhas
65
+ DeadJobs: Tarefas mortas
66
+ NoDeadJobsFound: Nenhuma tarefa morta foi encontrada
67
+ Dead: Morta
68
+ Process: Processo
69
+ Processes: Processos
70
+ Name: Nome
71
+ Thread: Thread
72
+ Threads: Threads
73
+ Jobs: Tarefas
74
+ Paused: Pausado
75
+ Stop: Parar
76
+ Quiet: Silenciar
77
+ StopAll: Parar Todos
78
+ QuietAll: Silenciar Todos
79
+ PollingInterval: Intervalo de Polling
80
+ Plugins: Plug-ins
81
+ NotYetEnqueued: Ainda não enfileirado
82
+ CreatedAt: Criado em
83
+ BackToApp: De volta ao aplicativo
84
+ Latency: Latência
85
+ Pause: Pausar
86
+ Unpause: Despausar
@@ -9,7 +9,7 @@
9
9
  <p class="navbar-text redis-url" title="<%= redis_connection_and_namespace %>"><%= redis_connection_and_namespace %></p>
10
10
  </li>
11
11
  <li>
12
- <p class="navbar-text server-utc-time"><%= server_utc_time %></p>
12
+ <p id="serverUtcTime" class="navbar-text server-utc-time"><%= server_utc_time %></p>
13
13
  </li>
14
14
  <li>
15
15
  <p class="navbar-text"><a style="color: gray;" href="https://github.com/mperham/sidekiq/wiki">docs</a></p>
data/web/views/_nav.erb CHANGED
@@ -1,7 +1,7 @@
1
1
  <div class="navbar navbar-default navbar-fixed-top">
2
2
  <div class="container-fluid">
3
3
  <div class="navbar-header" data-navbar="static">
4
- <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-menu">
4
+ <button type="button" class="navbar-toggle collapsed" data-toggle="navbar-menu" data-target="#navbar-menu">
5
5
  <span class="icon-bar"></span>
6
6
  <span class="icon-bar"></span>
7
7
  <span class="icon-bar"></span>
@@ -1,7 +1,4 @@
1
1
  <% if current_path != '' %>
2
- <% if params[:poll] %>
3
- <a id="live-poll" class="btn btn-primary active" href="<%= root_path + current_path %>"><%= t('StopPolling') %></a>
4
- <% else %>
5
- <a id="live-poll" class="btn btn-primary" href="<%= root_path + current_path %>?<%= qparams(poll: true) %>"><%= t('LivePoll') %></a>
6
- <% end %>
2
+ <a class="live-poll-start live-poll btn btn-primary"><%= t('LivePoll') %></a>
3
+ <a class="live-poll-stop live-poll btn btn-primary active"><%= t('StopPolling') %></a>
7
4
  <% end %>
@@ -1,39 +1,39 @@
1
1
  <ul class="list-unstyled summary row">
2
2
  <li class="processed col-sm-1">
3
- <span class="count"><%= number_with_delimiter(stats.processed) %></span>
3
+ <span id="txtProcessed" class="count"><%= number_with_delimiter(stats.processed) %></span>
4
4
  <span class="desc"><%= t('Processed') %></span>
5
5
  </li>
6
6
  <li class="failed col-sm-1">
7
- <span class="count"><%= number_with_delimiter(stats.failed) %></span>
7
+ <span id="txtFailed" class="count"><%= number_with_delimiter(stats.failed) %></span>
8
8
  <span class="desc"><%= t('Failed') %></span>
9
9
  </li>
10
10
  <li class="busy col-sm-1">
11
11
  <a href="<%= root_path %>busy">
12
- <span class="count"><%= number_with_delimiter(workers.size) %></span>
12
+ <span id="txtBusy" class="count"><%= number_with_delimiter(workset.size) %></span>
13
13
  <span class="desc"><%= t('Busy') %></span>
14
14
  </a>
15
15
  </li>
16
16
  <li class="enqueued col-sm-1">
17
17
  <a href="<%= root_path %>queues">
18
- <span class="count"><%= number_with_delimiter(stats.enqueued) %></span>
18
+ <span id="txtEnqueued" class="count"><%= number_with_delimiter(stats.enqueued) %></span>
19
19
  <span class="desc"><%= t('Enqueued') %></span>
20
20
  </a>
21
21
  </li>
22
22
  <li class="retries col-sm-1">
23
23
  <a href="<%= root_path %>retries">
24
- <span class="count"><%= number_with_delimiter(stats.retry_size) %></span>
24
+ <span id="txtRetries" class="count"><%= number_with_delimiter(stats.retry_size) %></span>
25
25
  <span class="desc"><%= t('Retries') %></span>
26
26
  </a>
27
27
  </li>
28
28
  <li class="scheduled col-sm-1">
29
29
  <a href="<%= root_path %>scheduled">
30
- <span class="count"><%= number_with_delimiter(stats.scheduled_size) %></span>
30
+ <span id="txtScheduled" class="count"><%= number_with_delimiter(stats.scheduled_size) %></span>
31
31
  <span class="desc"><%= t('Scheduled') %></span>
32
32
  </a>
33
33
  </li>
34
34
  <li class="dead col-sm-1">
35
35
  <a href="<%= root_path %>morgue">
36
- <span class="count"><%= number_with_delimiter(stats.dead_size) %></span>
36
+ <span id="txtDead" class="count"><%= number_with_delimiter(stats.dead_size) %></span>
37
37
  <span class="desc"><%= t('Dead') %></span>
38
38
  </a>
39
39
  </li>
data/web/views/busy.erb CHANGED
@@ -15,7 +15,7 @@
15
15
  <p><%= t('Threads') %></p>
16
16
  </div>
17
17
  <div class="stat">
18
- <h3><%= ws = workers.size; number_with_delimiter(ws) %></h3>
18
+ <h3><%= ws = workset.size; number_with_delimiter(ws) %></h3>
19
19
  <p><%= t('Busy') %></p>
20
20
  </div>
21
21
  <div class="stat">
@@ -48,13 +48,13 @@
48
48
  <thead>
49
49
  <th><%= t('Name') %></th>
50
50
  <th><%= t('Started') %></th>
51
- <th class="col-sm-1"><%= t('RSS') %><a href="https://github.com/mperham/sidekiq/wiki/Memory#rss"><span class="info-circle" title="Click to learn more about RSS">?</span></a></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
52
  <th class="col-sm-1"><%= t('Threads') %></th>
53
53
  <th class="col-sm-1"><%= t('Busy') %></th>
54
54
  <th>&nbsp;</th>
55
55
  </thead>
56
56
  <% lead = processes.leader %>
57
- <% processes.each do |process| %>
57
+ <% sorted_processes.each do |process| %>
58
58
  <tr>
59
59
  <td class="box">
60
60
  <%= "#{process['hostname']}:#{process['pid']}" %>
@@ -109,7 +109,7 @@
109
109
  <th><%= t('Arguments') %></th>
110
110
  <th><%= t('Started') %></th>
111
111
  </thead>
112
- <% workers.each do |process, thread, msg| %>
112
+ <% workset.each do |process, thread, msg| %>
113
113
  <% job = Sidekiq::JobRecord.new(msg['payload']) %>
114
114
  <tr>
115
115
  <td><%= process %></td>
@@ -1,17 +1,18 @@
1
+ <script type="text/javascript" src="<%= root_path %>javascripts/graph.js"></script>
1
2
  <script type="text/javascript" src="<%= root_path %>javascripts/dashboard.js"></script>
2
3
  <div class= "dashboard clearfix">
3
4
  <h3 >
4
5
  <%= t('Dashboard') %>
5
- <span class="beacon">
6
+ <span id="beacon" class="beacon">
6
7
  <span class="ring"></span>
7
8
  <span class="dot"></span>
8
9
  </span>
9
10
  </h3>
10
11
  <div class="interval-slider ltr">
11
12
  <span class="interval-slider-label"><%= t('PollingInterval') %>:</span>
12
- <span class="current-interval">5 sec</span>
13
+ <span id="sldr-text" class="current-interval">5 sec</span>
13
14
  <br/>
14
- <input type="range" min="2000" max="20000" step="1000" value="5000"/>
15
+ <input id="sldr" type="range" min="2000" max="20000" step="1000" value="5000"/>
15
16
  </div>
16
17
  </div>
17
18
 
@@ -47,35 +48,35 @@
47
48
  <div class="stats-container">
48
49
  <% if @redis_info.fetch("redis_version", nil) %>
49
50
  <div class="stat">
50
- <h3 class="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
51
+ <h3 id="redis_version"><%= @redis_info.fetch("redis_version") %></h3>
51
52
  <p><%= t('Version') %></p>
52
53
  </div>
53
54
  <% end %>
54
55
 
55
56
  <% if @redis_info.fetch("uptime_in_days", nil) %>
56
57
  <div class="stat">
57
- <h3 class="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
58
+ <h3 id="uptime_in_days"><%= @redis_info.fetch("uptime_in_days") %></h3>
58
59
  <p><%= t('Uptime') %></p>
59
60
  </div>
60
61
  <% end %>
61
62
 
62
63
  <% if @redis_info.fetch("connected_clients", nil) %>
63
64
  <div class="stat">
64
- <h3 class="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
65
+ <h3 id="connected_clients"><%= @redis_info.fetch("connected_clients") %></h3>
65
66
  <p><%= t('Connections') %></p>
66
67
  </div>
67
68
  <% end %>
68
69
 
69
70
  <% if @redis_info.fetch("used_memory_human", nil) %>
70
71
  <div class="stat">
71
- <h3 class="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
72
+ <h3 id="used_memory_human"><%= @redis_info.fetch("used_memory_human") %></h3>
72
73
  <p><%= t('MemoryUsage') %></p>
73
74
  </div>
74
75
  <% end %>
75
76
 
76
77
  <% if @redis_info.fetch("used_memory_peak_human", nil) %>
77
78
  <div class="stat">
78
- <h3 class="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
79
+ <h3 id="used_memory_peak_human"><%= @redis_info.fetch("used_memory_peak_human") %></h3>
79
80
  <p><%= t('PeakMemoryUsage') %></p>
80
81
  </div>
81
82
  <% end %>
data/web/views/layout.erb CHANGED
@@ -22,7 +22,7 @@
22
22
  <meta name="google" content="notranslate" />
23
23
  <%= display_custom_head %>
24
24
  </head>
25
- <body class="admin" data-poll-path="<%= poll_path %>" data-locale="<%= locale %>">
25
+ <body class="admin" data-locale="<%= locale %>">
26
26
  <%= erb :_nav %>
27
27
  <div id="page">
28
28
  <div class="container">
@@ -0,0 +1,69 @@
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>
@@ -0,0 +1,87 @@
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/queue.erb CHANGED
@@ -18,33 +18,37 @@
18
18
  <th><a href="<%= url %>?direction=<%= params[:direction] == 'asc' ? 'desc' : 'asc' %>"># <%= sort_direction_label %></a></th>
19
19
  <th><%= t('Job') %></th>
20
20
  <th><%= t('Arguments') %></th>
21
+ <th><%= t('Context') %></th>
21
22
  <th></th>
22
23
  </thead>
23
- <% @messages.each_with_index do |msg, index| %>
24
- <tr>
24
+ <% @jobs.each_with_index do |job, index| %>
25
+ <tr title="<%= job.jid %>">
25
26
  <% if params[:direction] == 'asc' %>
26
27
  <td><%= @count * (@current_page - 1) + index + 1 %></td>
27
28
  <% else %>
28
29
  <td><%= @total_size - (@count * (@current_page - 1) + index) %></td>
29
30
  <% end %>
30
31
  <td>
31
- <%= h(msg.display_class) %>
32
- <%= display_tags(msg, nil) %>
32
+ <%= h(job.display_class) %>
33
+ <%= display_tags(job, nil) %>
33
34
  </td>
34
35
  <td>
35
- <% a = msg.display_args %>
36
+ <% a = job.display_args %>
36
37
  <% if a.inspect.size > 100 %>
37
- <span class="worker_<%= index %>"><%= h(a.inspect[0..100]) + "... " %></span>
38
- <button data-toggle="collapse" data-target=".worker_<%= index %>" class="btn btn-default btn-xs"><%= t('ShowAll') %></button>
39
- <div class="toggle worker_<%= index %>"><%= display_args(a) %></div>
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>
40
41
  <% else %>
41
- <%= display_args(msg.display_args) %>
42
+ <%= display_args(job.display_args) %>
42
43
  <% end %>
43
44
  </td>
45
+ <td>
46
+ <%= h(job["cattr"].inspect) if job["cattr"]&.any? %>
47
+ </td>
44
48
  <td>
45
49
  <form action="<%= root_path %>queues/<%= CGI.escape(@name) %>/delete" method="post">
46
50
  <%= csrf_tag %>
47
- <input name="key_val" value="<%= h msg.value %>" type="hidden" />
51
+ <input name="key_val" value="<%= h job.value %>" type="hidden" />
48
52
  <input class="btn btn-danger btn-xs" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSure') %>" />
49
53
  </form>
50
54
  </td>
data/web/views/queues.erb CHANGED
@@ -21,7 +21,7 @@
21
21
  <td class="delete-confirm">
22
22
  <form action="<%=root_path %>queues/<%= CGI.escape(queue.name) %>" method="post">
23
23
  <%= csrf_tag %>
24
- <input class="btn btn-danger" type="submit" name="delete" value="<%= t('Delete') %>" data-confirm="<%= t('AreYouSureDeleteQueue', :queue => h(queue.name)) %>" />
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
25
 
26
26
  <% if Sidekiq.pro? %>
27
27
  <% if queue.paused? %>