1
0
Fork 0
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:
Tobias Svensson 2013-09-16 16:21:54 +01:00
parent 1186088a4f
commit 5b20e39ca0
12 changed files with 198 additions and 61 deletions

View file

@ -24,7 +24,7 @@ module Sidetiq
end end
configure do |config| configure do |config|
config.worker_history = 100 config.worker_history = 50
config.resolution = 1 config.resolution = 1
config.lock_expire = 1000 config.lock_expire = 1000
config.utc = false config.utc = false

View file

@ -32,8 +32,8 @@ module Sidetiq
error: "", error: "",
exception: "", exception: "",
backtrace: "", backtrace: "",
processor: "#{Socket.gethostname}:#{Process.pid}-#{Thread.current.object_id}", node: "#{Socket.gethostname}:#{Process.pid}-#{Thread.current.object_id}",
processed: Time.now.iso8601 timestamp: Time.now.iso8601
} }
end end

View 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>

View 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>

View file

@ -15,7 +15,7 @@
<% @schedules.each do |worker, schedule| %> <% @schedules.each do |worker, schedule| %>
<tr> <tr>
<td> <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><%= worker.get_sidekiq_options["queue"] %></td>
<td> <td>
<%= relative_time(schedule.next_occurrence(@time)) %> <%= relative_time(schedule.next_occurrence(@time)) %>

View file

@ -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 />

View 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 />

View file

View 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 />

View file

@ -11,7 +11,7 @@ module Sidetiq
erb File.read(File.join(VIEWS, 'sidetiq.erb')) erb File.read(File.join(VIEWS, 'sidetiq.erb'))
end end
app.get "/sidetiq/:name" do app.get "/sidetiq/:name/schedule" do
halt 404 unless (name = params[:name]) halt 404 unless (name = params[:name])
@time = Sidetiq.clock.gettime @time = Sidetiq.clock.gettime
@ -20,7 +20,23 @@ module Sidetiq
worker.name == name worker.name == name
end.flatten 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 end
app.post "/sidetiq/:name/trigger" do app.post "/sidetiq/:name/trigger" do

View file

@ -21,8 +21,8 @@ class TestHistory < Sidetiq::TestCase
assert_empty actual[:backtrace] assert_empty actual[:backtrace]
assert_empty actual[:exception] assert_empty actual[:exception]
refute_empty actual[:processor] refute_empty actual[:node]
refute_empty actual[:processed] refute_empty actual[:timestamp]
end end
def test_failure def test_failure
@ -45,8 +45,8 @@ class TestHistory < Sidetiq::TestCase
assert_equal "StandardError", actual[:exception] assert_equal "StandardError", actual[:exception]
refute_empty actual[:backtrace] refute_empty actual[:backtrace]
refute_empty actual[:processor] refute_empty actual[:node]
refute_empty actual[:processed] refute_empty actual[:timestamp]
end end
def middlewared def middlewared

View file

@ -33,8 +33,13 @@ class TestWeb < Sidetiq::TestCase
end end
end end
def test_details_page def test_history_page
get "/sidetiq/ScheduledWorker" 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 assert_equal 200, last_response.status
schedule = clock.schedules[ScheduledWorker] schedule = clock.schedules[ScheduledWorker]