mirror of
https://github.com/endofunky/sidetiq.git
synced 2022-11-09 13:53:30 -05:00
Show job history in web extension.
This commit is contained in:
parent
1186088a4f
commit
5b20e39ca0
12 changed files with 198 additions and 61 deletions
|
@ -24,7 +24,7 @@ module Sidetiq
|
|||
end
|
||||
|
||||
configure do |config|
|
||||
config.worker_history = 100
|
||||
config.worker_history = 50
|
||||
config.resolution = 1
|
||||
config.lock_expire = 1000
|
||||
config.utc = false
|
||||
|
|
|
@ -32,8 +32,8 @@ module Sidetiq
|
|||
error: "",
|
||||
exception: "",
|
||||
backtrace: "",
|
||||
processor: "#{Socket.gethostname}:#{Process.pid}-#{Thread.current.object_id}",
|
||||
processed: Time.now.iso8601
|
||||
node: "#{Socket.gethostname}:#{Process.pid}-#{Thread.current.object_id}",
|
||||
timestamp: Time.now.iso8601
|
||||
}
|
||||
end
|
||||
|
||||
|
|
22
lib/sidetiq/views/_worker_nav.erb
Normal file
22
lib/sidetiq/views/_worker_nav.erb
Normal file
|
@ -0,0 +1,22 @@
|
|||
<div class="span3">
|
||||
<ul class="nav nav-list sidetiq-sidenav">
|
||||
<li>
|
||||
<a href="/sidetiq">
|
||||
<i class="icon-chevron-right"></i>
|
||||
Home
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/sidetiq/<%= @worker.name %>/schedule">
|
||||
<i class="icon-chevron-right"></i>
|
||||
Job Schedule
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/sidetiq/<%= @worker.name %>/history">
|
||||
<i class="icon-chevron-right"></i>
|
||||
Job History
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
36
lib/sidetiq/views/assets/styles.css
Normal file
36
lib/sidetiq/views/assets/styles.css
Normal file
|
@ -0,0 +1,36 @@
|
|||
<style>
|
||||
.sidetiq-container {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.sidetiq-sidenav {
|
||||
width: 228px;
|
||||
padding: 0;
|
||||
background-color: #fff;
|
||||
-webkit-border-radius: 6px;
|
||||
-moz-border-radius: 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.sidetiq-sidenav > li > a {
|
||||
display: block;
|
||||
width: 190px \9;
|
||||
margin: 0 0 -1px;
|
||||
padding: 8px 14px;
|
||||
border: 1px solid #e5e5e5;
|
||||
}
|
||||
j
|
||||
.sidetiq-sidenav > li:first-child > a {
|
||||
-webkit-border-radius: 6px 6px 0 0;
|
||||
-moz-border-radius: 6px 6px 0 0;
|
||||
border-radius: 6px 6px 0 0;
|
||||
}
|
||||
|
||||
.sidetiq-sidenav > li:last-child > a {
|
||||
-webkit-border-radius: 0 0 6px 6px;
|
||||
-moz-border-radius: 0 0 6px 6px;
|
||||
border-radius: 0 0 6px 6px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
<% @schedules.each do |worker, schedule| %>
|
||||
<tr>
|
||||
<td>
|
||||
<a href="<%= "#{root_path}sidetiq/#{worker.name}" %>"><%= worker.name %></a>
|
||||
<a href="<%= "#{root_path}sidetiq/#{worker.name}/schedule" %>"><%= worker.name %></a>
|
||||
<td><%= worker.get_sidekiq_options["queue"] %></td>
|
||||
<td>
|
||||
<%= relative_time(schedule.next_occurrence(@time)) %>
|
||||
|
|
|
@ -1,49 +0,0 @@
|
|||
<header class="row">
|
||||
<div class="span5">
|
||||
<h3>Recurring Job: <%= @worker.name %></h3>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<% if (recurrences = @schedule.recurrence_rules).length > 0 %>
|
||||
<table class="table table-striped table-bordered table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th>Recurrences</th>
|
||||
</thead>
|
||||
<% recurrences.each do |rule| %>
|
||||
<tr>
|
||||
<td><%= rule.to_s %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<br />
|
||||
|
||||
<% if (exceptions = @schedule.exception_rules).length > 0 %>
|
||||
<table class="table table-striped table-bordered table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th>Exceptions</th>
|
||||
</thead>
|
||||
<% exceptions.each do |rule| %>
|
||||
<tr>
|
||||
<td><%= rule.to_s %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<br />
|
||||
|
||||
<table class="table table-striped table-bordered table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th style="width: 25%">Next 10 runs</th>
|
||||
<th style="width: 75%" />
|
||||
<% @schedule.next_occurrences(10, @time).each do |time| %>
|
||||
<tr>
|
||||
<td><time><%= time.getutc %></time></td>
|
||||
<td><%= relative_time(time) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
|
||||
<br />
|
48
lib/sidetiq/views/sidetiq_history.erb
Normal file
48
lib/sidetiq/views/sidetiq_history.erb
Normal file
|
@ -0,0 +1,48 @@
|
|||
<%= File.read(File.join(File.dirname(__FILE__), 'views', 'assets', 'styles.css')) %>
|
||||
|
||||
<header class="row">
|
||||
<div class="span5">
|
||||
<h3>Recurring Job: <%= @worker.name %></h3>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container-fluid sidetiq-container">
|
||||
<div class="row-fluid">
|
||||
<%= erb File.read(File.join(File.dirname(__FILE__), 'views', '_worker_nav.erb')) %>
|
||||
|
||||
<div class="span9">
|
||||
<table class="table table-striped table-bordered table-hover table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th style="width: 10%">Status</th>
|
||||
<th style="width: 20%">Timestamp</th>
|
||||
<th>Details</th>
|
||||
</thead>
|
||||
|
||||
<% @history.each do |entry| %>
|
||||
<% entry = JSON.parse(entry, symbolize_names: true) %>
|
||||
<tr class="<%= 'error' if entry[:status] == 'failure' %>">
|
||||
<td><%= entry[:status].capitalize %></td>
|
||||
<td><%= Time.parse(entry[:timestamp]).strftime("%m/%d/%Y %I:%M:%S%p") %></td>
|
||||
<td>
|
||||
<% if entry[:status] == 'failure' %>
|
||||
<a class="backtrace" href="#" onclick="$(this).next().toggle(); return false">
|
||||
<%= entry[:exception] %>: <%= entry[:error] %>
|
||||
</a>
|
||||
<div style="display: none; overflow: auto; width: 100%; background: white; ">
|
||||
<pre style="display: inline-block; font-size: 0.8em; border: none; white-space: nowrap; margin: 0">
|
||||
<%= entry[:backtrace].join("<br />") %>
|
||||
</pre>
|
||||
</div>
|
||||
<% end %>
|
||||
<p>
|
||||
<span>Node: <%= entry[:node] %></span>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
0
lib/sidetiq/views/sidetiq_history.rb
Normal file
0
lib/sidetiq/views/sidetiq_history.rb
Normal file
59
lib/sidetiq/views/sidetiq_schedule.erb
Normal file
59
lib/sidetiq/views/sidetiq_schedule.erb
Normal file
|
@ -0,0 +1,59 @@
|
|||
<%= File.read(File.join(File.dirname(__FILE__), 'views', 'assets', 'styles.css')) %>
|
||||
|
||||
<header class="row">
|
||||
<div class="span5">
|
||||
<h3>Recurring Job: <%= @worker.name %></h3>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="container-fluid sidetiq-container">
|
||||
<div class="row-fluid">
|
||||
<%= erb File.read(File.join(File.dirname(__FILE__), 'views', '_worker_nav.erb')) %>
|
||||
|
||||
<div class="span9">
|
||||
<% if (recurrences = @schedule.recurrence_rules).length > 0 %>
|
||||
<table class="table table-striped table-bordered table-hover table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th>Recurrences</th>
|
||||
</thead>
|
||||
<% recurrences.each do |rule| %>
|
||||
<tr>
|
||||
<td><%= rule.to_s %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<br />
|
||||
|
||||
<% if (exceptions = @schedule.exception_rules).length > 0 %>
|
||||
<table class="table table-striped table-bordered table-hover table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th>Exceptions</th>
|
||||
</thead>
|
||||
<% exceptions.each do |rule| %>
|
||||
<tr>
|
||||
<td><%= rule.to_s %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<% end %>
|
||||
|
||||
<br />
|
||||
|
||||
<table class="table table-striped table-bordered table-hover table-white" style="width: 100%; margin: 0; table-layout:fixed;">
|
||||
<thead>
|
||||
<th style="width: 25%">Next 10 runs</th>
|
||||
<th style="width: 75%" />
|
||||
<% @schedule.next_occurrences(10, @time).each do |time| %>
|
||||
<tr>
|
||||
<td><time><%= time.getutc %></time></td>
|
||||
<td><%= relative_time(time) %></td>
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<br />
|
|
@ -11,7 +11,7 @@ module Sidetiq
|
|||
erb File.read(File.join(VIEWS, 'sidetiq.erb'))
|
||||
end
|
||||
|
||||
app.get "/sidetiq/:name" do
|
||||
app.get "/sidetiq/:name/schedule" do
|
||||
halt 404 unless (name = params[:name])
|
||||
|
||||
@time = Sidetiq.clock.gettime
|
||||
|
@ -20,7 +20,23 @@ module Sidetiq
|
|||
worker.name == name
|
||||
end.flatten
|
||||
|
||||
erb File.read(File.join(VIEWS, 'sidetiq_details.erb'))
|
||||
erb File.read(File.join(VIEWS, 'sidetiq_schedule.erb'))
|
||||
end
|
||||
|
||||
app.get "/sidetiq/:name/history" do
|
||||
halt 404 unless (name = params[:name])
|
||||
|
||||
@time = Sidetiq.clock.gettime
|
||||
|
||||
@worker, @schedule = Sidetiq.schedules.select do |worker, _|
|
||||
worker.name == name
|
||||
end.flatten
|
||||
|
||||
@history = Sidekiq.redis do |redis|
|
||||
redis.lrange("sidetiq:#{@worker.name}:history", 0, -1)
|
||||
end
|
||||
|
||||
erb File.read(File.join(VIEWS, 'sidetiq_history.erb'))
|
||||
end
|
||||
|
||||
app.post "/sidetiq/:name/trigger" do
|
||||
|
|
|
@ -21,8 +21,8 @@ class TestHistory < Sidetiq::TestCase
|
|||
assert_empty actual[:backtrace]
|
||||
assert_empty actual[:exception]
|
||||
|
||||
refute_empty actual[:processor]
|
||||
refute_empty actual[:processed]
|
||||
refute_empty actual[:node]
|
||||
refute_empty actual[:timestamp]
|
||||
end
|
||||
|
||||
def test_failure
|
||||
|
@ -45,8 +45,8 @@ class TestHistory < Sidetiq::TestCase
|
|||
assert_equal "StandardError", actual[:exception]
|
||||
refute_empty actual[:backtrace]
|
||||
|
||||
refute_empty actual[:processor]
|
||||
refute_empty actual[:processed]
|
||||
refute_empty actual[:node]
|
||||
refute_empty actual[:timestamp]
|
||||
end
|
||||
|
||||
def middlewared
|
||||
|
|
|
@ -33,8 +33,13 @@ class TestWeb < Sidetiq::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_details_page
|
||||
get "/sidetiq/ScheduledWorker"
|
||||
def test_history_page
|
||||
get "/sidetiq/ScheduledWorker/history"
|
||||
assert_equal 200, last_response.status
|
||||
end
|
||||
|
||||
def test_schedule_page
|
||||
get "/sidetiq/ScheduledWorker/schedule"
|
||||
assert_equal 200, last_response.status
|
||||
schedule = clock.schedules[ScheduledWorker]
|
||||
|
||||
|
|
Loading…
Reference in a new issue