r3_exception_logger 0.1.10 → 0.1.11
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +75 -0
- data/LICENSE +20 -0
- data/README.old +107 -0
- data/README.rdoc +154 -0
- data/Rakefile +66 -0
- data/VERSION.yml +5 -0
- data/app/controllers/logged_exceptions_controller.rb +86 -0
- data/app/helpers/logged_exceptions_helper.rb +40 -0
- data/app/models/logged_exception.rb +79 -0
- data/app/views/layouts/logged_exceptions.html.erb +19 -0
- data/app/views/logged_exceptions/_exceptions.html.erb +31 -0
- data/app/views/logged_exceptions/_feed.html.erb +3 -0
- data/app/views/logged_exceptions/_show.html.erb +23 -0
- data/app/views/logged_exceptions/destroy.js.erb +2 -0
- data/app/views/logged_exceptions/destroy_all.js.erb +2 -0
- data/app/views/logged_exceptions/feed.rss.builder +20 -0
- data/app/views/logged_exceptions/index.html.erb +46 -0
- data/app/views/logged_exceptions/index.js.erb +2 -0
- data/app/views/logged_exceptions/query.js.erb +2 -0
- data/app/views/logged_exceptions/show.html.erb +8 -0
- data/app/views/logged_exceptions/show.js.erb +2 -0
- data/config/initializers/date_formats.rb +5 -0
- data/config/locales/en.yml +16 -0
- data/config/routes.rb +11 -0
- data/exception_logger.gemspec +23 -0
- data/public/javascripts/exception_logger.js +69 -0
- data/public/stylesheets/exception_logger.css +325 -0
- data/r3_exception_logger-0.1.10.gem +0 -0
- data/test/controllers/logged_exceptions_controller_test.rb +196 -0
- data/test/models/logged_exception_test.rb +39 -0
- data/test/rails_root/Gemfile +52 -0
- data/test/rails_root/Gemfile.lock +146 -0
- data/test/rails_root/app/controllers/application_controller.rb +5 -0
- data/test/rails_root/test/factories/exception_logger.rb +142 -0
- data/test/test_helper.rb +10 -0
- metadata +36 -1
@@ -0,0 +1,40 @@
|
|
1
|
+
module LoggedExceptionsHelper
|
2
|
+
def pretty_exception_date(exception)
|
3
|
+
if Date.today == exception.created_at.to_date
|
4
|
+
if exception.created_at > Time.now - 4.hours
|
5
|
+
"#{time_ago_in_words(exception.created_at).gsub(/about /,"~ ")} ago"
|
6
|
+
else
|
7
|
+
"Today, #{exception.created_at.strftime(Time::DATE_FORMATS[:exc_time])}"
|
8
|
+
end
|
9
|
+
else
|
10
|
+
exception.created_at.strftime(Time::DATE_FORMATS[:exc_date])
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def filtered?
|
15
|
+
[:query, :date_ranges_filter, :exception_names_filter, :controller_actions_filter].any? { |p| params[p] }
|
16
|
+
end
|
17
|
+
|
18
|
+
def listify(text)
|
19
|
+
list_items = text.scan(/^\s*\* (.+)/).map {|match| content_tag(:li, match.first) }
|
20
|
+
content_tag(:ul, list_items)
|
21
|
+
end
|
22
|
+
|
23
|
+
def page_title(text)
|
24
|
+
title = ""
|
25
|
+
unless controller.application_name.blank?
|
26
|
+
title << "#{controller.application_name} :: "
|
27
|
+
end
|
28
|
+
title << text.to_s
|
29
|
+
content_for(:title, title.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Rescue textilize call if RedCloth is not available.
|
33
|
+
def pretty_format(text)
|
34
|
+
begin
|
35
|
+
textilize(text).html_safe
|
36
|
+
rescue
|
37
|
+
simple_format(text).html_safe
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
class LoggedException < ActiveRecord::Base
|
2
|
+
class << self
|
3
|
+
def create_from_exception(controller, exception, data)
|
4
|
+
message = exception.message.inspect
|
5
|
+
message << "\n* Extra Data\n\n#{data}" unless data.blank?
|
6
|
+
e = create! \
|
7
|
+
:exception_class => exception.class.name,
|
8
|
+
:controller_name => controller.controller_path,
|
9
|
+
:action_name => controller.action_name,
|
10
|
+
:message => message,
|
11
|
+
:backtrace => exception.backtrace,
|
12
|
+
:request => controller.request
|
13
|
+
end
|
14
|
+
|
15
|
+
def host_name
|
16
|
+
`hostname -s`.chomp
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
scope :by_exception_class, lambda {|exception_class| where(:exception_class => exception_class)}
|
21
|
+
scope :by_controller_and_action, lambda {|controller_name, action_name| where(:controller_name => controller_name, :action_name => action_name)}
|
22
|
+
scope :by_controller, lambda {|controller_name| where(:controller_name => controller_name)}
|
23
|
+
scope :by_action, lambda {|action_name| where(:action_name => action_name)}
|
24
|
+
scope :message_like, lambda {|query| where(:message.matches => "%#{query}%")}
|
25
|
+
scope :days_old, lambda {|day_number| where("created_at >= ?", day_number.to_f.days.ago.utc)}
|
26
|
+
scope :sorted, order("created_at desc")
|
27
|
+
|
28
|
+
def name
|
29
|
+
"#{self.exception_class} in #{self.controller_action}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def backtrace=(trace)
|
33
|
+
trace = sanitize_backtrace(trace) * "\n" unless trace.is_a?(String)
|
34
|
+
write_attribute :backtrace, trace
|
35
|
+
end
|
36
|
+
|
37
|
+
def request=(request)
|
38
|
+
if request.is_a?(String)
|
39
|
+
write_attribute :request, request
|
40
|
+
else
|
41
|
+
max = request.env.keys.max { |a,b| a.length <=> b.length }
|
42
|
+
env = request.env.keys.sort.inject [] do |env, key|
|
43
|
+
env << '* ' + ("%-*s: %s" % [max.length, key, request.env[key].to_s.strip])
|
44
|
+
end
|
45
|
+
write_attribute(:environment, (env << "* Process: #{$$}" << "* Server : #{self.class.host_name}") * "\n")
|
46
|
+
|
47
|
+
write_attribute(:request, [
|
48
|
+
"* URL:#{" #{request.method.to_s.upcase}" unless request.get?} #{request.protocol}#{request.env["HTTP_HOST"]}#{request.fullpath}",
|
49
|
+
"* Format: #{request.format.to_s}",
|
50
|
+
"* Parameters: #{request.parameters.inspect}",
|
51
|
+
"* Rails Root: #{rails_root}"
|
52
|
+
] * "\n")
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def controller_action
|
57
|
+
@controller_action ||= "#{controller_name.camelcase}/#{action_name}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.class_names
|
61
|
+
select("DISTINCT exception_class").order(:exception_class).collect(&:exception_class)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.controller_actions
|
65
|
+
select("DISTINCT controller_name, action_name").order(:controller_name,:action_name).collect(&:controller_action)
|
66
|
+
end
|
67
|
+
|
68
|
+
private
|
69
|
+
@@rails_root = Pathname.new(Rails.root).cleanpath.to_s
|
70
|
+
@@backtrace_regex = /^#{Regexp.escape(@@rails_root)}/
|
71
|
+
|
72
|
+
def sanitize_backtrace(trace)
|
73
|
+
trace.collect { |line| Pathname.new(line.gsub(@@backtrace_regex, "[RAILS_ROOT]")).cleanpath.to_s }
|
74
|
+
end
|
75
|
+
|
76
|
+
def rails_root
|
77
|
+
@@rails_root
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title><%= content_for?(:title) ? yield(:title) : "Exception Logger" %></title>
|
5
|
+
<meta charset="UTF-8" />
|
6
|
+
<%= javascript_include_tag 'https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js' %>
|
7
|
+
<%= javascript_include_tag 'exception_logger' %>
|
8
|
+
<%= stylesheet_link_tag 'exception_logger' %>
|
9
|
+
<%= csrf_meta_tag %>
|
10
|
+
|
11
|
+
<%= auto_discovery_link_tag(:rss, {:action => "feed"}, {:title => "RSS Feed"}) %>
|
12
|
+
</head>
|
13
|
+
<body>
|
14
|
+
<div id="container">
|
15
|
+
<%= yield %>
|
16
|
+
</div>
|
17
|
+
<br style="clear:both" />
|
18
|
+
</body>
|
19
|
+
</html>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<div id="exceptions">
|
2
|
+
<div class="pages">
|
3
|
+
<%= link_to 'Delete Visible', { :action => 'destroy_all' }, :class => 'delete_visible_link' %>
|
4
|
+
<strong><%= paginate @exceptions, :style => 'display:inline' %></strong>
|
5
|
+
</div>
|
6
|
+
<h1>Exceptions <%= raw "<span>(filtered)</span>" if filtered? %> </h1>
|
7
|
+
<table>
|
8
|
+
<thead>
|
9
|
+
<tr>
|
10
|
+
<th>Exception</th>
|
11
|
+
<th>Date</th>
|
12
|
+
<th></th>
|
13
|
+
</tr>
|
14
|
+
</thead>
|
15
|
+
<tbody>
|
16
|
+
<% @exceptions.each do |exception| %>
|
17
|
+
<tr id="<%= dom_id(exception) %>" class="<%= cycle("eor", "") %> exception">
|
18
|
+
<td>
|
19
|
+
<div class="expclass"><%= link_to exception.name, {:action => "show", :id => exception}, :class => 'show_link' %></div>
|
20
|
+
<span class="message"><%= h exception.message %></span>
|
21
|
+
</td>
|
22
|
+
<td class="time"><%= pretty_exception_date(exception) %></td>
|
23
|
+
<td><%= link_to 'Delete', { :action => 'destroy', :id => exception }, :method => :delete, :class => "util delete_link" %></td>
|
24
|
+
</tr>
|
25
|
+
<% end %>
|
26
|
+
</tbody>
|
27
|
+
</table>
|
28
|
+
<div class="pages pages-bottom">
|
29
|
+
<strong><%= paginate @exceptions, :style => 'display:inline' %></strong>
|
30
|
+
</div>
|
31
|
+
</div> <!-- #exceptions -->
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<div class="tools">
|
2
|
+
<%= link_to 'Delete', { :action => 'destroy', :id => @exception }, :class => "util delete_link" %>
|
3
|
+
<span class="pipe">|</span>
|
4
|
+
<%= link_to "Close", "#", :class => "util close_link" %>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<div class="date">
|
8
|
+
<%= @exception.created_at.strftime(Time::DATE_FORMATS[:exc_full]) %>
|
9
|
+
</div>
|
10
|
+
<h1><%= @exception.name %></h1>
|
11
|
+
|
12
|
+
<h2>Request</h2>
|
13
|
+
<%= pretty_format(@exception.request) %>
|
14
|
+
|
15
|
+
<h2>Backtrace</h2>
|
16
|
+
<%= simple_format @exception.message %>
|
17
|
+
|
18
|
+
<div id="backtrace">
|
19
|
+
<%= raw @exception.backtrace.gsub(/\n/,"<br />") %>
|
20
|
+
</div>
|
21
|
+
|
22
|
+
<h2>Environment</h2>
|
23
|
+
<%= pretty_format(@exception.environment) %>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
xml.instruct! :xml, :version=>"1.0", :encoding=>"UTF-8"
|
2
|
+
|
3
|
+
xml.rss "version" => "2.0" do
|
4
|
+
xml.channel do
|
5
|
+
xml.title "#{LoggedExceptionsController.application_name}"
|
6
|
+
xml.link url_for(:only_path => false, :skip_relative_url_root => false)
|
7
|
+
xml.language "en-us"
|
8
|
+
xml.ttl "60"
|
9
|
+
|
10
|
+
@exceptions.each do |exc|
|
11
|
+
xml.item do
|
12
|
+
xml.title "#{exc.name} @ #{exc.created_at.rfc822}"
|
13
|
+
xml.description exc.message
|
14
|
+
xml.pubDate exc.created_at.rfc822
|
15
|
+
xml.guid [request.host_with_port, 'exceptions', exc.id.to_s].join(":"), "isPermaLink" => "false"
|
16
|
+
xml.link url_for(:action => 'index', :anchor => "e#{exc.id}", :only_path => false, :skip_relative_url_root => false)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
<% page_title t(".title") %>
|
2
|
+
<div id="right">
|
3
|
+
<h3><%=t(".filters")%></h3>
|
4
|
+
<ul id="all_exceptions" class="filters">
|
5
|
+
<li><%= link_to t(".latest_exceptions"), :action => 'index', :id => nil %></li>
|
6
|
+
</ul>
|
7
|
+
<h4><%=t(".exception")%></h4>
|
8
|
+
<ul id="exception_names" class="filters">
|
9
|
+
<% @exception_names.each do |name| %>
|
10
|
+
<li><%= link_to name, {:action => 'query', :exception_names_filter => "#{name}"}, :class => 'filter_link' %></li>
|
11
|
+
<% end %>
|
12
|
+
</ul>
|
13
|
+
<h4><%=t(".controller_action")%></h4>
|
14
|
+
<ul id="controller_actions" class="filters">
|
15
|
+
<% @controller_actions.each do |action| %>
|
16
|
+
<li><%= link_to action, {:action => 'query', :controller_actions_filter => "#{action}"}, :class => 'filter_link' %></li>
|
17
|
+
<% end %>
|
18
|
+
</ul>
|
19
|
+
<h4><%=t(".dates")%></h4>
|
20
|
+
<ul id="date_ranges" class="filters">
|
21
|
+
<li><%= link_to t(".today"), {:action => 'query', :date_ranges_filter => "1"}, :title => "1", :class => 'filter_link' %></li>
|
22
|
+
<li><%= link_to t(".last_few_days"), {:action => 'query', :date_ranges_filter => "3"}, :title => "3", :class => 'filter_link' %></li>
|
23
|
+
<li><%= link_to t(".last_7_days"), {:action => 'query', :date_ranges_filter => "7"}, :title => "7", :class => 'filter_link' %></li>
|
24
|
+
<li><%= link_to t(".last_30_days"), {:action => 'query', :date_ranges_filter => "30"}, :title => "30", :class => 'filter_link' %></li>
|
25
|
+
</ul>
|
26
|
+
<div id="search">
|
27
|
+
<%= form_tag "logged_exceptions/query", :id => 'query-form' %>
|
28
|
+
<div>
|
29
|
+
<%= text_field_tag :query, "", :size => 17 %>
|
30
|
+
<%= submit_tag :Find %>
|
31
|
+
<%= hidden_field_tag :exception_names_filter %>
|
32
|
+
<%= hidden_field_tag :date_ranges_filter %>
|
33
|
+
<%= hidden_field_tag :controller_actions_filter %>
|
34
|
+
<%= hidden_field_tag :page, (params[:page] || 1) %>
|
35
|
+
</div>
|
36
|
+
</form>
|
37
|
+
</div>
|
38
|
+
<%= render :partial => 'feed' %>
|
39
|
+
</div> <!-- right -->
|
40
|
+
<div id="left">
|
41
|
+
<div class="page" id="showpage" style="display:none;"></div>
|
42
|
+
<div class="page">
|
43
|
+
<%= render :partial => "exceptions" %>
|
44
|
+
</div>
|
45
|
+
</div>
|
46
|
+
<div id="activity" style="display:none;">Busy...</div>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
en:
|
2
|
+
logged_exceptions:
|
3
|
+
index:
|
4
|
+
title: Logged Exceptions
|
5
|
+
filters: Filters
|
6
|
+
latest_exceptions: Latest Exceptions
|
7
|
+
exception: Exception
|
8
|
+
controller_action: Controller / Action
|
9
|
+
dates: Dates
|
10
|
+
today: Today
|
11
|
+
last_few_days: Last few days
|
12
|
+
last_7_days: Last 7 days
|
13
|
+
last_30_days: Last 30 days
|
14
|
+
show:
|
15
|
+
title: Logged Exception
|
16
|
+
|
data/config/routes.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib/', __FILE__)
|
3
|
+
$:.unshift lib unless $:.include?(lib)
|
4
|
+
|
5
|
+
require 'bundler/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "r3_exception_logger"
|
9
|
+
s.version = "0.1.11"
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.authors = ["Chris Wise"]
|
12
|
+
s.email = ["cwise@murmurinformatics.com"]
|
13
|
+
s.homepage = "http://github.com/cwise/exception_logger"
|
14
|
+
s.summary = "Fork of exception_logger gem"
|
15
|
+
s.description = "Fork of exception_logger gem"
|
16
|
+
|
17
|
+
s.required_rubygems_version = ">= 1.3.6"
|
18
|
+
|
19
|
+
s.files = Dir.glob("**/*") + Dir.glob("{config}/**/*")
|
20
|
+
# s.files = `git ls-files -- {lib/*,vendor/*,*.gemspec}`.split("\n")
|
21
|
+
# s.files = `git ls-files -- {lib/*,app/*,config/*,public/*,vendor/*,*.gemspec}`.split("\n")
|
22
|
+
s.require_path = 'lib'
|
23
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
$(function () {
|
2
|
+
function CSRFProtection(xhr) {
|
3
|
+
var token = $('meta[name="csrf-token"]').attr('content');
|
4
|
+
if (token) xhr.setRequestHeader('X-CSRF-Token', token);
|
5
|
+
};
|
6
|
+
|
7
|
+
function ajax_headers() {
|
8
|
+
if ('ajaxPrefilter' in $) $.ajaxPrefilter(function(options, originalOptions, xhr){ CSRFProtection(xhr) });
|
9
|
+
else $(document).ajaxSend(function(e, xhr){ CSRFProtection(xhr) });
|
10
|
+
};
|
11
|
+
|
12
|
+
ajax_headers();
|
13
|
+
|
14
|
+
$('.show_link').live('click', function(event) {
|
15
|
+
$.get($(this).attr("href"));
|
16
|
+
return false;
|
17
|
+
});
|
18
|
+
|
19
|
+
$('.close_link').live('click', function(event) {
|
20
|
+
$("#showpage").hide();
|
21
|
+
return false;
|
22
|
+
});
|
23
|
+
|
24
|
+
$('.delete_link').live('click', function(event) {
|
25
|
+
$.ajax({
|
26
|
+
url: $(this).attr("href"),
|
27
|
+
type: 'DELETE'
|
28
|
+
});
|
29
|
+
return false;
|
30
|
+
});
|
31
|
+
|
32
|
+
$('.delete_visible_link').live('click', function(event) {
|
33
|
+
var arr=$('tr.exception').map(function() { var id = $(this).attr("id"); return parseInt(id.replace(/^\w+_/, '')); }).get();
|
34
|
+
$.ajax({
|
35
|
+
url: $(this).attr("href"),
|
36
|
+
type: 'POST',
|
37
|
+
data: $.param({ids: arr}),
|
38
|
+
dataType: 'script'
|
39
|
+
});
|
40
|
+
return false;
|
41
|
+
});
|
42
|
+
|
43
|
+
$('.filter_link').live('click', function(event) {
|
44
|
+
$('.filter_link').removeClass('selected');
|
45
|
+
$(this).addClass('selected');
|
46
|
+
$.ajax({
|
47
|
+
url: $(this).attr("href"),
|
48
|
+
type: 'POST',
|
49
|
+
dataType: 'script'
|
50
|
+
});
|
51
|
+
return false;
|
52
|
+
});
|
53
|
+
|
54
|
+
$('#query-form :submit').live('click', function(event) {
|
55
|
+
$.ajax({
|
56
|
+
url: $("#query-form").attr("action"),
|
57
|
+
type: 'POST',
|
58
|
+
data: $("#query-form").serialize(),
|
59
|
+
dataType: 'script'
|
60
|
+
});
|
61
|
+
return false;
|
62
|
+
});
|
63
|
+
|
64
|
+
$(".pagination a").live("click", function() {
|
65
|
+
$.getScript(this.href);
|
66
|
+
return false;
|
67
|
+
});
|
68
|
+
});
|
69
|
+
|
@@ -0,0 +1,325 @@
|
|
1
|
+
body
|
2
|
+
{
|
3
|
+
margin:0;
|
4
|
+
padding:0;
|
5
|
+
background:#000;
|
6
|
+
font-family:'Lucida Grande', Arial, Helvetica, sans-serif;
|
7
|
+
font-size:1.0em;
|
8
|
+
color:white;
|
9
|
+
}
|
10
|
+
|
11
|
+
#container
|
12
|
+
{
|
13
|
+
xwidth:95%;
|
14
|
+
margin:0 auto;
|
15
|
+
min-width:800px;
|
16
|
+
}
|
17
|
+
|
18
|
+
#left
|
19
|
+
{
|
20
|
+
xfloat:left;
|
21
|
+
xwidth:76%;
|
22
|
+
margin-right:235px;
|
23
|
+
|
24
|
+
}
|
25
|
+
|
26
|
+
#left .page
|
27
|
+
{
|
28
|
+
font-size:0.9em;
|
29
|
+
background:white;
|
30
|
+
border:2px solid #999;
|
31
|
+
border-width:0 2px 2px 0;
|
32
|
+
padding:25px;
|
33
|
+
xmargin-bottom:1em;
|
34
|
+
color:black;
|
35
|
+
}
|
36
|
+
|
37
|
+
#right
|
38
|
+
{
|
39
|
+
margin-top:1em;
|
40
|
+
float:right;
|
41
|
+
xwidth:22%;
|
42
|
+
font-size:0.9em;
|
43
|
+
width:200px;
|
44
|
+
margin-right:1.25em;
|
45
|
+
}
|
46
|
+
|
47
|
+
#right hr
|
48
|
+
{
|
49
|
+
border:0;
|
50
|
+
border-top:1px solid #222;
|
51
|
+
}
|
52
|
+
|
53
|
+
#search
|
54
|
+
{
|
55
|
+
margin-top:2em;
|
56
|
+
background:#111;
|
57
|
+
padding:10px 5px;
|
58
|
+
border:1px solid #222;
|
59
|
+
border-width:1px 0;
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
ul.filters
|
64
|
+
{
|
65
|
+
list-style-type:none;
|
66
|
+
padding:0;
|
67
|
+
margin:0;
|
68
|
+
font-size:0.9em;
|
69
|
+
}
|
70
|
+
ul.filters li { margin-bottom:0.2em;}
|
71
|
+
|
72
|
+
|
73
|
+
ul.filters a,
|
74
|
+
ul.filters a:visited {
|
75
|
+
display:block;
|
76
|
+
padding:1px 7px;
|
77
|
+
color:#fff;
|
78
|
+
xbackground-color:#fff;
|
79
|
+
text-decoration:none;
|
80
|
+
}
|
81
|
+
|
82
|
+
ul.filters a:hover
|
83
|
+
{
|
84
|
+
background:#666;
|
85
|
+
color:white;
|
86
|
+
}
|
87
|
+
|
88
|
+
ul.filters a.selected,
|
89
|
+
ul.filters a.selected:visited,
|
90
|
+
ul.filters a:active {
|
91
|
+
color:gold;
|
92
|
+
background-color:#333;
|
93
|
+
text-decoration:none;
|
94
|
+
font-weight:bold;
|
95
|
+
}
|
96
|
+
|
97
|
+
|
98
|
+
onclick a:hover
|
99
|
+
{
|
100
|
+
color:#fff;
|
101
|
+
text-decoration:none;
|
102
|
+
}
|
103
|
+
|
104
|
+
#exceptions table
|
105
|
+
{
|
106
|
+
width:99%;
|
107
|
+
border-collapse:collapse;
|
108
|
+
}
|
109
|
+
|
110
|
+
td
|
111
|
+
{
|
112
|
+
padding:5px 10px;
|
113
|
+
xborder:1px solid #ddd;
|
114
|
+
}
|
115
|
+
|
116
|
+
#backtrace
|
117
|
+
{
|
118
|
+
overflow:auto;
|
119
|
+
font-family:"Bitstream Vera Sans Mono", "Monaco", "Courier", monospace;;
|
120
|
+
font-size:0.85em;
|
121
|
+
margin-top:0.25em;
|
122
|
+
}
|
123
|
+
|
124
|
+
h2
|
125
|
+
{
|
126
|
+
background-color:#ddd;
|
127
|
+
font-size:0.8em;
|
128
|
+
padding:3px 10px;
|
129
|
+
}
|
130
|
+
|
131
|
+
form {margin:0;}
|
132
|
+
|
133
|
+
h3 {
|
134
|
+
font-size:0.8em;
|
135
|
+
color:#ddd;
|
136
|
+
background:#222;
|
137
|
+
padding:3px 7px;
|
138
|
+
}
|
139
|
+
|
140
|
+
div.date
|
141
|
+
{
|
142
|
+
color:#666;
|
143
|
+
font-size:0.8em;
|
144
|
+
}
|
145
|
+
|
146
|
+
h1
|
147
|
+
{
|
148
|
+
margin-top:0.25em;
|
149
|
+
font-size:1.25em;
|
150
|
+
padding-bottom:5px;
|
151
|
+
border-bottom:2px solid #ddd;
|
152
|
+
}
|
153
|
+
|
154
|
+
h1 span
|
155
|
+
{
|
156
|
+
color:#aaa;
|
157
|
+
font-weight:normal;
|
158
|
+
}
|
159
|
+
|
160
|
+
a
|
161
|
+
{
|
162
|
+
color:#369;
|
163
|
+
text-decoration:none;
|
164
|
+
}
|
165
|
+
a:hover
|
166
|
+
{
|
167
|
+
color:blue;
|
168
|
+
text-decoration:underline;
|
169
|
+
}
|
170
|
+
|
171
|
+
th
|
172
|
+
{
|
173
|
+
text-align:left;
|
174
|
+
xbackground:#333;
|
175
|
+
xcolor:gold;
|
176
|
+
font-size:0.75em;
|
177
|
+
padding:2px 10px;
|
178
|
+
}
|
179
|
+
|
180
|
+
tr { xcursor:pointer; }
|
181
|
+
|
182
|
+
tr.eor td
|
183
|
+
{
|
184
|
+
background:#e7e7e7;
|
185
|
+
|
186
|
+
}
|
187
|
+
|
188
|
+
/*
|
189
|
+
tr:hover td,
|
190
|
+
tr.eor:hover td
|
191
|
+
{
|
192
|
+
background:#333;
|
193
|
+
color:white;
|
194
|
+
}
|
195
|
+
tr:hover td a,
|
196
|
+
tr.eor:hover td a { color:gold; }
|
197
|
+
*/
|
198
|
+
|
199
|
+
.message
|
200
|
+
{
|
201
|
+
font-size:0.8em;
|
202
|
+
}
|
203
|
+
|
204
|
+
a.util
|
205
|
+
{
|
206
|
+
color:#c00;
|
207
|
+
font-size:0.7em;
|
208
|
+
}
|
209
|
+
|
210
|
+
.pipe
|
211
|
+
{
|
212
|
+
font-size:0.75em;
|
213
|
+
color:#999;
|
214
|
+
}
|
215
|
+
|
216
|
+
.tools { float:right; }
|
217
|
+
|
218
|
+
.time
|
219
|
+
{
|
220
|
+
color:#666;
|
221
|
+
font-size:0.75em;
|
222
|
+
xvertical-align:top;
|
223
|
+
}
|
224
|
+
|
225
|
+
|
226
|
+
.expclass
|
227
|
+
{
|
228
|
+
xcolor:#999;
|
229
|
+
}
|
230
|
+
.expclass a
|
231
|
+
{
|
232
|
+
font-size:0.9em;
|
233
|
+
}
|
234
|
+
|
235
|
+
tr.deleted td {
|
236
|
+
color:#aaa;
|
237
|
+
text-decoration: line-through;
|
238
|
+
}
|
239
|
+
tr.deleted td a { color:#aaa; }
|
240
|
+
|
241
|
+
.pages { float:right; margin-right:1em; }
|
242
|
+
.pages a { text-decoration:underline; }
|
243
|
+
.pages-bottom { border-top:2px solid #ddd; text-align:right; float:none;
|
244
|
+
padding-top:0.4em;
|
245
|
+
margin-top:0.4em;
|
246
|
+
padding-right:1em;
|
247
|
+
margin-right:0;
|
248
|
+
}
|
249
|
+
|
250
|
+
/* right */
|
251
|
+
|
252
|
+
#right h4
|
253
|
+
{
|
254
|
+
font-size:0.75em;
|
255
|
+
xbackground:#171717;
|
256
|
+
xbackground:#333;
|
257
|
+
color:#999;
|
258
|
+
padding:3px 5px;
|
259
|
+
margin-bottom:0.5em;
|
260
|
+
font-weight:normal;
|
261
|
+
}
|
262
|
+
|
263
|
+
/* tabs */
|
264
|
+
|
265
|
+
ul.tabs
|
266
|
+
{
|
267
|
+
list-style-type:none;
|
268
|
+
padding:0;
|
269
|
+
margin:1em 0;
|
270
|
+
float:left;
|
271
|
+
}
|
272
|
+
ul.tabs li { float:left; display:inline; }
|
273
|
+
ul.tabs li a
|
274
|
+
{
|
275
|
+
font-size:0.8em;
|
276
|
+
padding:3px 7px;
|
277
|
+
margin-right:1em;
|
278
|
+
text-decoration:none;
|
279
|
+
color:black;
|
280
|
+
}
|
281
|
+
|
282
|
+
ul.tabs li a:hover
|
283
|
+
{
|
284
|
+
background:#666;
|
285
|
+
color:white;
|
286
|
+
}
|
287
|
+
ul.tabs li.selected a
|
288
|
+
{
|
289
|
+
background:black;
|
290
|
+
color:white;
|
291
|
+
}
|
292
|
+
|
293
|
+
#activity {
|
294
|
+
position:fixed;
|
295
|
+
top:0; right:18px;
|
296
|
+
width:200px;
|
297
|
+
padding:5px 0;
|
298
|
+
text-align:center;
|
299
|
+
background-color:#cf1313;
|
300
|
+
color:#fff;
|
301
|
+
opacity:.8;
|
302
|
+
font-size: 11px;
|
303
|
+
}
|
304
|
+
|
305
|
+
#feed {
|
306
|
+
margin-top: 15px;
|
307
|
+
}
|
308
|
+
|
309
|
+
/* html5 changes */
|
310
|
+
|
311
|
+
#exceptions table {
|
312
|
+
border-collapse: collapse;
|
313
|
+
}
|
314
|
+
|
315
|
+
#exceptions table thead {
|
316
|
+
display: none;
|
317
|
+
}
|
318
|
+
|
319
|
+
#exceptions table tbody tr.exception td.time {
|
320
|
+
white-space: nowrap
|
321
|
+
}
|
322
|
+
|
323
|
+
#container #left #showpage {
|
324
|
+
margin-bottom:1em;
|
325
|
+
}
|