request_log 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +7 -0
- data/Gemfile.lock +1 -1
- data/README.rdoc +9 -6
- data/doc/README_rdoc.html +204 -0
- data/doc/created.rid +2 -0
- data/doc/index.html +54 -0
- data/doc/rdoc.css +706 -0
- data/lib/request_log/data.rb +4 -5
- data/lib/request_log/version.rb +1 -1
- data/spec/data_spec.rb +2 -2
- metadata +10 -5
data/CHANGELOG
ADDED
data/Gemfile.lock
CHANGED
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Request Log
|
1
|
+
= Request Log
|
2
2
|
|
3
3
|
Request Log is a Rack middleware for logging web requests to MongoDB. Each web request becomes a document in MongoDB
|
4
4
|
with fields like path, method, params, status, time, ip, runtime etc.
|
@@ -6,7 +6,6 @@ The gem offers support for monitoring the time overhead (usually very small) tha
|
|
6
6
|
The advantages of logging to MongoDB over logging to a plain text file are huge because of the query
|
7
7
|
capabilities of MongoDB. Here is an example of what a log document can look like:
|
8
8
|
|
9
|
-
summary: "GET / - 200 0.000303"
|
10
9
|
method: "GET"
|
11
10
|
path: "/"
|
12
11
|
ip: "10.218.1.177"
|
@@ -21,9 +20,9 @@ You can easily customize which fields are stored in the log.
|
|
21
20
|
|
22
21
|
Add gem dependencies with appropriate version numbers to your Gemfile (assuming you use Bundler):
|
23
22
|
|
24
|
-
gem 'mongo', '~>
|
25
|
-
gem 'bson_ext', '~>
|
26
|
-
gem 'request_log',
|
23
|
+
gem 'mongo', '~> version known to work'
|
24
|
+
gem 'bson_ext', '~> version known to work'
|
25
|
+
gem 'request_log', '~> version known to work'
|
27
26
|
|
28
27
|
Install with:
|
29
28
|
|
@@ -42,6 +41,10 @@ Next you need to setup a MongoDB connection. Here is a MongoHQ example that in R
|
|
42
41
|
RequestLog::Db.mongo_db = connection.db(uri.path.gsub(/^\//, ''))
|
43
42
|
end
|
44
43
|
|
44
|
+
MongoDB recommends using capped collections for logging as they have good write performance. Here is an example of how to do log rotation when the size hits 20GB (this step is optional, note that the command may take a while):
|
45
|
+
|
46
|
+
RequestLog::Db.mongo_db.create_collection("requests", :capped => true, :size => 20000000000)
|
47
|
+
|
45
48
|
Now setup the Middleware in your config.ru file:
|
46
49
|
|
47
50
|
use RequestLog::Middleware
|
@@ -49,7 +52,7 @@ Now setup the Middleware in your config.ru file:
|
|
49
52
|
Here is an example of how you can customize the middleware:
|
50
53
|
|
51
54
|
use RequestLog::Middleware,
|
52
|
-
:logger => lambda { |data|
|
55
|
+
:logger => lambda { |data| RequestLog::Db.requests.insert(data.attributes.except(:runtime)) },
|
53
56
|
:timeout => 0.5
|
54
57
|
|
55
58
|
In order to use the Rake tasks you need to make sure you have the MongoDB connection setup and that you
|
@@ -0,0 +1,204 @@
|
|
1
|
+
<?xml version="1.0" encoding="utf-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
4
|
+
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
6
|
+
<head>
|
7
|
+
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
8
|
+
|
9
|
+
<title>File: README.rdoc [RDoc Documentation]</title>
|
10
|
+
|
11
|
+
<link type="text/css" media="screen" href="./rdoc.css" rel="stylesheet" />
|
12
|
+
|
13
|
+
<script src="./js/jquery.js" type="text/javascript"
|
14
|
+
charset="utf-8"></script>
|
15
|
+
<script src="./js/thickbox-compressed.js" type="text/javascript"
|
16
|
+
charset="utf-8"></script>
|
17
|
+
<script src="./js/quicksearch.js" type="text/javascript"
|
18
|
+
charset="utf-8"></script>
|
19
|
+
<script src="./js/darkfish.js" type="text/javascript"
|
20
|
+
charset="utf-8"></script>
|
21
|
+
</head>
|
22
|
+
|
23
|
+
<body class="file">
|
24
|
+
<div id="metadata">
|
25
|
+
<div id="home-metadata">
|
26
|
+
<div id="home-section" class="section">
|
27
|
+
<h3 class="section-header">
|
28
|
+
<a href="./index.html">Home</a>
|
29
|
+
<a href="./index.html#classes">Classes</a>
|
30
|
+
<a href="./index.html#methods">Methods</a>
|
31
|
+
</h3>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div id="project-metadata">
|
36
|
+
|
37
|
+
|
38
|
+
<div id="fileindex-section" class="section project-section">
|
39
|
+
<h3 class="section-header">Files</h3>
|
40
|
+
<ul>
|
41
|
+
|
42
|
+
<li class="file"><a href="./README_rdoc.html">README.rdoc</a></li>
|
43
|
+
|
44
|
+
</ul>
|
45
|
+
</div>
|
46
|
+
|
47
|
+
|
48
|
+
<div id="classindex-section" class="section project-section">
|
49
|
+
<h3 class="section-header">Class Index
|
50
|
+
<span class="search-toggle"><img src="./images/find.png"
|
51
|
+
height="16" width="16" alt="[+]"
|
52
|
+
title="show/hide quicksearch" /></span></h3>
|
53
|
+
<form action="#" method="get" accept-charset="utf-8" class="initially-hidden">
|
54
|
+
<fieldset>
|
55
|
+
<legend>Quicksearch</legend>
|
56
|
+
<input type="text" name="quicksearch" value=""
|
57
|
+
class="quicksearch-field" />
|
58
|
+
</fieldset>
|
59
|
+
</form>
|
60
|
+
|
61
|
+
<ul class="link-list">
|
62
|
+
|
63
|
+
</ul>
|
64
|
+
<div id="no-class-search-results" style="display: none;">No matching classes.</div>
|
65
|
+
</div>
|
66
|
+
|
67
|
+
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<div id="documentation">
|
72
|
+
<h1>Request Log</h1>
|
73
|
+
<p>
|
74
|
+
Request Log is a Rack middleware for logging web requests to MongoDB. Each
|
75
|
+
web request becomes a document in MongoDB with fields like path, method,
|
76
|
+
params, status, time, ip, runtime etc. The gem offers support for
|
77
|
+
monitoring the time overhead (usually very small) that the logging incurs.
|
78
|
+
The advantages of logging to MongoDB over logging to a plain text file are
|
79
|
+
huge because of the query capabilities of MongoDB. Here is an example of
|
80
|
+
what a log document can look like:
|
81
|
+
</p>
|
82
|
+
<pre>
|
83
|
+
method: "GET"
|
84
|
+
path: "/"
|
85
|
+
ip: "10.218.1.177"
|
86
|
+
time: 2010-10-28 21:43:38 UTC
|
87
|
+
params: {"hello_world"=>"1"}
|
88
|
+
status: 200
|
89
|
+
runtime: 0.000303
|
90
|
+
</pre>
|
91
|
+
<p>
|
92
|
+
You can easily customize which fields are stored in the log.
|
93
|
+
</p>
|
94
|
+
<h2>Installation</h2>
|
95
|
+
<p>
|
96
|
+
Add gem dependencies with appropriate version numbers to your Gemfile
|
97
|
+
(assuming you use Bundler):
|
98
|
+
</p>
|
99
|
+
<pre>
|
100
|
+
gem 'mongo', '~> version known to work'
|
101
|
+
gem 'bson_ext', '~> version known to work'
|
102
|
+
gem 'request_log', '~> version known to work'
|
103
|
+
</pre>
|
104
|
+
<p>
|
105
|
+
Install with:
|
106
|
+
</p>
|
107
|
+
<pre>
|
108
|
+
bundle install
|
109
|
+
</pre>
|
110
|
+
<p>
|
111
|
+
Note that it’s up to your application how it wants to connect to
|
112
|
+
MongoDB (if at all) and the suggested mongo and bson_ext gems are just
|
113
|
+
suggestions.
|
114
|
+
</p>
|
115
|
+
<p>
|
116
|
+
Next you need to setup a MongoDB connection. Here is a MongoHQ example that
|
117
|
+
in Rails would belong in config/initializers/request_log.rb:
|
118
|
+
</p>
|
119
|
+
<pre>
|
120
|
+
if ENV['MONGOHQ_URL']
|
121
|
+
require 'uri'
|
122
|
+
require 'mongo'
|
123
|
+
uri = URI.parse(ENV['MONGOHQ_URL'])
|
124
|
+
connection = Mongo::Connection.from_uri(uri.to_s)
|
125
|
+
RequestLog::Db.mongo_db = connection.db(uri.path.gsub(/^\//, ''))
|
126
|
+
end
|
127
|
+
</pre>
|
128
|
+
<p>
|
129
|
+
MongoDB recommends using capped collections for logging as they have good
|
130
|
+
write performance. Here is an example of how to do log rotation when the
|
131
|
+
size hits 20GB (this step is optional, note that the command may take a
|
132
|
+
while):
|
133
|
+
</p>
|
134
|
+
<pre>
|
135
|
+
RequestLog::Db.mongo_db.create_collection("requests", :capped => true, :size => 20000000000)
|
136
|
+
</pre>
|
137
|
+
<p>
|
138
|
+
Now setup the Middleware in your config.ru file:
|
139
|
+
</p>
|
140
|
+
<pre>
|
141
|
+
use RequestLog::Middleware
|
142
|
+
</pre>
|
143
|
+
<p>
|
144
|
+
Here is an example of how you can customize the middleware:
|
145
|
+
</p>
|
146
|
+
<pre>
|
147
|
+
use RequestLog::Middleware,
|
148
|
+
:logger => lambda { |data| ::RequestLog::Db.requests.insert(data.attributes.except(:runtime)) },
|
149
|
+
:timeout => 0.5
|
150
|
+
</pre>
|
151
|
+
<p>
|
152
|
+
In order to use the Rake tasks you need to make sure you have the MongoDB
|
153
|
+
connection setup and that you require the tasks in your Rakefile, like
|
154
|
+
this:
|
155
|
+
</p>
|
156
|
+
<pre>
|
157
|
+
require 'request_log'
|
158
|
+
require 'config/initializers/request_log.rb' # The file where you setup the mongo db connection
|
159
|
+
require 'request_log/tasks'
|
160
|
+
</pre>
|
161
|
+
<h2>Accessing the logs</h2>
|
162
|
+
<p>
|
163
|
+
You can tail the log like this:
|
164
|
+
</p>
|
165
|
+
<pre>
|
166
|
+
rake request_log:tail
|
167
|
+
</pre>
|
168
|
+
<p>
|
169
|
+
If you want to query the log and print a certain time period you can use
|
170
|
+
request_log:print:
|
171
|
+
</p>
|
172
|
+
<pre>
|
173
|
+
rake request_log:print from="2010-10-28 17:06:08" to="2010-10-28 17:06:10" conditions='status: 200'
|
174
|
+
</pre>
|
175
|
+
<p>
|
176
|
+
If you are using MONGOHQ, remember to set the MONGOHQ_URL environment
|
177
|
+
variable.
|
178
|
+
</p>
|
179
|
+
<h2>Profiling</h2>
|
180
|
+
<p>
|
181
|
+
To monitor the time consumption and reliability of the MongoDB logging you
|
182
|
+
can use the RequestLog::Profiler class. It records number of failed and
|
183
|
+
successful loggings, average and maximum logging times etc. To persist the
|
184
|
+
profiling information to MongoDB you can configure the profiler like this:
|
185
|
+
</p>
|
186
|
+
<pre>
|
187
|
+
RequestLog::Profiler.persist_enabled = true
|
188
|
+
RequestLog::Profiler.persist_frequency = 1000 # persist profiling info every 1000 requests
|
189
|
+
</pre>
|
190
|
+
<p>
|
191
|
+
The profiling info will then be written to a table (request_log_profiling)
|
192
|
+
in the MongoDB database.
|
193
|
+
</p>
|
194
|
+
|
195
|
+
</div>
|
196
|
+
|
197
|
+
<div id="validator-badges">
|
198
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
199
|
+
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
200
|
+
Rdoc Generator</a> 1.1.6</small>.</p>
|
201
|
+
</div>
|
202
|
+
</body>
|
203
|
+
</html>
|
204
|
+
|
data/doc/created.rid
ADDED
data/doc/index.html
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
3
|
+
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
4
|
+
|
5
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
6
|
+
<head>
|
7
|
+
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
|
8
|
+
|
9
|
+
<title>RDoc Documentation</title>
|
10
|
+
|
11
|
+
<link type="text/css" media="screen" href="rdoc.css" rel="stylesheet" />
|
12
|
+
|
13
|
+
<script src="js/jquery.js" type="text/javascript" charset="utf-8"></script>
|
14
|
+
<script src="js/thickbox-compressed.js" type="text/javascript" charset="utf-8"></script>
|
15
|
+
<script src="js/quicksearch.js" type="text/javascript" charset="utf-8"></script>
|
16
|
+
<script src="js/darkfish.js" type="text/javascript" charset="utf-8"></script>
|
17
|
+
|
18
|
+
</head>
|
19
|
+
<body class="indexpage">
|
20
|
+
|
21
|
+
|
22
|
+
<h1>RDoc Documentation</h1>
|
23
|
+
|
24
|
+
|
25
|
+
<p>This is the API documentation for 'RDoc Documentation'.</p>
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
<h2>Files</h2>
|
31
|
+
<ul>
|
32
|
+
|
33
|
+
<li class="file"><a href="README_rdoc.html">README.rdoc</a></li>
|
34
|
+
|
35
|
+
</ul>
|
36
|
+
|
37
|
+
|
38
|
+
<h2 id="classes">Classes/Modules</h2>
|
39
|
+
<ul>
|
40
|
+
|
41
|
+
</ul>
|
42
|
+
|
43
|
+
<h2 id="methods">Methods</h2>
|
44
|
+
<ul>
|
45
|
+
|
46
|
+
</ul>
|
47
|
+
|
48
|
+
<div id="validator-badges">
|
49
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
50
|
+
<p><small>Generated with the <a href="http://deveiate.org/projects/Darkfish-Rdoc/">Darkfish
|
51
|
+
Rdoc Generator</a> 1.1.6</small>.</p>
|
52
|
+
</div>
|
53
|
+
</body>
|
54
|
+
</html>
|
data/doc/rdoc.css
ADDED
@@ -0,0 +1,706 @@
|
|
1
|
+
/*
|
2
|
+
* "Darkfish" Rdoc CSS
|
3
|
+
* $Id: rdoc.css 54 2009-01-27 01:09:48Z deveiant $
|
4
|
+
*
|
5
|
+
* Author: Michael Granger <ged@FaerieMUD.org>
|
6
|
+
*
|
7
|
+
*/
|
8
|
+
|
9
|
+
/* Base Green is: #6C8C22 */
|
10
|
+
|
11
|
+
*{ padding: 0; margin: 0; }
|
12
|
+
|
13
|
+
body {
|
14
|
+
background: #efefef;
|
15
|
+
font: 14px "Helvetica Neue", Helvetica, Tahoma, sans-serif;
|
16
|
+
}
|
17
|
+
body.class, body.module, body.file {
|
18
|
+
margin-left: 40px;
|
19
|
+
}
|
20
|
+
body.file-popup {
|
21
|
+
font-size: 90%;
|
22
|
+
margin-left: 0;
|
23
|
+
}
|
24
|
+
|
25
|
+
h1 {
|
26
|
+
font-size: 300%;
|
27
|
+
text-shadow: rgba(135,145,135,0.65) 2px 2px 3px;
|
28
|
+
color: #6C8C22;
|
29
|
+
}
|
30
|
+
h2,h3,h4 { margin-top: 1.5em; }
|
31
|
+
|
32
|
+
:link,
|
33
|
+
:visited {
|
34
|
+
color: #6C8C22;
|
35
|
+
text-decoration: none;
|
36
|
+
}
|
37
|
+
:link:hover,
|
38
|
+
:visited:hover {
|
39
|
+
border-bottom: 1px dotted #6C8C22;
|
40
|
+
}
|
41
|
+
|
42
|
+
pre {
|
43
|
+
background: #ddd;
|
44
|
+
padding: 0.5em 0;
|
45
|
+
}
|
46
|
+
|
47
|
+
|
48
|
+
/* @group Generic Classes */
|
49
|
+
|
50
|
+
.initially-hidden {
|
51
|
+
display: none;
|
52
|
+
}
|
53
|
+
|
54
|
+
.quicksearch-field {
|
55
|
+
width: 98%;
|
56
|
+
background: #ddd;
|
57
|
+
border: 1px solid #aaa;
|
58
|
+
height: 1.5em;
|
59
|
+
-webkit-border-radius: 4px;
|
60
|
+
}
|
61
|
+
.quicksearch-field:focus {
|
62
|
+
background: #f1edba;
|
63
|
+
}
|
64
|
+
|
65
|
+
.missing-docs {
|
66
|
+
font-size: 120%;
|
67
|
+
background: white url(images/wrench_orange.png) no-repeat 4px center;
|
68
|
+
color: #ccc;
|
69
|
+
line-height: 2em;
|
70
|
+
border: 1px solid #d00;
|
71
|
+
opacity: 1;
|
72
|
+
padding-left: 20px;
|
73
|
+
text-indent: 24px;
|
74
|
+
letter-spacing: 3px;
|
75
|
+
font-weight: bold;
|
76
|
+
-webkit-border-radius: 5px;
|
77
|
+
-moz-border-radius: 5px;
|
78
|
+
}
|
79
|
+
|
80
|
+
.target-section {
|
81
|
+
border: 2px solid #dcce90;
|
82
|
+
border-left-width: 8px;
|
83
|
+
padding: 0 1em;
|
84
|
+
background: #fff3c2;
|
85
|
+
}
|
86
|
+
|
87
|
+
/* @end */
|
88
|
+
|
89
|
+
|
90
|
+
/* @group Index Page, Standalone file pages */
|
91
|
+
body.indexpage {
|
92
|
+
margin: 1em 3em;
|
93
|
+
}
|
94
|
+
body.indexpage p,
|
95
|
+
body.indexpage div,
|
96
|
+
body.file p {
|
97
|
+
margin: 1em 0;
|
98
|
+
}
|
99
|
+
|
100
|
+
.indexpage ul,
|
101
|
+
.file #documentation ul {
|
102
|
+
line-height: 160%;
|
103
|
+
list-style: none;
|
104
|
+
}
|
105
|
+
.indexpage ul :link,
|
106
|
+
.indexpage ul :visited {
|
107
|
+
font-size: 16px;
|
108
|
+
}
|
109
|
+
|
110
|
+
.indexpage li,
|
111
|
+
.file #documentation li {
|
112
|
+
padding-left: 20px;
|
113
|
+
background: url(images/bullet_black.png) no-repeat left 4px;
|
114
|
+
}
|
115
|
+
.indexpage li.module {
|
116
|
+
background: url(images/package.png) no-repeat left 4px;
|
117
|
+
}
|
118
|
+
.indexpage li.class {
|
119
|
+
background: url(images/ruby.png) no-repeat left 4px;
|
120
|
+
}
|
121
|
+
.indexpage li.file {
|
122
|
+
background: url(images/page_white_text.png) no-repeat left 4px;
|
123
|
+
}
|
124
|
+
.file li p,
|
125
|
+
.indexpage li p {
|
126
|
+
margin: 0 0;
|
127
|
+
}
|
128
|
+
|
129
|
+
/* @end */
|
130
|
+
|
131
|
+
/* @group Top-Level Structure */
|
132
|
+
|
133
|
+
.class #metadata,
|
134
|
+
.file #metadata,
|
135
|
+
.module #metadata {
|
136
|
+
float: left;
|
137
|
+
width: 260px;
|
138
|
+
}
|
139
|
+
|
140
|
+
.class #documentation,
|
141
|
+
.file #documentation,
|
142
|
+
.module #documentation {
|
143
|
+
margin: 2em 1em 5em 300px;
|
144
|
+
min-width: 340px;
|
145
|
+
}
|
146
|
+
|
147
|
+
.file #metadata {
|
148
|
+
margin: 0.8em;
|
149
|
+
}
|
150
|
+
|
151
|
+
#validator-badges {
|
152
|
+
clear: both;
|
153
|
+
margin: 1em 1em 2em;
|
154
|
+
}
|
155
|
+
|
156
|
+
/* @end */
|
157
|
+
|
158
|
+
/* @group Metadata Section */
|
159
|
+
#metadata .section {
|
160
|
+
background-color: #dedede;
|
161
|
+
-moz-border-radius: 5px;
|
162
|
+
-webkit-border-radius: 5px;
|
163
|
+
border: 1px solid #aaa;
|
164
|
+
margin: 0 8px 16px;
|
165
|
+
font-size: 90%;
|
166
|
+
overflow: hidden;
|
167
|
+
}
|
168
|
+
#metadata h3.section-header {
|
169
|
+
margin: 0;
|
170
|
+
padding: 2px 8px;
|
171
|
+
background: #ccc;
|
172
|
+
color: #666;
|
173
|
+
-moz-border-radius-topleft: 4px;
|
174
|
+
-moz-border-radius-topright: 4px;
|
175
|
+
-webkit-border-top-left-radius: 4px;
|
176
|
+
-webkit-border-top-right-radius: 4px;
|
177
|
+
border-bottom: 1px solid #aaa;
|
178
|
+
}
|
179
|
+
#metadata #home-section h3.section-header {
|
180
|
+
border-bottom: 0;
|
181
|
+
}
|
182
|
+
|
183
|
+
#metadata ul,
|
184
|
+
#metadata dl,
|
185
|
+
#metadata p {
|
186
|
+
padding: 8px;
|
187
|
+
list-style: none;
|
188
|
+
}
|
189
|
+
|
190
|
+
#file-metadata ul {
|
191
|
+
padding-left: 28px;
|
192
|
+
list-style-image: url(images/page_green.png);
|
193
|
+
}
|
194
|
+
|
195
|
+
dl.svninfo {
|
196
|
+
color: #666;
|
197
|
+
margin: 0;
|
198
|
+
}
|
199
|
+
dl.svninfo dt {
|
200
|
+
font-weight: bold;
|
201
|
+
}
|
202
|
+
|
203
|
+
ul.link-list li {
|
204
|
+
white-space: nowrap;
|
205
|
+
}
|
206
|
+
ul.link-list .type {
|
207
|
+
font-size: 8px;
|
208
|
+
text-transform: uppercase;
|
209
|
+
color: white;
|
210
|
+
background: #969696;
|
211
|
+
padding: 2px 4px;
|
212
|
+
-webkit-border-radius: 5px;
|
213
|
+
}
|
214
|
+
|
215
|
+
/* @end */
|
216
|
+
|
217
|
+
|
218
|
+
/* @group Project Metadata Section */
|
219
|
+
#project-metadata {
|
220
|
+
margin-top: 3em;
|
221
|
+
}
|
222
|
+
|
223
|
+
.file #project-metadata {
|
224
|
+
margin-top: 0em;
|
225
|
+
}
|
226
|
+
|
227
|
+
#project-metadata .section {
|
228
|
+
border: 1px solid #aaa;
|
229
|
+
}
|
230
|
+
#project-metadata h3.section-header {
|
231
|
+
border-bottom: 1px solid #aaa;
|
232
|
+
position: relative;
|
233
|
+
}
|
234
|
+
#project-metadata h3.section-header .search-toggle {
|
235
|
+
position: absolute;
|
236
|
+
right: 5px;
|
237
|
+
}
|
238
|
+
|
239
|
+
|
240
|
+
#project-metadata form {
|
241
|
+
color: #777;
|
242
|
+
background: #ccc;
|
243
|
+
padding: 8px 8px 16px;
|
244
|
+
border-bottom: 1px solid #bbb;
|
245
|
+
}
|
246
|
+
#project-metadata fieldset {
|
247
|
+
border: 0;
|
248
|
+
}
|
249
|
+
|
250
|
+
#no-class-search-results {
|
251
|
+
margin: 0 auto 1em;
|
252
|
+
text-align: center;
|
253
|
+
font-size: 14px;
|
254
|
+
font-weight: bold;
|
255
|
+
color: #aaa;
|
256
|
+
}
|
257
|
+
|
258
|
+
/* @end */
|
259
|
+
|
260
|
+
|
261
|
+
/* @group Documentation Section */
|
262
|
+
#description {
|
263
|
+
font-size: 100%;
|
264
|
+
color: #333;
|
265
|
+
}
|
266
|
+
|
267
|
+
#description p {
|
268
|
+
margin: 1em 0.4em;
|
269
|
+
}
|
270
|
+
|
271
|
+
#description li p {
|
272
|
+
margin: 0;
|
273
|
+
}
|
274
|
+
|
275
|
+
#description ul {
|
276
|
+
margin-left: 1.5em;
|
277
|
+
}
|
278
|
+
#description ul li {
|
279
|
+
line-height: 1.4em;
|
280
|
+
}
|
281
|
+
|
282
|
+
#description dl,
|
283
|
+
#documentation dl {
|
284
|
+
margin: 8px 1.5em;
|
285
|
+
border: 1px solid #ccc;
|
286
|
+
}
|
287
|
+
#description dl {
|
288
|
+
font-size: 14px;
|
289
|
+
}
|
290
|
+
|
291
|
+
#description dt,
|
292
|
+
#documentation dt {
|
293
|
+
padding: 2px 4px;
|
294
|
+
font-weight: bold;
|
295
|
+
background: #ddd;
|
296
|
+
}
|
297
|
+
#description dd,
|
298
|
+
#documentation dd {
|
299
|
+
padding: 2px 12px;
|
300
|
+
}
|
301
|
+
#description dd + dt,
|
302
|
+
#documentation dd + dt {
|
303
|
+
margin-top: 0.7em;
|
304
|
+
}
|
305
|
+
|
306
|
+
#documentation .section {
|
307
|
+
font-size: 90%;
|
308
|
+
}
|
309
|
+
#documentation h3.section-header {
|
310
|
+
margin-top: 2em;
|
311
|
+
padding: 0.75em 0.5em;
|
312
|
+
background-color: #dedede;
|
313
|
+
color: #333;
|
314
|
+
font-size: 150%;
|
315
|
+
border: 1px solid #bbb;
|
316
|
+
-moz-border-radius: 3px;
|
317
|
+
-webkit-border-radius: 3px;
|
318
|
+
}
|
319
|
+
|
320
|
+
#constants-list > dl,
|
321
|
+
#attributes-list > dl {
|
322
|
+
margin: 1em 0 2em;
|
323
|
+
border: 0;
|
324
|
+
}
|
325
|
+
#constants-list > dl dt,
|
326
|
+
#attributes-list > dl dt {
|
327
|
+
padding-left: 0;
|
328
|
+
font-weight: bold;
|
329
|
+
font-family: Monaco, "Andale Mono";
|
330
|
+
background: inherit;
|
331
|
+
}
|
332
|
+
#constants-list > dl dt a,
|
333
|
+
#attributes-list > dl dt a {
|
334
|
+
color: inherit;
|
335
|
+
}
|
336
|
+
#constants-list > dl dd,
|
337
|
+
#attributes-list > dl dd {
|
338
|
+
margin: 0 0 1em 0;
|
339
|
+
padding: 0;
|
340
|
+
color: #666;
|
341
|
+
}
|
342
|
+
|
343
|
+
/* @group Method Details */
|
344
|
+
|
345
|
+
#documentation .method-source-code {
|
346
|
+
display: none;
|
347
|
+
}
|
348
|
+
|
349
|
+
#documentation .method-detail {
|
350
|
+
margin: 0.5em 0;
|
351
|
+
padding: 0.5em 0;
|
352
|
+
cursor: pointer;
|
353
|
+
}
|
354
|
+
#documentation .method-detail:hover {
|
355
|
+
background-color: #f1edba;
|
356
|
+
}
|
357
|
+
#documentation .method-heading {
|
358
|
+
position: relative;
|
359
|
+
padding: 2px 4px 0 20px;
|
360
|
+
font-size: 125%;
|
361
|
+
font-weight: bold;
|
362
|
+
color: #333;
|
363
|
+
background: url(images/brick.png) no-repeat left bottom;
|
364
|
+
}
|
365
|
+
#documentation .method-heading :link,
|
366
|
+
#documentation .method-heading :visited {
|
367
|
+
color: inherit;
|
368
|
+
}
|
369
|
+
#documentation .method-click-advice {
|
370
|
+
position: absolute;
|
371
|
+
top: 2px;
|
372
|
+
right: 5px;
|
373
|
+
font-size: 10px;
|
374
|
+
color: #9b9877;
|
375
|
+
visibility: hidden;
|
376
|
+
padding-right: 20px;
|
377
|
+
line-height: 20px;
|
378
|
+
background: url(images/zoom.png) no-repeat right top;
|
379
|
+
}
|
380
|
+
#documentation .method-detail:hover .method-click-advice {
|
381
|
+
visibility: visible;
|
382
|
+
}
|
383
|
+
|
384
|
+
#documentation .method-alias .method-heading {
|
385
|
+
color: #666;
|
386
|
+
background: url(images/brick_link.png) no-repeat left bottom;
|
387
|
+
}
|
388
|
+
|
389
|
+
#documentation .method-description,
|
390
|
+
#documentation .aliases {
|
391
|
+
margin: 0 20px;
|
392
|
+
line-height: 1.2em;
|
393
|
+
color: #666;
|
394
|
+
}
|
395
|
+
#documentation .aliases {
|
396
|
+
padding-top: 4px;
|
397
|
+
font-style: italic;
|
398
|
+
cursor: default;
|
399
|
+
}
|
400
|
+
#documentation .method-description p {
|
401
|
+
padding: 0;
|
402
|
+
}
|
403
|
+
#documentation .method-description p + p {
|
404
|
+
margin-bottom: 0.5em;
|
405
|
+
}
|
406
|
+
#documentation .method-description ul {
|
407
|
+
margin-left: 1.5em;
|
408
|
+
}
|
409
|
+
|
410
|
+
#documentation .attribute-method-heading {
|
411
|
+
background: url(images/tag_green.png) no-repeat left bottom;
|
412
|
+
}
|
413
|
+
#documentation #attribute-method-details .method-detail:hover {
|
414
|
+
background-color: transparent;
|
415
|
+
cursor: default;
|
416
|
+
}
|
417
|
+
#documentation .attribute-access-type {
|
418
|
+
font-size: 60%;
|
419
|
+
text-transform: uppercase;
|
420
|
+
vertical-align: super;
|
421
|
+
padding: 0 2px;
|
422
|
+
}
|
423
|
+
/* @end */
|
424
|
+
|
425
|
+
/* @end */
|
426
|
+
|
427
|
+
|
428
|
+
|
429
|
+
/* @group Source Code */
|
430
|
+
|
431
|
+
div.method-source-code {
|
432
|
+
background: #262626;
|
433
|
+
color: #efefef;
|
434
|
+
margin: 1em;
|
435
|
+
padding: 0.5em;
|
436
|
+
border: 1px dashed #999;
|
437
|
+
overflow: hidden;
|
438
|
+
}
|
439
|
+
|
440
|
+
div.method-source-code pre {
|
441
|
+
background: inherit;
|
442
|
+
padding: 0;
|
443
|
+
color: white;
|
444
|
+
overflow: auto;
|
445
|
+
}
|
446
|
+
|
447
|
+
/* @group Ruby keyword styles */
|
448
|
+
|
449
|
+
.ruby-constant { color: #7fffd4; background: transparent; }
|
450
|
+
.ruby-keyword { color: #00ffff; background: transparent; }
|
451
|
+
.ruby-ivar { color: #eedd82; background: transparent; }
|
452
|
+
.ruby-operator { color: #00ffee; background: transparent; }
|
453
|
+
.ruby-identifier { color: #ffdead; background: transparent; }
|
454
|
+
.ruby-node { color: #ffa07a; background: transparent; }
|
455
|
+
.ruby-comment { color: #b22222; font-weight: bold; background: transparent; }
|
456
|
+
.ruby-regexp { color: #ffa07a; background: transparent; }
|
457
|
+
.ruby-value { color: #7fffd4; background: transparent; }
|
458
|
+
|
459
|
+
/* @end */
|
460
|
+
/* @end */
|
461
|
+
|
462
|
+
|
463
|
+
/* @group File Popup Contents */
|
464
|
+
|
465
|
+
.file #metadata,
|
466
|
+
.file-popup #metadata {
|
467
|
+
}
|
468
|
+
|
469
|
+
.file-popup dl {
|
470
|
+
font-size: 80%;
|
471
|
+
padding: 0.75em;
|
472
|
+
background-color: #dedede;
|
473
|
+
color: #333;
|
474
|
+
border: 1px solid #bbb;
|
475
|
+
-moz-border-radius: 3px;
|
476
|
+
-webkit-border-radius: 3px;
|
477
|
+
}
|
478
|
+
.file dt {
|
479
|
+
font-weight: bold;
|
480
|
+
padding-left: 22px;
|
481
|
+
line-height: 20px;
|
482
|
+
background: url(images/page_white_width.png) no-repeat left top;
|
483
|
+
}
|
484
|
+
.file dt.modified-date {
|
485
|
+
background: url(images/date.png) no-repeat left top;
|
486
|
+
}
|
487
|
+
.file dt.requires {
|
488
|
+
background: url(images/plugin.png) no-repeat left top;
|
489
|
+
}
|
490
|
+
.file dt.scs-url {
|
491
|
+
background: url(images/wrench.png) no-repeat left top;
|
492
|
+
}
|
493
|
+
|
494
|
+
.file dl dd {
|
495
|
+
margin: 0 0 1em 0;
|
496
|
+
}
|
497
|
+
.file #metadata dl dd ul {
|
498
|
+
list-style: circle;
|
499
|
+
margin-left: 20px;
|
500
|
+
padding-top: 0;
|
501
|
+
}
|
502
|
+
.file #metadata dl dd ul li {
|
503
|
+
}
|
504
|
+
|
505
|
+
|
506
|
+
.file h2 {
|
507
|
+
margin-top: 2em;
|
508
|
+
padding: 0.75em 0.5em;
|
509
|
+
background-color: #dedede;
|
510
|
+
color: #333;
|
511
|
+
font-size: 120%;
|
512
|
+
border: 1px solid #bbb;
|
513
|
+
-moz-border-radius: 3px;
|
514
|
+
-webkit-border-radius: 3px;
|
515
|
+
}
|
516
|
+
|
517
|
+
/* @end */
|
518
|
+
|
519
|
+
|
520
|
+
|
521
|
+
|
522
|
+
/* @group ThickBox Styles */
|
523
|
+
#TB_window {
|
524
|
+
font: 12px Arial, Helvetica, sans-serif;
|
525
|
+
color: #333333;
|
526
|
+
}
|
527
|
+
|
528
|
+
#TB_secondLine {
|
529
|
+
font: 10px Arial, Helvetica, sans-serif;
|
530
|
+
color:#666666;
|
531
|
+
}
|
532
|
+
|
533
|
+
#TB_window :link,
|
534
|
+
#TB_window :visited { color: #666666; }
|
535
|
+
#TB_window :link:hover,
|
536
|
+
#TB_window :visited:hover { color: #000; }
|
537
|
+
#TB_window :link:active,
|
538
|
+
#TB_window :visited:active { color: #666666; }
|
539
|
+
#TB_window :link:focus,
|
540
|
+
#TB_window :visited:focus { color: #666666; }
|
541
|
+
|
542
|
+
#TB_overlay {
|
543
|
+
position: fixed;
|
544
|
+
z-index:100;
|
545
|
+
top: 0px;
|
546
|
+
left: 0px;
|
547
|
+
height:100%;
|
548
|
+
width:100%;
|
549
|
+
}
|
550
|
+
|
551
|
+
.TB_overlayMacFFBGHack {background: url(images/macFFBgHack.png) repeat;}
|
552
|
+
.TB_overlayBG {
|
553
|
+
background-color:#000;
|
554
|
+
filter:alpha(opacity=75);
|
555
|
+
-moz-opacity: 0.75;
|
556
|
+
opacity: 0.75;
|
557
|
+
}
|
558
|
+
|
559
|
+
* html #TB_overlay { /* ie6 hack */
|
560
|
+
position: absolute;
|
561
|
+
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
|
562
|
+
}
|
563
|
+
|
564
|
+
#TB_window {
|
565
|
+
position: fixed;
|
566
|
+
background: #ffffff;
|
567
|
+
z-index: 102;
|
568
|
+
color:#000000;
|
569
|
+
display:none;
|
570
|
+
border: 4px solid #525252;
|
571
|
+
text-align:left;
|
572
|
+
top:50%;
|
573
|
+
left:50%;
|
574
|
+
}
|
575
|
+
|
576
|
+
* html #TB_window { /* ie6 hack */
|
577
|
+
position: absolute;
|
578
|
+
margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px');
|
579
|
+
}
|
580
|
+
|
581
|
+
#TB_window img#TB_Image {
|
582
|
+
display:block;
|
583
|
+
margin: 15px 0 0 15px;
|
584
|
+
border-right: 1px solid #ccc;
|
585
|
+
border-bottom: 1px solid #ccc;
|
586
|
+
border-top: 1px solid #666;
|
587
|
+
border-left: 1px solid #666;
|
588
|
+
}
|
589
|
+
|
590
|
+
#TB_caption{
|
591
|
+
height:25px;
|
592
|
+
padding:7px 30px 10px 25px;
|
593
|
+
float:left;
|
594
|
+
}
|
595
|
+
|
596
|
+
#TB_closeWindow{
|
597
|
+
height:25px;
|
598
|
+
padding:11px 25px 10px 0;
|
599
|
+
float:right;
|
600
|
+
}
|
601
|
+
|
602
|
+
#TB_closeAjaxWindow{
|
603
|
+
padding:7px 10px 5px 0;
|
604
|
+
margin-bottom:1px;
|
605
|
+
text-align:right;
|
606
|
+
float:right;
|
607
|
+
}
|
608
|
+
|
609
|
+
#TB_ajaxWindowTitle{
|
610
|
+
float:left;
|
611
|
+
padding:7px 0 5px 10px;
|
612
|
+
margin-bottom:1px;
|
613
|
+
font-size: 22px;
|
614
|
+
}
|
615
|
+
|
616
|
+
#TB_title{
|
617
|
+
background-color: #6C8C22;
|
618
|
+
color: #dedede;
|
619
|
+
height:40px;
|
620
|
+
}
|
621
|
+
#TB_title :link,
|
622
|
+
#TB_title :visited {
|
623
|
+
color: white !important;
|
624
|
+
border-bottom: 1px dotted #dedede;
|
625
|
+
}
|
626
|
+
|
627
|
+
#TB_ajaxContent{
|
628
|
+
clear:both;
|
629
|
+
padding:2px 15px 15px 15px;
|
630
|
+
overflow:auto;
|
631
|
+
text-align:left;
|
632
|
+
line-height:1.4em;
|
633
|
+
}
|
634
|
+
|
635
|
+
#TB_ajaxContent.TB_modal{
|
636
|
+
padding:15px;
|
637
|
+
}
|
638
|
+
|
639
|
+
#TB_ajaxContent p{
|
640
|
+
padding:5px 0px 5px 0px;
|
641
|
+
}
|
642
|
+
|
643
|
+
#TB_load{
|
644
|
+
position: fixed;
|
645
|
+
display:none;
|
646
|
+
height:13px;
|
647
|
+
width:208px;
|
648
|
+
z-index:103;
|
649
|
+
top: 50%;
|
650
|
+
left: 50%;
|
651
|
+
margin: -6px 0 0 -104px; /* -height/2 0 0 -width/2 */
|
652
|
+
}
|
653
|
+
|
654
|
+
* html #TB_load { /* ie6 hack */
|
655
|
+
position: absolute;
|
656
|
+
margin-top: expression(0 - parseInt(this.offsetHeight / 2) + (TBWindowMargin = document.documentElement && document.documentElement.scrollTop || document.body.scrollTop) + 'px');
|
657
|
+
}
|
658
|
+
|
659
|
+
#TB_HideSelect{
|
660
|
+
z-index:99;
|
661
|
+
position:fixed;
|
662
|
+
top: 0;
|
663
|
+
left: 0;
|
664
|
+
background-color:#fff;
|
665
|
+
border:none;
|
666
|
+
filter:alpha(opacity=0);
|
667
|
+
-moz-opacity: 0;
|
668
|
+
opacity: 0;
|
669
|
+
height:100%;
|
670
|
+
width:100%;
|
671
|
+
}
|
672
|
+
|
673
|
+
* html #TB_HideSelect { /* ie6 hack */
|
674
|
+
position: absolute;
|
675
|
+
height: expression(document.body.scrollHeight > document.body.offsetHeight ? document.body.scrollHeight : document.body.offsetHeight + 'px');
|
676
|
+
}
|
677
|
+
|
678
|
+
#TB_iframeContent{
|
679
|
+
clear:both;
|
680
|
+
border:none;
|
681
|
+
margin-bottom:-1px;
|
682
|
+
margin-top:1px;
|
683
|
+
_margin-bottom:1px;
|
684
|
+
}
|
685
|
+
|
686
|
+
/* @end */
|
687
|
+
|
688
|
+
/* @group Debugging Section */
|
689
|
+
|
690
|
+
#debugging-toggle {
|
691
|
+
text-align: center;
|
692
|
+
}
|
693
|
+
#debugging-toggle img {
|
694
|
+
cursor: pointer;
|
695
|
+
}
|
696
|
+
|
697
|
+
#rdoc-debugging-section-dump {
|
698
|
+
display: none;
|
699
|
+
margin: 0 2em 2em;
|
700
|
+
background: #ccc;
|
701
|
+
border: 1px solid #999;
|
702
|
+
}
|
703
|
+
|
704
|
+
|
705
|
+
|
706
|
+
/* @end */
|
data/lib/request_log/data.rb
CHANGED
@@ -18,14 +18,13 @@ module RequestLog
|
|
18
18
|
method = env['REQUEST_METHOD']
|
19
19
|
path = self.class.request_path(env)
|
20
20
|
{
|
21
|
-
:summary => "#{method} #{path} - #{status} #{app_time}",
|
22
21
|
:method => method,
|
23
22
|
:path => path,
|
24
|
-
:ip => env['REMOTE_ADDR'],
|
25
|
-
:time => Time.now.utc,
|
26
|
-
:params => params,
|
27
23
|
:status => status,
|
28
|
-
:
|
24
|
+
:time => Time.now.utc,
|
25
|
+
:runtime => app_time,
|
26
|
+
:ip => env['REMOTE_ADDR'],
|
27
|
+
:params => params
|
29
28
|
}
|
30
29
|
end
|
31
30
|
|
data/lib/request_log/version.rb
CHANGED
data/spec/data_spec.rb
CHANGED
@@ -12,8 +12,8 @@ describe RequestLog::Data do
|
|
12
12
|
it "returns a hash with information about a request" do
|
13
13
|
puts "running spec"
|
14
14
|
attributes = @data.attributes
|
15
|
-
attributes[:summary].should
|
16
|
-
attributes[:runtime].
|
15
|
+
attributes[:summary].should be_nil
|
16
|
+
attributes[:runtime].should == @app_time
|
17
17
|
attributes[:time].should >= (Time.now-1).utc
|
18
18
|
attributes[:time].should <= Time.now.utc
|
19
19
|
attributes[:method].should == "GET"
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
- 0
|
8
7
|
- 1
|
9
|
-
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Peter Marklund
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-
|
17
|
+
date: 2010-11-02 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -73,10 +73,15 @@ extra_rdoc_files: []
|
|
73
73
|
|
74
74
|
files:
|
75
75
|
- .gitignore
|
76
|
+
- CHANGELOG
|
76
77
|
- Gemfile
|
77
78
|
- Gemfile.lock
|
78
79
|
- README.rdoc
|
79
80
|
- Rakefile
|
81
|
+
- doc/README_rdoc.html
|
82
|
+
- doc/created.rid
|
83
|
+
- doc/index.html
|
84
|
+
- doc/rdoc.css
|
80
85
|
- lib/request_log.rb
|
81
86
|
- lib/request_log/data.rb
|
82
87
|
- lib/request_log/db.rb
|
@@ -105,7 +110,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
110
|
requirements:
|
106
111
|
- - ">="
|
107
112
|
- !ruby/object:Gem::Version
|
108
|
-
hash:
|
113
|
+
hash: 413546077
|
109
114
|
segments:
|
110
115
|
- 0
|
111
116
|
version: "0"
|
@@ -114,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
114
119
|
requirements:
|
115
120
|
- - ">="
|
116
121
|
- !ruby/object:Gem::Version
|
117
|
-
hash:
|
122
|
+
hash: 413546077
|
118
123
|
segments:
|
119
124
|
- 0
|
120
125
|
version: "0"
|