ntail 0.0.7 → 0.0.8
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/VERSION +1 -1
- data/lib/ntail/log_line.rb +0 -126
- data/lib/ntail/uri.rb +81 -0
- data/ntail.gemspec +5 -4
- data/test/ntail/test_uri.rb +32 -0
- metadata +22 -20
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.8
|
data/lib/ntail/log_line.rb
CHANGED
@@ -102,131 +102,5 @@ module NginxTail
|
|
102
102
|
]
|
103
103
|
end
|
104
104
|
|
105
|
-
CONVERSIONS = [
|
106
|
-
|
107
|
-
:to_date,
|
108
|
-
:to_date_s,
|
109
|
-
|
110
|
-
:to_agent,
|
111
|
-
:to_agent_s,
|
112
|
-
|
113
|
-
:to_host_name,
|
114
|
-
:to_refering_website,
|
115
|
-
|
116
|
-
:to_country_s,
|
117
|
-
:to_city_s,
|
118
|
-
|
119
|
-
]
|
120
|
-
|
121
|
-
def self.log_subcomponent?(subcomponent)
|
122
|
-
# TODO replace with some clever meta-programming...
|
123
|
-
SUBCOMPONENTS.include?(subcomponent)
|
124
|
-
end
|
125
|
-
|
126
|
-
def self.log_component?(component)
|
127
|
-
# TODO replace with some clever meta-programming...
|
128
|
-
COMPONENTS.include?(component)
|
129
|
-
end
|
130
|
-
|
131
|
-
def self.log_conversion?(conversion)
|
132
|
-
# TODO replace with some clever meta-programming...
|
133
|
-
CONVERSIONS.include?(conversion)
|
134
|
-
end
|
135
|
-
|
136
|
-
def self.log_directive?(directive)
|
137
|
-
(directive == :full) or log_conversion?(directive) or log_component?(directive) or log_subcomponent?(directive)
|
138
|
-
end
|
139
|
-
|
140
|
-
#
|
141
|
-
# extraction filters for log line components
|
142
|
-
#
|
143
|
-
|
144
|
-
def self.regexp_for_remote_address(remote_address)
|
145
|
-
Regexp.compile(/^(#{remote_address}) /)
|
146
|
-
end
|
147
|
-
|
148
|
-
def self.regexp_for_request(request)
|
149
|
-
Regexp.compile(/^([^"]+) "([^"]*#{request}[^"]*)" /)
|
150
|
-
end
|
151
|
-
|
152
|
-
def self.regexp_for_status(status)
|
153
|
-
Regexp.compile(/ "([^"]+)" (#{status}) /)
|
154
|
-
end
|
155
|
-
|
156
|
-
def self.regexp_for_http_referer(http_referer)
|
157
|
-
Regexp.compile(/" .* "([^"]*#{http_referer}[^"]*)" "/)
|
158
|
-
end
|
159
|
-
|
160
|
-
def self.regexp_for_http_user_agent(http_user_agent)
|
161
|
-
Regexp.compile(/ "([^"]*#{http_user_agent}[^"]*)"$/)
|
162
|
-
end
|
163
|
-
|
164
|
-
#
|
165
|
-
# validation of log line components
|
166
|
-
#
|
167
|
-
|
168
|
-
def self.valid_status?(status)
|
169
|
-
if /\A(\d{1,3})\Z/ =~ status
|
170
|
-
return $~.captures.all? { |i| 100 <= i.to_i and i.to_i < 600 }
|
171
|
-
end
|
172
|
-
return false
|
173
|
-
end
|
174
|
-
|
175
|
-
def self.valid_v4?(addr)
|
176
|
-
if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
|
177
|
-
return $~.captures.all? {|i| i.to_i < 256}
|
178
|
-
end
|
179
|
-
return false
|
180
|
-
end
|
181
|
-
|
182
|
-
def self.valid_request?(request) true ; end
|
183
|
-
def self.valid_referer?(referer) true ; end
|
184
|
-
def self.valid_user_agent?(user_agent) true ; end
|
185
|
-
|
186
|
-
#
|
187
|
-
# "GET /xd_receiver.html HTTP/1.1"
|
188
|
-
# "GET /crossdomain.xml HTTP/1.1"
|
189
|
-
# "GET /favicon.ico HTTP/1.1"
|
190
|
-
# "GET /robots.txt HTTP/1.0"
|
191
|
-
#
|
192
|
-
|
193
|
-
AUTOMATED_REQUESTS = [
|
194
|
-
Regexp.compile('^[A-Z]+ \/xd_receiver.html'),
|
195
|
-
Regexp.compile('^[A-Z]+ \/crossdomain.xml'),
|
196
|
-
Regexp.compile('^[A-Z]+ \/favicon.ico'),
|
197
|
-
Regexp.compile('^[A-Z]+ \/robots.txt'),
|
198
|
-
nil
|
199
|
-
].compact!
|
200
|
-
|
201
|
-
def self.automated_request?(request) !AUTOMATED_REQUESTS.detect { |automated_request_regexp| request.match(automated_request_regexp) }.nil? end
|
202
|
-
def automated_request?() self.class.automated_request?(self.request) ; end
|
203
|
-
|
204
|
-
#
|
205
|
-
# subdirectories of the "public" folder in the web root,
|
206
|
-
# which - in a typical Rails setup - are served by nginx
|
207
|
-
#
|
208
|
-
|
209
|
-
STATIC_REPOS = %w{
|
210
|
-
flash
|
211
|
-
html
|
212
|
-
images
|
213
|
-
javascripts
|
214
|
-
movies
|
215
|
-
newsletters
|
216
|
-
pictures
|
217
|
-
stylesheets
|
218
|
-
xml
|
219
|
-
}
|
220
|
-
|
221
|
-
STATIC_URIS = STATIC_REPOS.map { |repo| Regexp.compile("^\/#{repo}\/") }
|
222
|
-
|
223
|
-
def self.static_uri?(uri) !STATIC_URIS.detect { |static_uri_regexp| uri.match(static_uri_regexp) }.nil? end
|
224
|
-
def static_uri?() self.class.static_uri?(self.uri); end
|
225
|
-
|
226
|
-
STATIC_REQUESTS = STATIC_REPOS.map { |repo| Regexp.compile("^[A-Z]+ \/#{repo}\/") }
|
227
|
-
|
228
|
-
def self.static_request?(request) !STATIC_REQUESTS.detect { |static_request_regexp| request.match(static_request_regexp) }.nil? end
|
229
|
-
def static_request?() self.class.static_request?(self.request) ; end
|
230
|
-
|
231
105
|
end # class LogLine
|
232
106
|
end # module NginxTail
|
data/lib/ntail/uri.rb
CHANGED
@@ -4,6 +4,79 @@ module NginxTail
|
|
4
4
|
def self.included(base) # :nodoc:
|
5
5
|
base.class_eval do
|
6
6
|
|
7
|
+
#
|
8
|
+
# files in the "public" folder of the web root
|
9
|
+
# which are requested automagically, by things
|
10
|
+
# like browsers, Facebook, search engines, ...
|
11
|
+
#
|
12
|
+
|
13
|
+
@@default_automatic_files = %w{
|
14
|
+
xd_receiver.html
|
15
|
+
crossdomain.xml
|
16
|
+
favicon.ico
|
17
|
+
sitemap.xml
|
18
|
+
robots.txt
|
19
|
+
}
|
20
|
+
|
21
|
+
@@automatic_files = [] ; @@automatic_uris = []
|
22
|
+
|
23
|
+
# mainly (solely?) for testing purposes...
|
24
|
+
def self.automatic_files()
|
25
|
+
@@automatic_files.dup
|
26
|
+
end
|
27
|
+
|
28
|
+
# mainly (solely?) for testing purposes...
|
29
|
+
def self.automatic_uris()
|
30
|
+
@@automatic_uris.dup
|
31
|
+
end
|
32
|
+
|
33
|
+
# mainly (solely?) for testing purposes...
|
34
|
+
def self.reset_automatic_files()
|
35
|
+
while !@@automatic_files.empty? ; @@automatic_files.pop ; end
|
36
|
+
while !@@automatic_uris.empty? ; @@automatic_uris.pop ; end
|
37
|
+
self.add_automatic_file(@@default_automatic_files)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.add_automatic_file(automatic_file)
|
41
|
+
if automatic_file.is_a? Array
|
42
|
+
# some ducktyping, so that we can also accepts arrays of values
|
43
|
+
automatic_file.each { |file| self.add_automatic_file(file) }
|
44
|
+
else
|
45
|
+
(@@automatic_files << automatic_file).uniq!
|
46
|
+
(@@automatic_uris << Regexp.compile("^\/#{automatic_file}")).uniq!
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
# populate with default values...
|
51
|
+
self.reset_automatic_files
|
52
|
+
|
53
|
+
def self.automatic_uri?(uri)
|
54
|
+
!@@automatic_uris.detect { |automatic_uri_regexp| uri.match(automatic_uri_regexp) }.nil?
|
55
|
+
end
|
56
|
+
|
57
|
+
#
|
58
|
+
# subdirectories of the "public" folder in the web root,
|
59
|
+
# which - in a typical Rails setup - are served by nginx
|
60
|
+
#
|
61
|
+
|
62
|
+
@@static_repos = %w{
|
63
|
+
flash
|
64
|
+
html
|
65
|
+
images
|
66
|
+
javascripts
|
67
|
+
movies
|
68
|
+
newsletters
|
69
|
+
pictures
|
70
|
+
stylesheets
|
71
|
+
xml
|
72
|
+
}
|
73
|
+
|
74
|
+
@@static_uris = @@static_repos.map { |repo| Regexp.compile("^\/#{repo}\/") }
|
75
|
+
|
76
|
+
def self.static_uri?(uri)
|
77
|
+
!@@static_uris.detect { |static_uri_regexp| uri.match(static_uri_regexp) }.nil?
|
78
|
+
end
|
79
|
+
|
7
80
|
def self.to_uri_s(uri)
|
8
81
|
uri || "-" # will be nil if $request == "-" (ie. "dodgy" HTTP requests)
|
9
82
|
end
|
@@ -17,6 +90,14 @@ module NginxTail
|
|
17
90
|
def to_uri_s
|
18
91
|
self.class.to_uri_s(self.uri)
|
19
92
|
end
|
93
|
+
|
94
|
+
def automatic_uri?
|
95
|
+
self.class.automatic_uri?(self.uri)
|
96
|
+
end
|
97
|
+
|
98
|
+
def static_uri?
|
99
|
+
self.class.static_uri?(self.uri)
|
100
|
+
end
|
20
101
|
|
21
102
|
end
|
22
103
|
end
|
data/ntail.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{ntail}
|
8
|
-
s.version = "0.0.
|
8
|
+
s.version = "0.0.8"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Peter Vandenberk"]
|
12
|
-
s.date = %q{2011-01-
|
12
|
+
s.date = %q{2011-01-10}
|
13
13
|
s.default_executable = %q{ntail}
|
14
14
|
s.description = %q{A tail(1)-like utility for nginx log files. It supports parsing, filtering and formatting individual log lines.}
|
15
15
|
s.email = %q{pvandenberk@mac.com}
|
@@ -57,12 +57,13 @@ Gem::Specification.new do |s|
|
|
57
57
|
"test/ntail/test_request.rb",
|
58
58
|
"test/ntail/test_status.rb",
|
59
59
|
"test/ntail/test_time_local.rb",
|
60
|
+
"test/ntail/test_uri.rb",
|
60
61
|
"test/test_ntail.rb"
|
61
62
|
]
|
62
63
|
s.homepage = %q{http://github.com/pvdb/ntail}
|
63
64
|
s.licenses = ["MIT"]
|
64
65
|
s.require_paths = ["lib"]
|
65
|
-
s.rubygems_version = %q{1.
|
66
|
+
s.rubygems_version = %q{1.4.1}
|
66
67
|
s.summary = %q{A tail(1)-like utility for nginx log files}
|
67
68
|
s.test_files = [
|
68
69
|
"test/helper.rb",
|
@@ -77,11 +78,11 @@ Gem::Specification.new do |s|
|
|
77
78
|
"test/ntail/test_request.rb",
|
78
79
|
"test/ntail/test_status.rb",
|
79
80
|
"test/ntail/test_time_local.rb",
|
81
|
+
"test/ntail/test_uri.rb",
|
80
82
|
"test/test_ntail.rb"
|
81
83
|
]
|
82
84
|
|
83
85
|
if s.respond_to? :specification_version then
|
84
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
85
86
|
s.specification_version = 3
|
86
87
|
|
87
88
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestUri < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "ntail" do
|
6
|
+
|
7
|
+
teardown do
|
8
|
+
# undo any changes the test may have made
|
9
|
+
NginxTail::LogLine.reset_automatic_files
|
10
|
+
end
|
11
|
+
|
12
|
+
should "correctly identify a default automatic request" do
|
13
|
+
# directly via the helper function
|
14
|
+
# parsed from a raw log line
|
15
|
+
log_line = random_log_line(:uri => '/index.html')
|
16
|
+
assert !log_line.automatic_uri?
|
17
|
+
log_line = random_log_line(:uri => '/robots.txt')
|
18
|
+
assert log_line.automatic_uri?
|
19
|
+
end
|
20
|
+
|
21
|
+
should "correctly identify a custom automatic request" do
|
22
|
+
# directly via the helper function
|
23
|
+
# parsed from a raw log line
|
24
|
+
log_line = random_log_line(:uri => '/blegga.html')
|
25
|
+
assert !log_line.automatic_uri?
|
26
|
+
NginxTail::LogLine.add_automatic_file('blegga.html')
|
27
|
+
assert log_line.automatic_uri?
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ntail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
5
|
-
prerelease:
|
4
|
+
hash: 15
|
5
|
+
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 8
|
10
|
+
version: 0.0.8
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Peter Vandenberk
|
@@ -15,13 +15,11 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-10 00:00:00 +00:00
|
19
19
|
default_executable: ntail
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
type: :runtime
|
23
|
-
prerelease: false
|
24
|
-
name: rainbow
|
25
23
|
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
24
|
none: false
|
27
25
|
requirements:
|
@@ -32,10 +30,10 @@ dependencies:
|
|
32
30
|
- 0
|
33
31
|
version: "0"
|
34
32
|
requirement: *id001
|
33
|
+
prerelease: false
|
34
|
+
name: rainbow
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
type: :runtime
|
37
|
-
prerelease: false
|
38
|
-
name: user-agent
|
39
37
|
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
38
|
none: false
|
41
39
|
requirements:
|
@@ -46,10 +44,10 @@ dependencies:
|
|
46
44
|
- 0
|
47
45
|
version: "0"
|
48
46
|
requirement: *id002
|
47
|
+
prerelease: false
|
48
|
+
name: user-agent
|
49
49
|
- !ruby/object:Gem::Dependency
|
50
50
|
type: :development
|
51
|
-
prerelease: false
|
52
|
-
name: shoulda
|
53
51
|
version_requirements: &id003 !ruby/object:Gem::Requirement
|
54
52
|
none: false
|
55
53
|
requirements:
|
@@ -60,10 +58,10 @@ dependencies:
|
|
60
58
|
- 0
|
61
59
|
version: "0"
|
62
60
|
requirement: *id003
|
61
|
+
prerelease: false
|
62
|
+
name: shoulda
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
64
|
type: :development
|
65
|
-
prerelease: false
|
66
|
-
name: bundler
|
67
65
|
version_requirements: &id004 !ruby/object:Gem::Requirement
|
68
66
|
none: false
|
69
67
|
requirements:
|
@@ -76,10 +74,10 @@ dependencies:
|
|
76
74
|
- 0
|
77
75
|
version: 1.0.0
|
78
76
|
requirement: *id004
|
77
|
+
prerelease: false
|
78
|
+
name: bundler
|
79
79
|
- !ruby/object:Gem::Dependency
|
80
80
|
type: :development
|
81
|
-
prerelease: false
|
82
|
-
name: jeweler
|
83
81
|
version_requirements: &id005 !ruby/object:Gem::Requirement
|
84
82
|
none: false
|
85
83
|
requirements:
|
@@ -92,10 +90,10 @@ dependencies:
|
|
92
90
|
- 1
|
93
91
|
version: 1.5.1
|
94
92
|
requirement: *id005
|
93
|
+
prerelease: false
|
94
|
+
name: jeweler
|
95
95
|
- !ruby/object:Gem::Dependency
|
96
96
|
type: :development
|
97
|
-
prerelease: false
|
98
|
-
name: rcov
|
99
97
|
version_requirements: &id006 !ruby/object:Gem::Requirement
|
100
98
|
none: false
|
101
99
|
requirements:
|
@@ -106,10 +104,10 @@ dependencies:
|
|
106
104
|
- 0
|
107
105
|
version: "0"
|
108
106
|
requirement: *id006
|
107
|
+
prerelease: false
|
108
|
+
name: rcov
|
109
109
|
- !ruby/object:Gem::Dependency
|
110
110
|
type: :development
|
111
|
-
prerelease: false
|
112
|
-
name: geoip
|
113
111
|
version_requirements: &id007 !ruby/object:Gem::Requirement
|
114
112
|
none: false
|
115
113
|
requirements:
|
@@ -120,6 +118,8 @@ dependencies:
|
|
120
118
|
- 0
|
121
119
|
version: "0"
|
122
120
|
requirement: *id007
|
121
|
+
prerelease: false
|
122
|
+
name: geoip
|
123
123
|
description: A tail(1)-like utility for nginx log files. It supports parsing, filtering and formatting individual log lines.
|
124
124
|
email: pvandenberk@mac.com
|
125
125
|
executables:
|
@@ -168,6 +168,7 @@ files:
|
|
168
168
|
- test/ntail/test_request.rb
|
169
169
|
- test/ntail/test_status.rb
|
170
170
|
- test/ntail/test_time_local.rb
|
171
|
+
- test/ntail/test_uri.rb
|
171
172
|
- test/test_ntail.rb
|
172
173
|
has_rdoc: true
|
173
174
|
homepage: http://github.com/pvdb/ntail
|
@@ -199,7 +200,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
199
200
|
requirements: []
|
200
201
|
|
201
202
|
rubyforge_project:
|
202
|
-
rubygems_version: 1.
|
203
|
+
rubygems_version: 1.4.1
|
203
204
|
signing_key:
|
204
205
|
specification_version: 3
|
205
206
|
summary: A tail(1)-like utility for nginx log files
|
@@ -216,4 +217,5 @@ test_files:
|
|
216
217
|
- test/ntail/test_request.rb
|
217
218
|
- test/ntail/test_status.rb
|
218
219
|
- test/ntail/test_time_local.rb
|
220
|
+
- test/ntail/test_uri.rb
|
219
221
|
- test/test_ntail.rb
|