system-metrics 0.1.0
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.
- data/LICENSE +20 -0
- data/README.rdoc +106 -0
- data/app/controllers/system_metrics/metrics_controller.rb +49 -0
- data/app/helpers/system_metrics/metrics_helper.rb +36 -0
- data/app/models/system_metrics/metric.rb +36 -0
- data/app/views/layouts/system_metrics/metrics.html.erb +42 -0
- data/app/views/system_metrics/metrics/_menu.html.erb +8 -0
- data/app/views/system_metrics/metrics/_metric_row.html.erb +19 -0
- data/app/views/system_metrics/metrics/_metric_table.html.erb +24 -0
- data/app/views/system_metrics/metrics/_portlet.html.erb +18 -0
- data/app/views/system_metrics/metrics/_title_bar.html.erb +17 -0
- data/app/views/system_metrics/metrics/admin.html.erb +27 -0
- data/app/views/system_metrics/metrics/category.html.erb +4 -0
- data/app/views/system_metrics/metrics/index.html.erb +6 -0
- data/app/views/system_metrics/metrics/show.html.erb +26 -0
- data/config/routes.rb +7 -0
- data/init.rb +1 -0
- data/lib/generators/system_metrics.rb +9 -0
- data/lib/generators/system_metrics/install/install_generator.rb +21 -0
- data/lib/generators/system_metrics/migration/migration_generator.rb +26 -0
- data/lib/generators/system_metrics/migration/templates/migration.rb +22 -0
- data/lib/system-metrics.rb +1 -0
- data/lib/system_metrics.rb +33 -0
- data/lib/system_metrics/collector.rb +32 -0
- data/lib/system_metrics/config.rb +38 -0
- data/lib/system_metrics/engine.rb +43 -0
- data/lib/system_metrics/instrument.rb +10 -0
- data/lib/system_metrics/instrument/action_controller.rb +20 -0
- data/lib/system_metrics/instrument/action_mailer.rb +15 -0
- data/lib/system_metrics/instrument/action_view.rb +23 -0
- data/lib/system_metrics/instrument/active_record.rb +20 -0
- data/lib/system_metrics/instrument/base.rb +77 -0
- data/lib/system_metrics/instrument/rack.rb +11 -0
- data/lib/system_metrics/middleware.rb +32 -0
- data/lib/system_metrics/nested_event.rb +57 -0
- data/lib/system_metrics/store.rb +31 -0
- data/lib/system_metrics/version.rb +3 -0
- data/public/images/rings_13.png +0 -0
- data/public/stylesheets/app.css +13 -0
- data/public/stylesheets/base.css +46 -0
- data/public/stylesheets/footer.css +6 -0
- data/public/stylesheets/graphs.css +9 -0
- data/public/stylesheets/header.css +52 -0
- data/public/stylesheets/ie.css +36 -0
- data/public/stylesheets/menu_bar.css +7 -0
- data/public/stylesheets/metric.css +19 -0
- data/public/stylesheets/payload.css +4 -0
- data/public/stylesheets/portlet.css +11 -0
- data/public/stylesheets/print.css +29 -0
- data/public/stylesheets/reset.css +65 -0
- data/public/stylesheets/title_bar.css +29 -0
- data/public/stylesheets/typography.css +123 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/support/db_setup.rb +41 -0
- data/spec/support/mock_app.rb +23 -0
- data/spec/support/notifications_support.rb +12 -0
- data/spec/support/test_logger.rb +11 -0
- data/spec/support/test_store.rb +11 -0
- data/spec/support/transactional_specs.rb +17 -0
- data/spec/system_metrics/collector_spec.rb +60 -0
- data/spec/system_metrics/config_spec.rb +24 -0
- data/spec/system_metrics/engine_spec.rb +50 -0
- data/spec/system_metrics/middleware_spec.rb +45 -0
- data/spec/system_metrics_spec.rb +29 -0
- data/system-metrics.gemspec +24 -0
- metadata +163 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'active_support/notifications'
|
2
|
+
|
3
|
+
module SystemMetrics
|
4
|
+
class NestedEvent < ActiveSupport::Notifications::Event
|
5
|
+
|
6
|
+
def self.arrange(events, options={})
|
7
|
+
events.sort! { |a, b| a.end <=> b.end } unless options[:presort] == false
|
8
|
+
|
9
|
+
while event = events.shift
|
10
|
+
if parent = events.find { |n| n.parent_of?(event) }
|
11
|
+
parent.children << event
|
12
|
+
elsif events.empty?
|
13
|
+
root = event
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
root
|
18
|
+
end
|
19
|
+
|
20
|
+
def exclusive_duration
|
21
|
+
@exclusive_duration ||= duration - children.inject(0.0) { |sum, child| sum + child.duration }
|
22
|
+
end
|
23
|
+
|
24
|
+
def started_at
|
25
|
+
self.time
|
26
|
+
end
|
27
|
+
|
28
|
+
def ended_at
|
29
|
+
self.end
|
30
|
+
end
|
31
|
+
|
32
|
+
def children
|
33
|
+
@children ||= []
|
34
|
+
end
|
35
|
+
|
36
|
+
def parent_of?(event)
|
37
|
+
start = (started_at - event.started_at) * 1000.0
|
38
|
+
start <= 0 && (start + duration >= event.duration)
|
39
|
+
end
|
40
|
+
|
41
|
+
def child_of?(event)
|
42
|
+
event.parent_of?(self)
|
43
|
+
end
|
44
|
+
|
45
|
+
def to_hash
|
46
|
+
{
|
47
|
+
:name => name,
|
48
|
+
:started_at => started_at,
|
49
|
+
:ended_at => self.ended_at,
|
50
|
+
:transaction_id => transaction_id,
|
51
|
+
:payload => payload,
|
52
|
+
:duration => duration,
|
53
|
+
:exclusive_duration => exclusive_duration
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module SystemMetrics
|
2
|
+
class Store
|
3
|
+
def save(events)
|
4
|
+
root_event = SystemMetrics::NestedEvent.arrange(events, :presort => false)
|
5
|
+
root_model = create_metric(root_event)
|
6
|
+
root_model.update_attributes(:request_id => root_model.id)
|
7
|
+
save_tree(root_event.children, root_model.id, root_model.id)
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def save_tree(events, request_id, parent_id)
|
13
|
+
events.each do |event|
|
14
|
+
model = create_metric(event, :request_id => request_id, :parent_id => parent_id)
|
15
|
+
save_tree(event.children, request_id, model.id)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def create_metric(event, merge_params={})
|
20
|
+
action, category = event.name.split('.')
|
21
|
+
params = event.to_hash.delete_if do |key, value|
|
22
|
+
![:name, :started_at, :transaction_id, :payload, :duration, :exclusive_duration].include?(key)
|
23
|
+
end
|
24
|
+
params = params.merge(merge_params).merge(
|
25
|
+
:action => action,
|
26
|
+
:category => category
|
27
|
+
)
|
28
|
+
SystemMetrics::Metric.create(params)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
Binary file
|
@@ -0,0 +1,46 @@
|
|
1
|
+
body {
|
2
|
+
font-size: 72%;
|
3
|
+
line-height: 150%;
|
4
|
+
color: #323537;
|
5
|
+
background: #EFEFEF;
|
6
|
+
}
|
7
|
+
|
8
|
+
h1, h2, h3, h4, h5, h6 {
|
9
|
+
color: #F47721;
|
10
|
+
font-weight: normal;
|
11
|
+
}
|
12
|
+
|
13
|
+
tbody tr:nth-child(2n) td, tbody tr.even td {
|
14
|
+
background-color: #EFEFEF;
|
15
|
+
}
|
16
|
+
|
17
|
+
thead th {
|
18
|
+
background-color: #6A7176;
|
19
|
+
color: #CDCDCD;
|
20
|
+
}
|
21
|
+
|
22
|
+
a {
|
23
|
+
color: #323537;
|
24
|
+
text-decoration: none;
|
25
|
+
}
|
26
|
+
|
27
|
+
a:hover {
|
28
|
+
color: #F47721;
|
29
|
+
text-decoration: underline;
|
30
|
+
}
|
31
|
+
|
32
|
+
input[type=submit] {
|
33
|
+
background: #EFEFEF;
|
34
|
+
padding: 6px 10px 4px;
|
35
|
+
border: none;
|
36
|
+
-moz-border-radius: 10px;
|
37
|
+
-webkit-border-radius: 10px;
|
38
|
+
border-radius: 10px;
|
39
|
+
}
|
40
|
+
|
41
|
+
input[type=submit]:hover {
|
42
|
+
background: #7B8389;
|
43
|
+
color: #FFF;
|
44
|
+
cursor: pointer;
|
45
|
+
}
|
46
|
+
|
@@ -0,0 +1,52 @@
|
|
1
|
+
#header {
|
2
|
+
color: white;
|
3
|
+
background-color: #6A7176;
|
4
|
+
border-bottom: 1px solid #44484B;
|
5
|
+
padding: 9px 30px;
|
6
|
+
position: relative;
|
7
|
+
text-shadow: 0 1px 0 black;
|
8
|
+
z-index: 900;
|
9
|
+
}
|
10
|
+
|
11
|
+
#header h1 {
|
12
|
+
color: #CDCDCD;
|
13
|
+
display: inline;
|
14
|
+
font-size: 1.3em;
|
15
|
+
margin-right: 20px;
|
16
|
+
}
|
17
|
+
|
18
|
+
#header a, #header a:link {
|
19
|
+
color: #CDCDCD;
|
20
|
+
}
|
21
|
+
|
22
|
+
#header ul#tabs {
|
23
|
+
display: inline;
|
24
|
+
height: 100%;
|
25
|
+
}
|
26
|
+
|
27
|
+
#header ul#tabs li {
|
28
|
+
display: inline;
|
29
|
+
font-size: 1em;
|
30
|
+
margin-right: 4px;
|
31
|
+
padding: 9px 0;
|
32
|
+
position: relative;
|
33
|
+
}
|
34
|
+
|
35
|
+
#header ul#tabs li a {
|
36
|
+
padding: 6px 10px 4px;
|
37
|
+
position: relative;
|
38
|
+
text-decoration: none;
|
39
|
+
-moz-border-radius: 10px;
|
40
|
+
-webkit-border-radius: 10px;
|
41
|
+
border-radius: 10px;
|
42
|
+
}
|
43
|
+
|
44
|
+
#header ul#tabs li:hover > a {
|
45
|
+
background: #7B8389;
|
46
|
+
color: #FFF;
|
47
|
+
}
|
48
|
+
|
49
|
+
#header img {
|
50
|
+
position: relative;
|
51
|
+
top: 2px;
|
52
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
/* -----------------------------------------------------------------------
|
2
|
+
|
3
|
+
|
4
|
+
Blueprint CSS Framework 1.0.1
|
5
|
+
http://blueprintcss.org
|
6
|
+
|
7
|
+
* Copyright (c) 2007-Present. See LICENSE for more info.
|
8
|
+
* See README for instructions on how to use Blueprint.
|
9
|
+
* For credits and origins, see AUTHORS.
|
10
|
+
* This is a compressed file. See the sources in the 'src' directory.
|
11
|
+
|
12
|
+
----------------------------------------------------------------------- */
|
13
|
+
|
14
|
+
/* ie.css */
|
15
|
+
body {text-align:center;}
|
16
|
+
.container {text-align:left;}
|
17
|
+
* html .column, * html .span-1, * html .span-2, * html .span-3, * html .span-4, * html .span-5, * html .span-6, * html .span-7, * html .span-8, * html .span-9, * html .span-10, * html .span-11, * html .span-12, * html .span-13, * html .span-14, * html .span-15, * html .span-16, * html .span-17, * html .span-18, * html .span-19, * html .span-20, * html .span-21, * html .span-22, * html .span-23, * html .span-24 {display:inline;overflow-x:hidden;}
|
18
|
+
* html legend {margin:0px -8px 16px 0;padding:0;}
|
19
|
+
sup {vertical-align:text-top;}
|
20
|
+
sub {vertical-align:text-bottom;}
|
21
|
+
html>body p code {*white-space:normal;}
|
22
|
+
hr {margin:-8px auto 11px;}
|
23
|
+
img {-ms-interpolation-mode:bicubic;}
|
24
|
+
.clearfix, .container {display:inline-block;}
|
25
|
+
* html .clearfix, * html .container {height:1%;}
|
26
|
+
fieldset {padding-top:0;}
|
27
|
+
legend {margin-top:-0.2em;margin-bottom:1em;margin-left:-0.5em;}
|
28
|
+
textarea {overflow:auto;}
|
29
|
+
label {vertical-align:middle;position:relative;top:-0.25em;}
|
30
|
+
input.text, input.title, textarea {background-color:#fff;border:1px solid #bbb;}
|
31
|
+
input.text:focus, input.title:focus {border-color:#666;}
|
32
|
+
input.text, input.title, textarea, select {margin:0.5em 0;}
|
33
|
+
input.checkbox, input.radio {position:relative;top:.25em;}
|
34
|
+
form.inline div, form.inline p {vertical-align:middle;}
|
35
|
+
form.inline input.checkbox, form.inline input.radio, form.inline input.button, form.inline button {margin:0.5em 0;}
|
36
|
+
button, input.button {position:relative;top:0.25em;}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#metric-details {
|
2
|
+
border-right: 1px solid #EFEFEF;
|
3
|
+
float: left;
|
4
|
+
padding-right: 20px;
|
5
|
+
width: 37%;
|
6
|
+
}
|
7
|
+
|
8
|
+
#metric-details h2 {
|
9
|
+
font-size: 500%;
|
10
|
+
line-height: normal;
|
11
|
+
margin-bottom: 20px;
|
12
|
+
color: #323537;
|
13
|
+
text-align: center;
|
14
|
+
}
|
15
|
+
|
16
|
+
#metric-children {
|
17
|
+
float: right;
|
18
|
+
width: 60%;
|
19
|
+
}
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/* -----------------------------------------------------------------------
|
2
|
+
|
3
|
+
|
4
|
+
Blueprint CSS Framework 1.0.1
|
5
|
+
http://blueprintcss.org
|
6
|
+
|
7
|
+
* Copyright (c) 2007-Present. See LICENSE for more info.
|
8
|
+
* See README for instructions on how to use Blueprint.
|
9
|
+
* For credits and origins, see AUTHORS.
|
10
|
+
* This is a compressed file. See the sources in the 'src' directory.
|
11
|
+
|
12
|
+
----------------------------------------------------------------------- */
|
13
|
+
|
14
|
+
/* print.css */
|
15
|
+
body {line-height:1.5;font-family:"Helvetica Neue", Arial, Helvetica, sans-serif;color:#000;background:none;font-size:10pt;}
|
16
|
+
.container {background:none;}
|
17
|
+
hr {background:#ccc;color:#ccc;width:100%;height:2px;margin:2em 0;padding:0;border:none;}
|
18
|
+
hr.space {background:#fff;color:#fff;visibility:hidden;}
|
19
|
+
h1, h2, h3, h4, h5, h6 {font-family:"Helvetica Neue", Arial, "Lucida Grande", sans-serif;}
|
20
|
+
code {font:.9em "Courier New", Monaco, Courier, monospace;}
|
21
|
+
a img {border:none;}
|
22
|
+
p img.top {margin-top:0;}
|
23
|
+
blockquote {margin:1.5em;padding:1em;font-style:italic;font-size:.9em;}
|
24
|
+
.small {font-size:.9em;}
|
25
|
+
.large {font-size:1.1em;}
|
26
|
+
.quiet {color:#999;}
|
27
|
+
.hide {display:none;}
|
28
|
+
a:link, a:visited {background:transparent;font-weight:700;text-decoration:underline;}
|
29
|
+
a:link:after, a:visited:after {content:" (" attr(href) ")";font-size:90%;}
|
@@ -0,0 +1,65 @@
|
|
1
|
+
/* --------------------------------------------------------------
|
2
|
+
|
3
|
+
reset.css
|
4
|
+
* Resets default browser CSS.
|
5
|
+
|
6
|
+
-------------------------------------------------------------- */
|
7
|
+
|
8
|
+
html {
|
9
|
+
margin:0;
|
10
|
+
padding:0;
|
11
|
+
border:0;
|
12
|
+
}
|
13
|
+
|
14
|
+
body, div, span, object, iframe,
|
15
|
+
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
|
16
|
+
a, abbr, acronym, address, code,
|
17
|
+
del, dfn, em, img, q, dl, dt, dd, ol, ul, li,
|
18
|
+
fieldset, form, label, legend,
|
19
|
+
table, caption, tbody, tfoot, thead, tr, th, td,
|
20
|
+
article, aside, dialog, figure, footer, header,
|
21
|
+
hgroup, nav, section {
|
22
|
+
margin: 0;
|
23
|
+
padding: 0;
|
24
|
+
border: 0;
|
25
|
+
font-size: 100%;
|
26
|
+
font: inherit;
|
27
|
+
vertical-align: baseline;
|
28
|
+
}
|
29
|
+
|
30
|
+
/* This helps to make newer HTML5 elements behave like DIVs in older browers */
|
31
|
+
article, aside, details, figcaption, figure, dialog,
|
32
|
+
footer, header, hgroup, menu, nav, section {
|
33
|
+
display:block;
|
34
|
+
}
|
35
|
+
|
36
|
+
/* Line-height should always be unitless! */
|
37
|
+
body {
|
38
|
+
line-height: 1.5;
|
39
|
+
background: white;
|
40
|
+
}
|
41
|
+
|
42
|
+
/* Tables still need 'cellspacing="0"' in the markup. */
|
43
|
+
table {
|
44
|
+
border-collapse: separate;
|
45
|
+
border-spacing: 0;
|
46
|
+
}
|
47
|
+
/* float:none prevents the span-x classes from breaking table-cell display */
|
48
|
+
caption, th, td {
|
49
|
+
text-align: left;
|
50
|
+
font-weight: normal;
|
51
|
+
float:none !important;
|
52
|
+
}
|
53
|
+
table, th, td {
|
54
|
+
vertical-align: middle;
|
55
|
+
}
|
56
|
+
|
57
|
+
/* Remove possible quote marks (") from <q>, <blockquote>. */
|
58
|
+
blockquote:before, blockquote:after, q:before, q:after { content: ''; }
|
59
|
+
blockquote, q { quotes: "" ""; }
|
60
|
+
|
61
|
+
/* Remove annoying border on linked images. */
|
62
|
+
a img { border: none; }
|
63
|
+
|
64
|
+
/* Remember to define your own focus styles! */
|
65
|
+
:focus { outline: 0; }
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#title-bar {
|
2
|
+
background: #EFEFEF;
|
3
|
+
border-bottom: 1px solid #EDEDED;
|
4
|
+
color: #5E6469;
|
5
|
+
font-size: 1em;
|
6
|
+
font-weight: bold;
|
7
|
+
line-height: 140%;
|
8
|
+
padding: 10px 30px;
|
9
|
+
position: relative;
|
10
|
+
text-shadow: 0 1px 0 white;
|
11
|
+
-moz-box-shadow: 0 1px 2px #AAAAAA;
|
12
|
+
-webkit-box-shadow: 0 1px 2px #AAAAAA;
|
13
|
+
box-shadow: 0 1px 2px #AAAAAA;
|
14
|
+
}
|
15
|
+
|
16
|
+
#title-bar h2 {
|
17
|
+
font-size: 2.6em;
|
18
|
+
font-weight: bold;
|
19
|
+
margin: 12px 0 10px;
|
20
|
+
}
|
21
|
+
|
22
|
+
#title-bar h4 {
|
23
|
+
margin-bottom: 0.25em;
|
24
|
+
color: #5E6469;
|
25
|
+
}
|
26
|
+
|
27
|
+
#title-bar h4 a {
|
28
|
+
color: #5E6469;
|
29
|
+
}
|