danielsdeleo-teeth 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +11 -0
- data/README.rdoc +107 -10
- data/Rakefile +47 -31
- data/VERSION.yml +4 -0
- data/doc/classes/String.html +182 -0
- data/doc/classes/Teeth/DuplicateDefinitionError.html +113 -0
- data/doc/classes/Teeth/DuplicateRuleError.html +113 -0
- data/doc/classes/Teeth/InvalidDefaultDefinitionName.html +113 -0
- data/doc/classes/Teeth/InvalidExtensionDirectory.html +113 -0
- data/doc/classes/Teeth/RuleStatement.html +291 -0
- data/doc/classes/Teeth/RuleStatementGroup.html +195 -0
- data/doc/classes/Teeth/Scanner.html +535 -0
- data/doc/classes/Teeth/ScannerDefinition.html +253 -0
- data/doc/classes/Teeth/ScannerDefinitionArgumentError.html +113 -0
- data/doc/classes/Teeth/ScannerDefinitionGroup.html +269 -0
- data/doc/classes/Teeth/ScannerError.html +111 -0
- data/doc/classes/Teeth.html +129 -0
- data/doc/created.rid +1 -0
- data/doc/files/README_rdoc.html +314 -0
- data/doc/files/ext/scan_apache_logs/scan_apache_logs_yy_c.html +101 -0
- data/doc/files/ext/scan_rails_logs/scan_rails_logs_yy_c.html +101 -0
- data/doc/files/lib/rule_statement_rb.html +101 -0
- data/doc/files/lib/scanner_definition_rb.html +101 -0
- data/doc/files/lib/scanner_rb.html +108 -0
- data/doc/files/lib/teeth_rb.html +111 -0
- data/doc/fr_class_index.html +39 -0
- data/doc/fr_file_index.html +33 -0
- data/doc/fr_method_index.html +60 -0
- data/doc/index.html +24 -0
- data/doc/rdoc-style.css +208 -0
- data/ext/scan_apache_logs/Makefile +158 -0
- data/ext/scan_apache_logs/extconf.rb +3 -0
- data/ext/scan_apache_logs/scan_apache_logs.yy +267 -0
- data/ext/scan_apache_logs/scan_apache_logs.yy.c +8355 -0
- data/ext/scan_rails_logs/Makefile +158 -0
- data/ext/scan_rails_logs/extconf.rb +3 -0
- data/ext/scan_rails_logs/scan_rails_logs.yy +376 -0
- data/ext/scan_rails_logs/scan_rails_logs.yy.c +11127 -0
- data/lib/rule_statement.rb +61 -0
- data/lib/scanner.rb +98 -0
- data/lib/scanner_definition.rb +116 -0
- data/lib/teeth.rb +5 -1
- data/scanners/scan_apache_logs.rb +27 -0
- data/scanners/scan_rails_logs.rb +70 -0
- data/spec/fixtures/rails_1x.log +59 -0
- data/spec/fixtures/rails_22.log +12 -0
- data/spec/fixtures/rails_22_cached.log +10 -0
- data/spec/fixtures/rails_unordered.log +24 -0
- data/spec/playground/show_apache_processing.rb +13 -0
- data/spec/spec_helper.rb +6 -1
- data/spec/unit/rule_statement_spec.rb +60 -0
- data/spec/unit/{tokenize_apache_spec.rb → scan_apache_spec.rb} +16 -11
- data/spec/unit/scan_rails_logs_spec.rb +90 -0
- data/spec/unit/scaner_definition_spec.rb +65 -0
- data/spec/unit/scanner_spec.rb +109 -0
- data/teeth.gemspec +31 -0
- data/templates/tokenizer.yy.erb +168 -0
- metadata +60 -15
- data/ext/extconf.rb +0 -4
- data/ext/tokenize_apache_logs.yy +0 -215
- data/ext/tokenize_apache_logs.yy.c +0 -12067
data/LICENSE
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
Copyright (c) 2009, Daniel Stephen DeLeo
|
2
|
+
Portions Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
|
3
|
+
All rights reserved.
|
4
|
+
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
8
|
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
9
|
+
Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
10
|
+
|
11
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.rdoc
CHANGED
@@ -1,26 +1,123 @@
|
|
1
1
|
= Teeth
|
2
|
-
Teeth is a library for fast parsing of log files such as Apache access and error logs. It uses C extensions generated by flex.
|
2
|
+
Teeth is a library for fast parsing of log files such as Apache access and error logs. It uses C extensions generated by flex[http://flex.sourceforge.net/index.html] (as in Flex and Bison). If you only want to use the built-in scanners, you don't need flex. If you want to add support for new/different log formats, you'll need to have flex installed.
|
3
3
|
|
4
4
|
= Example
|
5
5
|
require "teeth"
|
6
6
|
|
7
7
|
access_log = %q{myhost.localdomain:80 172.16.115.1 - - [13/Dec/2008:19:26:11 -0500] "GET /favicon.ico HTTP/1.1" 404 241 "http://172.16.115.130/" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; en) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1"}
|
8
|
-
access_log.
|
9
|
-
=>
|
8
|
+
access_log.scan_apache_logs
|
9
|
+
=> {:strings=>["241"],
|
10
|
+
:apache_access_datetime=>["13/Dec/2008:19:26:11 -0500"],
|
11
|
+
:absolute_url=>["http://172.16.115.130/"],
|
12
|
+
:message=>"myhost.localdomain:80 172.16.115.1 - - [13/Dec/2008:19:26:11 -0500] \"GET /favicon.ico HTTP/1.1\" 404 241 \"http://172.16.115.130/\" \"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; en) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1\"",
|
13
|
+
:http_method=>["GET"],
|
14
|
+
:browser_string=>["Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_4_11; en) AppleWebKit/525.27.1 (KHTML, like Gecko) Version/3.2.1 Safari/525.27.1"],
|
15
|
+
:relative_url=>["/favicon.ico"],
|
16
|
+
:http_version=>["HTTP/1.1"],
|
17
|
+
:host=>["myhost.localdomain:80"],
|
18
|
+
:id=>"8AD5CBCC1CB011DE8CE10017F22FF48F",
|
19
|
+
:http_response=>["404"],
|
20
|
+
:ipv4_addr=>["172.16.115.1"]}
|
10
21
|
|
11
|
-
= Formats
|
12
|
-
|
22
|
+
= Supported Log Formats
|
23
|
+
* Apache (access and error logs)
|
24
|
+
* Rails
|
13
25
|
|
14
|
-
Support for other web servers as well as other types of servers (e.g., SMTP, etc.) and generic syslog logs is planned for the future.
|
26
|
+
Support for other web servers, app servers, and applications as well as other types of servers (e.g., SMTP, etc.) and generic syslog logs is planned for the future.
|
27
|
+
|
28
|
+
== Creating Your Own Scanners
|
29
|
+
Teeth includes a library that can generate a flex scanner definition using a simplified definition written in ruby. This cuts down on the repetition involved in writing all the C code by hand. The included scanners for Apache and Rails logs are defined this way. You can find them in the scanners directory.
|
30
|
+
|
31
|
+
Here's an example based on the definition for the Rails log scanner:
|
32
|
+
|
33
|
+
require File.dirname(__FILE__) + "/../lib/teeth"
|
34
|
+
scanner = Teeth::Scanner.new(:rails_logs, File.dirname(__FILE__) + '/../ext/scan_rails_logs/')
|
35
|
+
|
36
|
+
Flex definitions are kinda like macros for regular expressions.
|
37
|
+
We include some of the available defaults here to make writing
|
38
|
+
the scanner easier
|
39
|
+
|
40
|
+
scanner.load_default_definitions_for(:whitespace, :ip, :time, :web)
|
41
|
+
|
42
|
+
Add some more definitions
|
43
|
+
scanner.definitions do |define|
|
44
|
+
define.RAILS_TEASER '(processing|filter\ chain\ halted|rendered)'
|
45
|
+
define.CONTROLLER_ACTION '[a-z0-9]+#[a-z0-9]+'
|
46
|
+
|
47
|
+
Scanner is case insensitive
|
48
|
+
define.RAILS_ERROR_CLASS '([a-z]+\:\:)*[a-z]+error'
|
49
|
+
|
50
|
+
"start conditions" are a feature of flex that allows
|
51
|
+
us to have some regular expressions that are only active
|
52
|
+
when we tell the scanner to enter a certain state. Here
|
53
|
+
we define the ``REQUEST_COMPLETED'' state, and specify
|
54
|
+
that it is exclusive. This means that if the scanner is
|
55
|
+
in this state, it only matches rules written for this state
|
56
|
+
define.REQUEST_COMPLETED :start_condition => :exclusive
|
57
|
+
end
|
58
|
+
|
59
|
+
Define rules. These are the actions that the scanner executes when
|
60
|
+
it sees text that matches a regular expression. The default action
|
61
|
+
is to add :action_name => [matched_text] to the results Hash, or push
|
62
|
+
the matched text on the end of the array if it already exists.
|
63
|
+
scanner.rules do |r|
|
64
|
+
|
65
|
+
This will add something like :teaser => ["Processing"] to the results
|
66
|
+
r.teaser '{RAILS_TEASER}'
|
67
|
+
r.controller_action '{CONTROLLER_ACTION}'
|
68
|
+
|
69
|
+
Use some of the default definitions we added above.
|
70
|
+
r.datetime '{YEAR}"-"{MONTH_NUM}"-"{MDAY}{WS}{HOUR}":"{MINSEC}":"{MINSEC}'
|
71
|
+
r.http_method '{HTTP_VERB}'
|
72
|
+
|
73
|
+
With :skip_line => true, scanner stops processing the line immediately
|
74
|
+
r.skip_lines '{RAILS_SKIP_LINES}', :skip_line => true
|
75
|
+
r.error '{RAILS_ERROR_CLASS}'
|
76
|
+
|
77
|
+
with :strip_ends => true, scanner removes first and last characters from matched text
|
78
|
+
r.error_message '\(({WS}|{NON_WS})+\)', :strip_ends => true
|
79
|
+
|
80
|
+
Puts scanner in the ``REQUEST_COMPLETED'' state we defined above.
|
81
|
+
The scanner only matches rules beginning with ``<REQUEST_COMPLETED>''
|
82
|
+
now
|
83
|
+
r.teaser 'completed\ in', :begin => "REQUEST_COMPLETED"
|
84
|
+
|
85
|
+
These rules only apply to the ``REQUEST_COMPLETED'' State
|
86
|
+
r.duration_s '<REQUEST_COMPLETED>[0-9]+\.[0-9]+'
|
87
|
+
r.duration_ms '<REQUEST_COMPLETED>[0-9]+/ms'
|
88
|
+
r.http_response '<REQUEST_COMPLETED>{HTTPCODE}'
|
89
|
+
|
90
|
+
Need a "catchall" rule -- flex scanner "jams" if there isn't a default rule (the
|
91
|
+
catchall rule for the default/INITIAL state is automatically included).
|
92
|
+
note that :ignore => true makes the scanner ignore what it matches but doesn't
|
93
|
+
stop processing of the line.
|
94
|
+
r.ignore_others '<REQUEST_COMPLETED>{CATCHALL}', :ignore => true
|
95
|
+
|
96
|
+
The "strings" action is special. It keeps track of whether the last token
|
97
|
+
was also a string, and if it was, the new string is appended to the
|
98
|
+
last string instead of being pushed to the array. For example, when scanning
|
99
|
+
an apache error log, ``Invalid URI in request'' will be extracted as a complete
|
100
|
+
string (instead of ["Invalid", "URI", "in", "request"])
|
101
|
+
r.strings '{NON_WS}{NON_WS}*'
|
102
|
+
end
|
103
|
+
|
104
|
+
Writes the generated scanner and an extconf.rb for it to the directory
|
105
|
+
we specified when we initialized the scanner.
|
106
|
+
scanner.write!
|
107
|
+
|
108
|
+
There's not much in the way of documentation for the scanner generator, but you can
|
109
|
+
refer to the specs and the definitions for Apache and Rails logs to get a sense
|
110
|
+
of how it works. It would probably help to learn about flex's regex syntax
|
111
|
+
and other features.
|
15
112
|
|
16
113
|
= Ruby 1.9
|
17
|
-
Ruby 1.9 is supported
|
114
|
+
Ruby 1.9 is supported on the master branch. Don't use the ruby1.9 branch, it is orphaned.
|
18
115
|
|
19
116
|
= Shortcomings and Known Issues
|
20
|
-
In addition to the lack of support for formats other than Apache
|
21
|
-
*
|
117
|
+
In addition to the lack of support for formats other than Apache and Rails described above:
|
118
|
+
* It's a new project, lots of API changes
|
22
119
|
* Does not convert datetimes to Ruby Time objects
|
23
|
-
* Does not use context or knowledge of the log format to its advantage.
|
120
|
+
* Does not always use context or knowledge of the log format to its advantage. This is improving now that the scanner can utilize start conditions.
|
24
121
|
|
25
122
|
= Performance
|
26
123
|
On my laptop, a white MacBook 2.0 GHz Intel Core Duo, teeth can process more than 30k lines of Apache access logs per second. So it's pretty fast. If modified to not create a UUID or keep the full message, this can be increased to around 45k lines/sec. One could potentially do pretty well on the wide_finder2[http://www.tbray.org/ongoing/When/200x/2008/05/01/Wide-Finder-2]...
|
data/Rakefile
CHANGED
@@ -22,7 +22,7 @@ end
|
|
22
22
|
Rake::RDocTask.new do |rdt|
|
23
23
|
rdt.rdoc_dir = "doc"
|
24
24
|
rdt.main = "README.rdoc"
|
25
|
-
rdt.rdoc_files.include("README.rdoc", "lib/*", "ext
|
25
|
+
rdt.rdoc_files.include("README.rdoc", "lib/*", "ext/*/*.yy.c")
|
26
26
|
end
|
27
27
|
|
28
28
|
begin
|
@@ -37,52 +37,68 @@ begin
|
|
37
37
|
s.has_rdoc = true
|
38
38
|
s.extra_rdoc_files = ["README.rdoc"]
|
39
39
|
s.require_path = ["lib"]
|
40
|
-
s.required_ruby_version = '<=1.9.0' # different branch for 1.8 and 1.9...
|
41
40
|
s.authors = ["Daniel DeLeo"]
|
42
|
-
s.extensions = ["ext/extconf.rb"]
|
43
|
-
s.rubyforge_project = "bloomfilter"
|
41
|
+
s.extensions = ["ext/scan_apache_logs/extconf.rb", "ext/scan_rails_logs/extconf.rb"]
|
44
42
|
|
45
43
|
# ruby -rpp -e' pp `git ls-files`.split("\n") '
|
46
|
-
s.files =
|
47
|
-
"Rakefile",
|
48
|
-
"ext/extconf.rb",
|
49
|
-
"ext/tokenize_apache_logs.yy",
|
50
|
-
"ext/tokenize_apache_logs.yy.c",
|
51
|
-
"lib/teeth.rb",
|
52
|
-
"spec/fixtures/access.log",
|
53
|
-
"spec/fixtures/big-access.log",
|
54
|
-
"spec/fixtures/big-error.log",
|
55
|
-
"spec/fixtures/error.log",
|
56
|
-
"spec/fixtures/med-error.log",
|
57
|
-
"spec/spec.opts",
|
58
|
-
"spec/spec_helper.rb",
|
59
|
-
"spec/unit/tokenize_apache_spec.rb"]
|
44
|
+
s.files = `git ls-files`.split("\n").reject {|f| f =~ /git/}
|
60
45
|
end
|
61
46
|
rescue LoadError
|
62
47
|
puts "Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com"
|
63
48
|
end
|
64
49
|
|
65
|
-
|
66
|
-
|
50
|
+
desc "outputs a list of files suitable for use with the gemspec"
|
51
|
+
task :list_files do
|
52
|
+
sh %q{ruby -rpp -e' pp `git ls-files`.split("\n").reject {|f| f =~ /git/} '}
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
CLEAN.add ["ext/*/*.bundle", "ext/*/*.so", "ext/*/*.o"]
|
57
|
+
CLOBBER.add ["ext/*/Makefile", "ext/*/*.c"]
|
67
58
|
|
68
59
|
namespace :ext do
|
69
60
|
desc "Installs the C extensions. Usually requires root."
|
70
61
|
task :install => :build do
|
71
|
-
Dir.
|
62
|
+
Dir.glob("ext/*/").each do |ext_dir|
|
63
|
+
Dir.chdir(ext_dir) {sh "make install"}
|
64
|
+
end
|
72
65
|
end
|
73
66
|
|
74
67
|
desc "Compiles the C extensions"
|
75
|
-
task :build
|
76
|
-
Dir.
|
68
|
+
task :build do |t|
|
69
|
+
Dir.glob("ext/*/").each do |ext_dir|
|
70
|
+
cd(ext_dir) {sh "make"}
|
71
|
+
end
|
77
72
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
73
|
+
|
74
|
+
desc "Generates Makefiles with extconf/mkmf"
|
75
|
+
task :makefiles
|
76
|
+
|
77
|
+
FileList["ext/*/*.yy"].each do |flex_file|
|
78
|
+
flex_generated_c = flex_file.ext("yy.c")
|
79
|
+
file flex_generated_c => flex_file do |t|
|
80
|
+
sh "flex -i -s -o #{flex_generated_c} #{flex_file}"
|
81
|
+
end
|
82
|
+
task :build => flex_generated_c
|
83
|
+
file flex_file
|
81
84
|
end
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
85
|
+
|
86
|
+
FileList["ext/*/extconf.rb"].each do |extconf_file|
|
87
|
+
extension_dir = extconf_file.sub("extconf.rb", '')
|
88
|
+
makefile = extension_dir + "Makefile"
|
89
|
+
file makefile => extconf_file do |t|
|
90
|
+
Dir.chdir(extension_dir) {ruby "./extconf.rb"}
|
91
|
+
end
|
92
|
+
file extconf_file
|
93
|
+
task :build => makefile
|
87
94
|
end
|
95
|
+
|
96
|
+
desc "Compiles Teeth::Scanner scanner definitions into flex scanner definition"
|
97
|
+
task :scanners do
|
98
|
+
FileList["scanners/*"].each do |scanner|
|
99
|
+
ruby scanner
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
|
88
104
|
end
|
data/VERSION.yml
ADDED
@@ -0,0 +1,182 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title>Class: String</title>
|
9
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
10
|
+
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
11
|
+
<link rel="stylesheet" href=".././rdoc-style.css" type="text/css" media="screen" />
|
12
|
+
<script type="text/javascript">
|
13
|
+
// <![CDATA[
|
14
|
+
|
15
|
+
function popupCode( url ) {
|
16
|
+
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
17
|
+
}
|
18
|
+
|
19
|
+
function toggleCode( id ) {
|
20
|
+
if ( document.getElementById )
|
21
|
+
elem = document.getElementById( id );
|
22
|
+
else if ( document.all )
|
23
|
+
elem = eval( "document.all." + id );
|
24
|
+
else
|
25
|
+
return false;
|
26
|
+
|
27
|
+
elemStyle = elem.style;
|
28
|
+
|
29
|
+
if ( elemStyle.display != "block" ) {
|
30
|
+
elemStyle.display = "block"
|
31
|
+
} else {
|
32
|
+
elemStyle.display = "none"
|
33
|
+
}
|
34
|
+
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Make codeblocks hidden by default
|
39
|
+
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
40
|
+
|
41
|
+
// ]]>
|
42
|
+
</script>
|
43
|
+
|
44
|
+
</head>
|
45
|
+
<body>
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
<div id="classHeader">
|
50
|
+
<table class="header-table">
|
51
|
+
<tr class="top-aligned-row">
|
52
|
+
<td><strong>Class</strong></td>
|
53
|
+
<td class="class-name-in-header">String</td>
|
54
|
+
</tr>
|
55
|
+
<tr class="top-aligned-row">
|
56
|
+
<td><strong>In:</strong></td>
|
57
|
+
<td>
|
58
|
+
</td>
|
59
|
+
</tr>
|
60
|
+
|
61
|
+
</table>
|
62
|
+
</div>
|
63
|
+
<!-- banner header -->
|
64
|
+
|
65
|
+
<div id="bodyContent">
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
<div id="contextContent">
|
70
|
+
|
71
|
+
|
72
|
+
|
73
|
+
</div>
|
74
|
+
|
75
|
+
<div id="method-list">
|
76
|
+
<h3 class="section-bar">Methods</h3>
|
77
|
+
|
78
|
+
<div class="name-list">
|
79
|
+
<a href="#M000001">scan_apache_logs</a>
|
80
|
+
<a href="#M000002">scan_rails_logs</a>
|
81
|
+
</div>
|
82
|
+
</div>
|
83
|
+
|
84
|
+
</div>
|
85
|
+
|
86
|
+
|
87
|
+
<!-- if includes -->
|
88
|
+
|
89
|
+
<div id="section">
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
<!-- if method_list -->
|
99
|
+
<div id="methods">
|
100
|
+
<h3 class="section-bar">Public Instance methods</h3>
|
101
|
+
|
102
|
+
<div id="method-M000001" class="method-detail">
|
103
|
+
<a name="M000001"></a>
|
104
|
+
|
105
|
+
<div class="method-heading">
|
106
|
+
<a href="#M000001" class="method-signature">
|
107
|
+
<span class="method-name">scan_apache_logs</span><span class="method-args">()</span>
|
108
|
+
</a>
|
109
|
+
</div>
|
110
|
+
|
111
|
+
<div class="method-description">
|
112
|
+
<p>
|
113
|
+
Scans self, which is expected to be a single line from an Apache error or
|
114
|
+
access log, and returns a Hash of the components of the log message. The
|
115
|
+
following parts of the log message are returned if they are present: IPv4
|
116
|
+
address, datetime, HTTP Version used, the browser string given by the
|
117
|
+
client, any absolute or relative URLs, the error level, HTTP response code,
|
118
|
+
HTTP Method (verb), and any other uncategorized strings present.
|
119
|
+
</p>
|
120
|
+
<p><a class="source-toggle" href="#"
|
121
|
+
onclick="toggleCode('M000001-source');return false;">[Source]</a></p>
|
122
|
+
<div class="method-source-code" id="M000001-source">
|
123
|
+
<pre>
|
124
|
+
/* Scans self, which is expected to be a single line from an Apache error or
|
125
|
+
* access log, and returns a Hash of the components of the log message. The
|
126
|
+
* following parts of the log message are returned if they are present:
|
127
|
+
* IPv4 address, datetime, HTTP Version used, the browser string given by the
|
128
|
+
* client, any absolute or relative URLs, the error level, HTTP response code,
|
129
|
+
* HTTP Method (verb), and any other uncategorized strings present. */
|
130
|
+
VALUE t_scan_apache_logs(VALUE self) {
|
131
|
+
|
132
|
+
</pre>
|
133
|
+
</div>
|
134
|
+
</div>
|
135
|
+
</div>
|
136
|
+
|
137
|
+
<div id="method-M000002" class="method-detail">
|
138
|
+
<a name="M000002"></a>
|
139
|
+
|
140
|
+
<div class="method-heading">
|
141
|
+
<a href="#M000002" class="method-signature">
|
142
|
+
<span class="method-name">scan_rails_logs</span><span class="method-args">()</span>
|
143
|
+
</a>
|
144
|
+
</div>
|
145
|
+
|
146
|
+
<div class="method-description">
|
147
|
+
<p>
|
148
|
+
Scans self, which is expected to be a line from a Rails production or dev
|
149
|
+
log, and returns a Hash of the significant features in the log message,
|
150
|
+
including the IP address of the client, the Controller and Action, any
|
151
|
+
partials rendered, and the time spent rendering them, the duration of the
|
152
|
+
DB request(s), the HTTP verb, etc.
|
153
|
+
</p>
|
154
|
+
<p><a class="source-toggle" href="#"
|
155
|
+
onclick="toggleCode('M000002-source');return false;">[Source]</a></p>
|
156
|
+
<div class="method-source-code" id="M000002-source">
|
157
|
+
<pre>
|
158
|
+
/* Scans self, which is expected to be a line from a Rails production or dev log,
|
159
|
+
* and returns a Hash of the significant features in the log message, including
|
160
|
+
* the IP address of the client, the Controller and Action, any partials rendered,
|
161
|
+
* and the time spent rendering them, the duration of the DB request(s), the HTTP
|
162
|
+
* verb, etc. */
|
163
|
+
VALUE t_scan_rails_logs(VALUE self) {
|
164
|
+
|
165
|
+
</pre>
|
166
|
+
</div>
|
167
|
+
</div>
|
168
|
+
</div>
|
169
|
+
|
170
|
+
|
171
|
+
</div>
|
172
|
+
|
173
|
+
|
174
|
+
</div>
|
175
|
+
|
176
|
+
|
177
|
+
<div id="validator-badges">
|
178
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
179
|
+
</div>
|
180
|
+
|
181
|
+
</body>
|
182
|
+
</html>
|
@@ -0,0 +1,113 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title>Class: Teeth::DuplicateDefinitionError</title>
|
9
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
10
|
+
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
11
|
+
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
12
|
+
<script type="text/javascript">
|
13
|
+
// <![CDATA[
|
14
|
+
|
15
|
+
function popupCode( url ) {
|
16
|
+
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
17
|
+
}
|
18
|
+
|
19
|
+
function toggleCode( id ) {
|
20
|
+
if ( document.getElementById )
|
21
|
+
elem = document.getElementById( id );
|
22
|
+
else if ( document.all )
|
23
|
+
elem = eval( "document.all." + id );
|
24
|
+
else
|
25
|
+
return false;
|
26
|
+
|
27
|
+
elemStyle = elem.style;
|
28
|
+
|
29
|
+
if ( elemStyle.display != "block" ) {
|
30
|
+
elemStyle.display = "block"
|
31
|
+
} else {
|
32
|
+
elemStyle.display = "none"
|
33
|
+
}
|
34
|
+
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Make codeblocks hidden by default
|
39
|
+
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
40
|
+
|
41
|
+
// ]]>
|
42
|
+
</script>
|
43
|
+
|
44
|
+
</head>
|
45
|
+
<body>
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
<div id="classHeader">
|
50
|
+
<table class="header-table">
|
51
|
+
<tr class="top-aligned-row">
|
52
|
+
<td><strong>Class</strong></td>
|
53
|
+
<td class="class-name-in-header">Teeth::DuplicateDefinitionError</td>
|
54
|
+
</tr>
|
55
|
+
<tr class="top-aligned-row">
|
56
|
+
<td><strong>In:</strong></td>
|
57
|
+
<td>
|
58
|
+
<a href="../../files/lib/scanner_definition_rb.html">
|
59
|
+
lib/scanner_definition.rb
|
60
|
+
</a>
|
61
|
+
<br />
|
62
|
+
</td>
|
63
|
+
</tr>
|
64
|
+
|
65
|
+
<tr class="top-aligned-row">
|
66
|
+
<td><strong>Parent:</strong></td>
|
67
|
+
<td>
|
68
|
+
<a href="ScannerError.html">
|
69
|
+
ScannerError
|
70
|
+
</a>
|
71
|
+
</td>
|
72
|
+
</tr>
|
73
|
+
</table>
|
74
|
+
</div>
|
75
|
+
<!-- banner header -->
|
76
|
+
|
77
|
+
<div id="bodyContent">
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
<div id="contextContent">
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
</div>
|
86
|
+
|
87
|
+
|
88
|
+
</div>
|
89
|
+
|
90
|
+
|
91
|
+
<!-- if includes -->
|
92
|
+
|
93
|
+
<div id="section">
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
<!-- if method_list -->
|
103
|
+
|
104
|
+
|
105
|
+
</div>
|
106
|
+
|
107
|
+
|
108
|
+
<div id="validator-badges">
|
109
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
</body>
|
113
|
+
</html>
|
@@ -0,0 +1,113 @@
|
|
1
|
+
<?xml version="1.0" encoding="iso-8859-1"?>
|
2
|
+
<!DOCTYPE html
|
3
|
+
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
4
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
5
|
+
|
6
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
7
|
+
<head>
|
8
|
+
<title>Class: Teeth::DuplicateRuleError</title>
|
9
|
+
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
10
|
+
<meta http-equiv="Content-Script-Type" content="text/javascript" />
|
11
|
+
<link rel="stylesheet" href="../.././rdoc-style.css" type="text/css" media="screen" />
|
12
|
+
<script type="text/javascript">
|
13
|
+
// <![CDATA[
|
14
|
+
|
15
|
+
function popupCode( url ) {
|
16
|
+
window.open(url, "Code", "resizable=yes,scrollbars=yes,toolbar=no,status=no,height=150,width=400")
|
17
|
+
}
|
18
|
+
|
19
|
+
function toggleCode( id ) {
|
20
|
+
if ( document.getElementById )
|
21
|
+
elem = document.getElementById( id );
|
22
|
+
else if ( document.all )
|
23
|
+
elem = eval( "document.all." + id );
|
24
|
+
else
|
25
|
+
return false;
|
26
|
+
|
27
|
+
elemStyle = elem.style;
|
28
|
+
|
29
|
+
if ( elemStyle.display != "block" ) {
|
30
|
+
elemStyle.display = "block"
|
31
|
+
} else {
|
32
|
+
elemStyle.display = "none"
|
33
|
+
}
|
34
|
+
|
35
|
+
return true;
|
36
|
+
}
|
37
|
+
|
38
|
+
// Make codeblocks hidden by default
|
39
|
+
document.writeln( "<style type=\"text/css\">div.method-source-code { display: none }</style>" )
|
40
|
+
|
41
|
+
// ]]>
|
42
|
+
</script>
|
43
|
+
|
44
|
+
</head>
|
45
|
+
<body>
|
46
|
+
|
47
|
+
|
48
|
+
|
49
|
+
<div id="classHeader">
|
50
|
+
<table class="header-table">
|
51
|
+
<tr class="top-aligned-row">
|
52
|
+
<td><strong>Class</strong></td>
|
53
|
+
<td class="class-name-in-header">Teeth::DuplicateRuleError</td>
|
54
|
+
</tr>
|
55
|
+
<tr class="top-aligned-row">
|
56
|
+
<td><strong>In:</strong></td>
|
57
|
+
<td>
|
58
|
+
<a href="../../files/lib/rule_statement_rb.html">
|
59
|
+
lib/rule_statement.rb
|
60
|
+
</a>
|
61
|
+
<br />
|
62
|
+
</td>
|
63
|
+
</tr>
|
64
|
+
|
65
|
+
<tr class="top-aligned-row">
|
66
|
+
<td><strong>Parent:</strong></td>
|
67
|
+
<td>
|
68
|
+
<a href="ScannerError.html">
|
69
|
+
ScannerError
|
70
|
+
</a>
|
71
|
+
</td>
|
72
|
+
</tr>
|
73
|
+
</table>
|
74
|
+
</div>
|
75
|
+
<!-- banner header -->
|
76
|
+
|
77
|
+
<div id="bodyContent">
|
78
|
+
|
79
|
+
|
80
|
+
|
81
|
+
<div id="contextContent">
|
82
|
+
|
83
|
+
|
84
|
+
|
85
|
+
</div>
|
86
|
+
|
87
|
+
|
88
|
+
</div>
|
89
|
+
|
90
|
+
|
91
|
+
<!-- if includes -->
|
92
|
+
|
93
|
+
<div id="section">
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
|
98
|
+
|
99
|
+
|
100
|
+
|
101
|
+
|
102
|
+
<!-- if method_list -->
|
103
|
+
|
104
|
+
|
105
|
+
</div>
|
106
|
+
|
107
|
+
|
108
|
+
<div id="validator-badges">
|
109
|
+
<p><small><a href="http://validator.w3.org/check/referer">[Validate]</a></small></p>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
</body>
|
113
|
+
</html>
|