rscratch 0.1.3
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.
- checksums.yaml +15 -0
- data/MIT-LICENSE +20 -0
- data/README.md +99 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/rscratch/Chart.min.js +11 -0
- data/app/assets/javascripts/rscratch/application.js +128 -0
- data/app/assets/javascripts/rscratch/dashboard.js +90 -0
- data/app/assets/javascripts/rscratch/exceptions.js +97 -0
- data/app/assets/javascripts/rscratch/templates/exception_overview.jst.ejs +57 -0
- data/app/assets/javascripts/rscratch/templates/loader.jst.ejs +65 -0
- data/app/assets/stylesheets/rscratch/application.css +13 -0
- data/app/assets/stylesheets/rscratch/style.css +101 -0
- data/app/controllers/rscratch/application_controller.rb +12 -0
- data/app/controllers/rscratch/dashboard_controller.rb +13 -0
- data/app/controllers/rscratch/exceptions_controller.rb +23 -0
- data/app/helpers/rscratch/application_helper.rb +4 -0
- data/app/helpers/rscratch/dashboard_helper.rb +4 -0
- data/app/helpers/rscratch/exceptions_helper.rb +4 -0
- data/app/models/rscratch/exception.rb +68 -0
- data/app/models/rscratch/exception_log.rb +49 -0
- data/app/views/layouts/rscratch/application.html.haml +35 -0
- data/app/views/rscratch/dashboard/index.html.haml +12 -0
- data/app/views/rscratch/exceptions/_exception_smartlist.html.haml +21 -0
- data/app/views/rscratch/exceptions/index.html.haml +59 -0
- data/app/views/rscratch/exceptions/index.js.erb +3 -0
- data/app/views/rscratch/exceptions/show.json.jbuilder +13 -0
- data/app/views/smart_listing/_action_custom.html.erb +10 -0
- data/app/views/smart_listing/_action_delete.html.erb +12 -0
- data/app/views/smart_listing/_action_edit.html.erb +11 -0
- data/app/views/smart_listing/_action_show.html.erb +11 -0
- data/app/views/smart_listing/_item_new.html.erb +30 -0
- data/app/views/smart_listing/_pagination_per_page_link.html.erb +12 -0
- data/app/views/smart_listing/_pagination_per_page_links.html.erb +19 -0
- data/app/views/smart_listing/_sortable.html.erb +21 -0
- data/config/routes.rb +8 -0
- data/db/migrate/20160123064059_create_rscratch_exceptions.rb +15 -0
- data/db/migrate/20160123064828_create_rscratch_exception_logs.rb +17 -0
- data/lib/generators/rscratch/install/install_generator.rb +27 -0
- data/lib/generators/rscratch/install/templates/initializer.rb.erb +7 -0
- data/lib/generators/rscratch/install/templates/migration.rb +40 -0
- data/lib/rscratch.rb +11 -0
- data/lib/rscratch/configuration.rb +7 -0
- data/lib/rscratch/engine.rb +10 -0
- data/lib/rscratch/version.rb +3 -0
- data/lib/tasks/rscratch_tasks.rake +4 -0
- data/test/dummy/README.rdoc +261 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +15 -0
- data/test/dummy/app/assets/stylesheets/application.css +13 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +4 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fixtures/rscratch/exception_logs.yml +23 -0
- data/test/fixtures/rscratch/exceptions.yml +19 -0
- data/test/functional/rscratch/dashboard_controller_test.rb +11 -0
- data/test/functional/rscratch/exceptions_controller_test.rb +11 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/rscratch_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- data/test/unit/helpers/rscratch/dashboard_helper_test.rb +6 -0
- data/test/unit/helpers/rscratch/exceptions_helper_test.rb +6 -0
- data/test/unit/rscratch/exception_log_test.rb +9 -0
- data/test/unit/rscratch/exception_test.rb +9 -0
- metadata +235 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<%
|
|
2
|
+
|
|
3
|
+
var entityMap = {
|
|
4
|
+
"&": "&",
|
|
5
|
+
"<": "<",
|
|
6
|
+
">": ">",
|
|
7
|
+
'"': '"',
|
|
8
|
+
"'": ''',
|
|
9
|
+
"/": '/'
|
|
10
|
+
};
|
|
11
|
+
function escapeHtml(string) {
|
|
12
|
+
return String(string).replace(/[&<>"'\/]/g, function (s) {
|
|
13
|
+
return entityMap[s];
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
var created_at = new Date(response.created_at);
|
|
17
|
+
var created_at = created_at.format("dd-mm-yyyy hh:MM TT","GMT");
|
|
18
|
+
|
|
19
|
+
var updated_at = new Date(response.updated_at);
|
|
20
|
+
var updated_at = updated_at.format("dd-mm-yyyy hh:MM TT","GMT");
|
|
21
|
+
%>
|
|
22
|
+
<div class="row">
|
|
23
|
+
<div class="col s3">First seen at</div>
|
|
24
|
+
<div class="col s9"><%= created_at %></div>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="row">
|
|
27
|
+
<div class="col s3">Last seen at</div>
|
|
28
|
+
<div class="col s9"><%= updated_at %></div>
|
|
29
|
+
</div>
|
|
30
|
+
<div class="row">
|
|
31
|
+
<div class="col s3">Occurrences</div>
|
|
32
|
+
<div class="col s9"><%= response.total_occurance_count %></div>
|
|
33
|
+
</div>
|
|
34
|
+
<div class="row">
|
|
35
|
+
<div class="col s3">Description</div>
|
|
36
|
+
<div class="col s9"> <%= escapeHtml(response.log.description) %></div>
|
|
37
|
+
</div>
|
|
38
|
+
<div class="row">
|
|
39
|
+
<div class="col s3">Environment</div>
|
|
40
|
+
<div class="col s9"><%= response.app_environment %></div>
|
|
41
|
+
</div>
|
|
42
|
+
<div class="row">
|
|
43
|
+
<div class="col s3">Request URL</div>
|
|
44
|
+
<div class="col s9"><%= response.log.request_url %></div>
|
|
45
|
+
</div>
|
|
46
|
+
<div class="row">
|
|
47
|
+
<div class="col s3">Request Method</div>
|
|
48
|
+
<div class="col s9"><%= response.log.request_method %></div>
|
|
49
|
+
</div>
|
|
50
|
+
<div class="row">
|
|
51
|
+
<div class="col s3">Client IP</div>
|
|
52
|
+
<div class="col s9"><%= response.log.client_ip %></div>
|
|
53
|
+
</div>
|
|
54
|
+
<div class="row">
|
|
55
|
+
<div class="col s3">User Agent</div>
|
|
56
|
+
<div class="col s9"><%= response.log.user_agent %></div>
|
|
57
|
+
</div>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
<center>
|
|
2
|
+
<% if (typeof loader_type != 'undefined') {%>
|
|
3
|
+
<% if(loader_type == "progressbar") { %>
|
|
4
|
+
<div class="m-progress">
|
|
5
|
+
<div class="indeterminate"></div>
|
|
6
|
+
</div>
|
|
7
|
+
<% } else { if(loader_type == "blue-spinner") {%>
|
|
8
|
+
<div class="preloader-wrapper active" style="margin:40px">
|
|
9
|
+
<div class="spinner-layer spinner-blue-only">
|
|
10
|
+
<div class="circle-clipper left">
|
|
11
|
+
<div class="circle"></div>
|
|
12
|
+
</div><div class="gap-patch">
|
|
13
|
+
<div class="circle"></div>
|
|
14
|
+
</div><div class="circle-clipper right">
|
|
15
|
+
<div class="circle"></div>
|
|
16
|
+
</div>
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
|
|
20
|
+
<% } %>
|
|
21
|
+
<% } %>
|
|
22
|
+
<% } else { %>
|
|
23
|
+
<div class="preloader-wrapper active" style="margin:40px; margin-top:80px">
|
|
24
|
+
<div class="spinner-layer spinner-blue">
|
|
25
|
+
<div class="circle-clipper left">
|
|
26
|
+
<div class="circle"></div>
|
|
27
|
+
</div><div class="gap-patch">
|
|
28
|
+
<div class="circle"></div>
|
|
29
|
+
</div><div class="circle-clipper right">
|
|
30
|
+
<div class="circle"></div>
|
|
31
|
+
</div>
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
<div class="spinner-layer spinner-red">
|
|
35
|
+
<div class="circle-clipper left">
|
|
36
|
+
<div class="circle"></div>
|
|
37
|
+
</div><div class="gap-patch">
|
|
38
|
+
<div class="circle"></div>
|
|
39
|
+
</div><div class="circle-clipper right">
|
|
40
|
+
<div class="circle"></div>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<div class="spinner-layer spinner-yellow">
|
|
45
|
+
<div class="circle-clipper left">
|
|
46
|
+
<div class="circle"></div>
|
|
47
|
+
</div><div class="gap-patch">
|
|
48
|
+
<div class="circle"></div>
|
|
49
|
+
</div><div class="circle-clipper right">
|
|
50
|
+
<div class="circle"></div>
|
|
51
|
+
</div>
|
|
52
|
+
</div>
|
|
53
|
+
|
|
54
|
+
<div class="spinner-layer spinner-green">
|
|
55
|
+
<div class="circle-clipper left">
|
|
56
|
+
<div class="circle"></div>
|
|
57
|
+
</div><div class="gap-patch">
|
|
58
|
+
<div class="circle"></div>
|
|
59
|
+
</div><div class="circle-clipper right">
|
|
60
|
+
<div class="circle"></div>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
<% } %>
|
|
65
|
+
</center>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
|
3
|
+
* listed below.
|
|
4
|
+
*
|
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
|
6
|
+
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
|
7
|
+
*
|
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
|
9
|
+
* compiled file, but it's generally better to create a new file per style scope.
|
|
10
|
+
*
|
|
11
|
+
*= require_self
|
|
12
|
+
*= require_tree .
|
|
13
|
+
*/
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
h1.logo-wrapper {
|
|
2
|
+
margin: 0px 30px 0px 0px;
|
|
3
|
+
overflow-y:hidden;
|
|
4
|
+
}
|
|
5
|
+
h1.logo-wrapper a {
|
|
6
|
+
display: inline;
|
|
7
|
+
}
|
|
8
|
+
h1.logo-wrapper a:hover{
|
|
9
|
+
background-color: #FFF;
|
|
10
|
+
}
|
|
11
|
+
header .brand-logo {
|
|
12
|
+
margin: 1px 0px;
|
|
13
|
+
padding: 0px 20px;
|
|
14
|
+
}
|
|
15
|
+
header .brand-logo img {
|
|
16
|
+
width: 172px;
|
|
17
|
+
}
|
|
18
|
+
h1 span.logo-text {
|
|
19
|
+
display: none;
|
|
20
|
+
}
|
|
21
|
+
.p0{ padding: 0px !important; }
|
|
22
|
+
.p5{ padding: 5px !important; }
|
|
23
|
+
.p10{ padding: 10px !important; }
|
|
24
|
+
.p20{ padding: 20px; }
|
|
25
|
+
|
|
26
|
+
.margin-t-0{ margin-top:0px !important; }
|
|
27
|
+
.margin-t-5{ margin-top:5px !important; }
|
|
28
|
+
.margin-0{ margin:0px !important; }
|
|
29
|
+
|
|
30
|
+
.font-10{ font-size: 10px; }
|
|
31
|
+
.font-11{ font-size: 11px; }
|
|
32
|
+
.font-12{ font-size: 12px; }
|
|
33
|
+
.font-14{ font-size: 14px; }
|
|
34
|
+
.font-16{ font-size: 16px !important; }
|
|
35
|
+
.font-18{ font-size: 18px !important; }
|
|
36
|
+
.font-20{ font-size: 20px !important; }
|
|
37
|
+
.font-24{ font-size: 24px !important; }
|
|
38
|
+
.font-34{ font-size: 34px !important; }
|
|
39
|
+
|
|
40
|
+
.font-weight-300{ font-weight: 300 !important; }
|
|
41
|
+
|
|
42
|
+
.min-height-70{ min-height: 70px !important; }
|
|
43
|
+
|
|
44
|
+
.fixed-sidebar{
|
|
45
|
+
position: fixed;
|
|
46
|
+
height: calc(100% - 50px);
|
|
47
|
+
overflow-y:auto;
|
|
48
|
+
width:inherit
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
span.badge {
|
|
52
|
+
font-weight: 300;
|
|
53
|
+
font-size: 0.8rem;
|
|
54
|
+
color: #FFF;
|
|
55
|
+
background-color: #26A69A;
|
|
56
|
+
border-radius: 2px;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
span.label {
|
|
60
|
+
font-weight: 300;
|
|
61
|
+
font-size: 0.8rem;
|
|
62
|
+
color: #FFF;
|
|
63
|
+
background-color: #26A69A;
|
|
64
|
+
border-radius: 2px;
|
|
65
|
+
padding: 1px 6px;
|
|
66
|
+
line-height: inherit;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.width-100{ width: 100%; }
|
|
70
|
+
|
|
71
|
+
.border-radius-0{border-radius: 0px !important;}
|
|
72
|
+
.collection .collection-item {
|
|
73
|
+
border-right: 4px solid #FFFFFF;
|
|
74
|
+
padding: 5px 20px;
|
|
75
|
+
}
|
|
76
|
+
.collection .collection-item.selected {
|
|
77
|
+
background: #E1F5FE none repeat scroll 0% 0%;
|
|
78
|
+
border-right: 4px solid #29B6F6;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.tabs .indicator {
|
|
82
|
+
position: absolute;
|
|
83
|
+
bottom: 0;
|
|
84
|
+
height: 2px;
|
|
85
|
+
background-color: #b2ebf2 !important;
|
|
86
|
+
will-change: left, right; }
|
|
87
|
+
#log-page-header .card-image {
|
|
88
|
+
height: 250px;
|
|
89
|
+
}
|
|
90
|
+
#log-page-header .card-content {
|
|
91
|
+
margin-top: -30px;
|
|
92
|
+
}
|
|
93
|
+
#log-page-header .card-profile-image {
|
|
94
|
+
width: 110px;
|
|
95
|
+
position: absolute;
|
|
96
|
+
top: 190px;
|
|
97
|
+
z-index: 1;
|
|
98
|
+
left: 40px;
|
|
99
|
+
cursor: pointer;
|
|
100
|
+
margin: 0px;
|
|
101
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
require_dependency "rscratch/application_controller"
|
|
2
|
+
|
|
3
|
+
module Rscratch
|
|
4
|
+
class DashboardController < ApplicationController
|
|
5
|
+
def index
|
|
6
|
+
@activity_log = Rscratch::ExceptionLog.select("count(id) as exception_count, date(created_at) as date").group("date(created_at)").order("date(created_at)").last(30)
|
|
7
|
+
respond_to do |format|
|
|
8
|
+
format.html # index.html.erb
|
|
9
|
+
format.json { render json: @activity_log }
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
require_dependency "rscratch/application_controller"
|
|
2
|
+
module Rscratch
|
|
3
|
+
class ExceptionsController < ApplicationController
|
|
4
|
+
include SmartListing::Helper::ControllerExtensions
|
|
5
|
+
helper SmartListing::Helper
|
|
6
|
+
def index
|
|
7
|
+
@exceptions = Rscratch::Exception.order("updated_at desc")
|
|
8
|
+
smart_listing_create :exceptions, @exceptions.by_status('new'), partial: "rscratch/exceptions/exception_smartlist"
|
|
9
|
+
smart_listing_create :resolved_exceptions, @exceptions.by_status('resolved'), partial: "rscratch/exceptions/exception_smartlist"
|
|
10
|
+
respond_to do |format|
|
|
11
|
+
format.html # index.html.erb
|
|
12
|
+
format.js
|
|
13
|
+
format.json { render json: @exceptions }
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
def show
|
|
17
|
+
@excp = Rscratch::Exception.find(params[:id])
|
|
18
|
+
@log = @excp.exception_logs.order("created_at desc").page(params[:page]).per(1)
|
|
19
|
+
@historical_data = @excp.exception_logs.select("count(id) as exception_count, date(created_at) as date").group("date(created_at)").order("date(created_at)").last(30)
|
|
20
|
+
rescue Exception => @error
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
module Rscratch
|
|
2
|
+
class Exception < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
if Rails::VERSION::MAJOR == 3
|
|
5
|
+
attr_accessible :action, :app_environment, :controller, :exception, :message, :new_occurance_count, :total_occurance_count, :status
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
STATUS = %w(new under_development resolved)
|
|
9
|
+
|
|
10
|
+
### => Model Relations
|
|
11
|
+
has_many :exception_logs, :dependent => :destroy
|
|
12
|
+
|
|
13
|
+
### => Model Validations
|
|
14
|
+
validates :exception , presence: true
|
|
15
|
+
validates :message , presence: true
|
|
16
|
+
validates :controller , presence: true
|
|
17
|
+
validates :action , presence: true
|
|
18
|
+
validates :app_environment , presence: true
|
|
19
|
+
validates :status , presence: true, :inclusion => {:in => STATUS}
|
|
20
|
+
|
|
21
|
+
### => Model Scopes
|
|
22
|
+
scope :by_exception, lambda {|exc|where(["exception=?", exc])}
|
|
23
|
+
scope :by_message, lambda {|msg|where(["message=?", msg])}
|
|
24
|
+
scope :by_controller, lambda {|con|where(["controller=?", con])}
|
|
25
|
+
scope :by_action, lambda {|act|where(["action=?", act])}
|
|
26
|
+
scope :by_environment, lambda {|env|where(["app_environment=?", env])}
|
|
27
|
+
scope :by_status, lambda {|status|where(["status=?", status])}
|
|
28
|
+
|
|
29
|
+
# => Dynamic methods for exception statuses
|
|
30
|
+
STATUS.each do |status|
|
|
31
|
+
define_method "#{status}?" do
|
|
32
|
+
self.status == status
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Log an exception
|
|
37
|
+
def self.log(exc,request)
|
|
38
|
+
_exception = self.find_or_add_exception(exc,request.filtered_parameters["controller"].camelize,request.filtered_parameters["action"],Rails.env.camelize)
|
|
39
|
+
_excp_log = ExceptionLog.new(
|
|
40
|
+
:description => exc.inspect,
|
|
41
|
+
:backtrace => exc.backtrace.join("\n"),
|
|
42
|
+
:request_url => request.original_url,
|
|
43
|
+
:request_method => request.request_method,
|
|
44
|
+
:parameters => request.filtered_parameters,
|
|
45
|
+
:user_agent => request.user_agent,
|
|
46
|
+
:client_ip => request.remote_ip,
|
|
47
|
+
:status => "new")
|
|
48
|
+
_exception.exception_logs << _excp_log
|
|
49
|
+
return _exception
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Log unique exceptions
|
|
53
|
+
def self.find_or_add_exception exc,_controller,_action,_env
|
|
54
|
+
_excp = Exception.by_exception(exc.class).by_message(exc.message).by_controller(_controller).by_action(_action).by_environment(_env)
|
|
55
|
+
if _excp.present?
|
|
56
|
+
return _excp.first
|
|
57
|
+
else
|
|
58
|
+
_new_excp = Exception.create( :exception => exc.class,
|
|
59
|
+
:message => exc.message,
|
|
60
|
+
:controller => _controller,
|
|
61
|
+
:action => _action,
|
|
62
|
+
:app_environment => _env,
|
|
63
|
+
:status => "new")
|
|
64
|
+
return _new_excp
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
module Rscratch
|
|
2
|
+
class ExceptionLog < ActiveRecord::Base
|
|
3
|
+
|
|
4
|
+
if Rails::VERSION::MAJOR == 3
|
|
5
|
+
attr_accessible :backtrace, :client_ip, :description, :exception_id, :parameters, :request_method, :request_url, :status, :user_agent
|
|
6
|
+
end
|
|
7
|
+
### => Model Relations
|
|
8
|
+
belongs_to :exception
|
|
9
|
+
|
|
10
|
+
### => Defining statuses
|
|
11
|
+
STATUS = %w(new under_development resolved)
|
|
12
|
+
|
|
13
|
+
### => Model Validations
|
|
14
|
+
validates :exception_id, presence: true
|
|
15
|
+
validates :status, presence: true, :inclusion => {:in => STATUS}
|
|
16
|
+
|
|
17
|
+
### => Model Callbacks
|
|
18
|
+
after_create :calculate_exception_count
|
|
19
|
+
|
|
20
|
+
# => Dynamic methods for log statuses
|
|
21
|
+
STATUS.each do |status|
|
|
22
|
+
define_method "#{status}?" do
|
|
23
|
+
self.status == status
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
### => Model Scopes
|
|
28
|
+
scope :by_exception, lambda {|exc_id|where(["exception_id=?", exc_id])}
|
|
29
|
+
scope :unresolved_exceptions, lambda {|last_id|where(["id >?", last_id])}
|
|
30
|
+
scope :resolved, lambda {where(["status=?", "resolved"])}
|
|
31
|
+
|
|
32
|
+
def development!
|
|
33
|
+
update_attribute(:status, 'under_development')
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def resolve!
|
|
37
|
+
update_attribute(:status, 'resolved')
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def calculate_exception_count
|
|
43
|
+
_exception_logs = ExceptionLog.by_exception(self.exception_id)
|
|
44
|
+
_last_resolved = _exception_logs.resolved.last
|
|
45
|
+
_new_logs = _last_resolved.present? ? (ExceptionLog.unresolved_exceptions(_last_resolved.id)) : _exception_logs
|
|
46
|
+
self.exception.update_attributes(:total_occurance_count=>_exception_logs.count, :new_occurance_count=>_new_logs.count)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
!!!
|
|
2
|
+
%html
|
|
3
|
+
%head
|
|
4
|
+
%title Rscratch | Track Exceptions and Bugs of your Rails application
|
|
5
|
+
/ Import Google Icon Font
|
|
6
|
+
%link{:href => "http://fonts.googleapis.com/icon?family=Material+Icons", :rel => "stylesheet"}
|
|
7
|
+
/ Import materialize.css
|
|
8
|
+
%link{:href => "https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/css/materialize.min.css", :rel => "stylesheet"}
|
|
9
|
+
/ Compiled and minified JavaScript
|
|
10
|
+
= stylesheet_link_tag "rscratch/application", :media => "all"
|
|
11
|
+
= javascript_include_tag "rscratch/application"
|
|
12
|
+
%script{:src => "https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.5/js/materialize.min.js"}
|
|
13
|
+
= csrf_meta_tags
|
|
14
|
+
%body
|
|
15
|
+
.navbar-fixed
|
|
16
|
+
%nav.white
|
|
17
|
+
.nav-wrapper
|
|
18
|
+
%ul.left
|
|
19
|
+
%li
|
|
20
|
+
%h1.logo-wrapper{:style => ""}
|
|
21
|
+
%a{:href => "/rscratch"}
|
|
22
|
+
%img{:alt => "Rscratch", :height => "55", :src => "http://rscratch.github.io/rscratch_logo.png"}
|
|
23
|
+
%span.logo-text RScratch
|
|
24
|
+
%ul#nav-mobile.left.hide-on-med-and-down.grey-text
|
|
25
|
+
%li{:class => "#{'active' if current_page?(root_path)}"}
|
|
26
|
+
%a.grey-text.text-darken-2{:href => root_path} DASHBOARD
|
|
27
|
+
%li{:class => "#{'active' if current_page?(exceptions_path)}"}
|
|
28
|
+
%a.grey-text.text-darken-2{:href => exceptions_path} EXCEPTIONS
|
|
29
|
+
/ %li
|
|
30
|
+
/ %a.grey-text.text-darken-2{:href => "#"} CONFIGURATIONS
|
|
31
|
+
%ul.right.hide-on-med-and-down
|
|
32
|
+
%li
|
|
33
|
+
%a.waves-effect.waves-light.btn.green.darken-1{:href => "https://github.com/avishekjana/rscratch", :target => "_blank"}
|
|
34
|
+
Fork on Github
|
|
35
|
+
= yield
|