ntail 1.3.1 → 1.3.2
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/.document +1 -1
- data/Gemfile.lock +1 -1
- data/README.md +2 -2
- data/VERSION +1 -1
- data/lib/ntail/body_bytes_sent.rb +3 -3
- data/lib/ntail/http_method.rb +8 -8
- data/lib/ntail/http_referer.rb +7 -7
- data/lib/ntail/http_user_agent.rb +13 -13
- data/lib/ntail/http_version.rb +3 -3
- data/lib/ntail/known_ip_addresses.rb +6 -6
- data/lib/ntail/local_ip_addresses.rb +7 -7
- data/lib/ntail/log_line.rb +2 -0
- data/lib/ntail/proxy_addresses.rb +3 -3
- data/lib/ntail/remote_addr.rb +3 -3
- data/lib/ntail/remote_user.rb +4 -4
- data/lib/ntail/request.rb +4 -4
- data/lib/ntail/status.rb +8 -8
- data/lib/ntail/time_local.rb +5 -5
- data/lib/ntail/uri.rb +4 -4
- data/ntail.gemspec +2 -2
- data/spec/application_spec.rb +2 -2
- data/test/helper.rb +11 -11
- data/test/ntail/test_formatting.rb +10 -10
- data/test/ntail/test_http_method.rb +16 -16
- data/test/ntail/test_http_referer.rb +7 -7
- data/test/ntail/test_http_user_agent.rb +2 -2
- data/test/ntail/test_http_version.rb +1 -1
- data/test/ntail/test_known_ip_addresses.rb +6 -6
- data/test/ntail/test_local_ip_addresses.rb +6 -6
- data/test/ntail/test_log_line.rb +6 -6
- data/test/ntail/test_remote_addr.rb +4 -4
- data/test/ntail/test_remote_user.rb +7 -7
- data/test/ntail/test_request.rb +8 -8
- data/test/ntail/test_status.rb +3 -3
- data/test/ntail/test_time_local.rb +4 -4
- data/test/ntail/test_uri.rb +6 -6
- data/test/test_ntail.rb +2 -2
- metadata +3 -3
data/.document
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
ntail
|
2
2
|
=====
|
3
3
|
|
4
|
-
A `tail(1)`-like utility for nginx log files that supports parsing, filtering and formatting of individual
|
4
|
+
A `tail(1)`-like utility for nginx log files that supports parsing, filtering and formatting of individual
|
5
5
|
log lines (in nginx's so-called ["combined" log format](http://wiki.nginx.org/NginxHttpLogModule#log_format)).
|
6
6
|
|
7
7
|
<a name="intro"/>
|
@@ -126,7 +126,7 @@ Advanced Examples
|
|
126
126
|
|
127
127
|
TODO
|
128
128
|
----
|
129
|
-
|
129
|
+
|
130
130
|
* implement a native `"-f"` option for ntail, similar to that of `tail(1)`, using e.g. flori's [file-tail gem](https://github.com/flori/file-tail)
|
131
131
|
* implement a `"-i"` option ("ignore exceptions"/"continue processing"), if handling a single line raises an exception
|
132
132
|
* or indeed a reverse `"-r"` option ("re-raise exception"), to immediately stop processing and raising the exception for investigation
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.3.
|
1
|
+
1.3.2
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module BodyBytesSent
|
3
|
-
|
3
|
+
|
4
4
|
def self.included(base) # :nodoc:
|
5
5
|
base.class_eval do
|
6
6
|
|
7
7
|
# this ensures the below module methods actually make sense...
|
8
8
|
raise "Class #{base.name} should implement instance method 'body_bytes_sent'" unless base.instance_methods.map(&:to_s).include? 'body_bytes_sent'
|
9
|
-
|
9
|
+
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
end
|
14
14
|
end
|
data/lib/ntail/http_method.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module HttpMethod
|
3
|
-
|
3
|
+
|
4
4
|
#
|
5
5
|
# http://www.ietf.org/rfc/rfc2616.txt - "section 5.1.1 Method"
|
6
|
-
#
|
7
|
-
# OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT
|
8
6
|
#
|
9
|
-
|
7
|
+
# OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT
|
8
|
+
#
|
9
|
+
|
10
10
|
def self.included(base) # :nodoc:
|
11
11
|
base.class_eval do
|
12
|
-
|
12
|
+
|
13
13
|
def self.to_http_method_s(http_method)
|
14
14
|
(http_method ||= "").upcase! # will be nil if $request == "-" (ie. "dodgy" HTTP requests)
|
15
15
|
case http_method
|
@@ -22,13 +22,13 @@ module NginxTail
|
|
22
22
|
|
23
23
|
# this ensures the below module methods actually make sense...
|
24
24
|
raise "Class #{base.name} should implement instance method 'http_method'" unless base.instance_methods.map(&:to_s).include? 'http_method'
|
25
|
-
|
25
|
+
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def to_http_method_s
|
30
30
|
self.class.to_http_method_s(self.http_method)
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
end
|
34
34
|
end
|
data/lib/ntail/http_referer.rb
CHANGED
@@ -20,12 +20,12 @@ module NginxTail
|
|
20
20
|
def self.reset_internal_referers()
|
21
21
|
while !@@internal_referers.empty? ; @@internal_referers.pop ; end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
# mainly (solely?) for testing purposes...
|
25
25
|
def self.internal_referers()
|
26
26
|
@@internal_referers.dup
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def self.add_internal_referer(internal_referer)
|
30
30
|
raise "Cannot add unkown HTTP referer" if self.unknown_referer? internal_referer
|
31
31
|
(@@internal_referers << internal_referer).uniq!
|
@@ -34,11 +34,11 @@ module NginxTail
|
|
34
34
|
def self.unknown_referer?(http_referer)
|
35
35
|
http_referer == UNKNOWN_REFERER
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
def self.internal_referer?(http_referer)
|
39
39
|
!self.unknown_referer?(http_referer) && !@@internal_referers.detect { |referer| referer.match(http_referer) }.nil?
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def self.external_referer?(http_referer)
|
43
43
|
!self.unknown_referer?(http_referer) && !self.internal_referer?(http_referer)
|
44
44
|
end
|
@@ -64,15 +64,15 @@ module NginxTail
|
|
64
64
|
def unknown_referer?
|
65
65
|
self.class.unknown_referer?(self.http_referer)
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
def internal_referer?
|
69
69
|
self.class.internal_referer?(self.http_referer)
|
70
70
|
end
|
71
|
-
|
71
|
+
|
72
72
|
def external_referer?
|
73
73
|
self.class.external_referer?(self.http_referer)
|
74
74
|
end
|
75
|
-
|
75
|
+
|
76
76
|
def to_referer_s
|
77
77
|
self.class.to_referer_s(self.http_referer)
|
78
78
|
end
|
@@ -2,7 +2,7 @@ require 'rubygems'
|
|
2
2
|
require 'user-agent'
|
3
3
|
|
4
4
|
class Agent
|
5
|
-
|
5
|
+
|
6
6
|
def search_bot?
|
7
7
|
false
|
8
8
|
end
|
@@ -14,7 +14,7 @@ class SearchBot < Agent
|
|
14
14
|
def search_bot?
|
15
15
|
true
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
#
|
19
19
|
# Feedfetcher-Google; (+http://www.google.com/feedfetcher.html; feed-id=17168503030479467473)
|
20
20
|
# Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
|
@@ -52,8 +52,8 @@ class SearchBot < Agent
|
|
52
52
|
|
53
53
|
def self.search_bot?(http_user_agent)
|
54
54
|
!KNOWN_SEARCH_BOTS.detect { |bot| bot.match(http_user_agent) }.nil?
|
55
|
-
end
|
56
|
-
|
55
|
+
end
|
56
|
+
|
57
57
|
attr_accessor :name
|
58
58
|
attr_accessor :os
|
59
59
|
|
@@ -80,7 +80,7 @@ class SearchBot < Agent
|
|
80
80
|
else super(string)
|
81
81
|
end
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
def self.os_for_user_agent string
|
85
85
|
case string
|
86
86
|
when GOOGLE_BOT then :"google.com"
|
@@ -98,18 +98,18 @@ class SearchBot < Agent
|
|
98
98
|
else super(string)
|
99
99
|
end
|
100
100
|
end
|
101
|
-
|
101
|
+
|
102
102
|
end
|
103
103
|
|
104
104
|
module NginxTail
|
105
105
|
module HttpUserAgent
|
106
|
-
|
106
|
+
|
107
107
|
def self.included(base) # :nodoc:
|
108
108
|
base.class_eval do
|
109
109
|
|
110
110
|
def self.search_bot?(http_user_agent)
|
111
111
|
SearchBot.search_bot?(http_user_agent)
|
112
|
-
end
|
112
|
+
end
|
113
113
|
|
114
114
|
def self.to_agent(http_user_agent)
|
115
115
|
if self.search_bot? http_user_agent
|
@@ -126,22 +126,22 @@ module NginxTail
|
|
126
126
|
|
127
127
|
# this ensures the below module methods actually make sense...
|
128
128
|
raise "Class #{base.name} should implement instance method 'http_user_agent'" unless base.instance_methods.map(&:to_s).include? 'http_user_agent'
|
129
|
-
|
129
|
+
|
130
130
|
end
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
def search_bot?
|
134
134
|
self.class.search_bot?(self.http_user_agent)
|
135
135
|
end
|
136
|
-
|
136
|
+
|
137
137
|
def to_agent
|
138
138
|
self.class.to_agent(self.http_user_agent)
|
139
139
|
end
|
140
|
-
|
140
|
+
|
141
141
|
def to_agent_s
|
142
142
|
self.class.to_agent_s(self.http_user_agent)
|
143
143
|
end
|
144
|
-
|
144
|
+
|
145
145
|
end
|
146
146
|
end
|
147
147
|
|
data/lib/ntail/http_version.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module HttpVersion
|
3
|
-
|
3
|
+
|
4
4
|
def self.included(base) # :nodoc:
|
5
5
|
base.class_eval do
|
6
6
|
|
@@ -25,13 +25,13 @@ module NginxTail
|
|
25
25
|
|
26
26
|
# this ensures the below module methods actually make sense...
|
27
27
|
raise "Class #{base.name} should implement instance method 'http_version'" unless base.instance_methods.map(&:to_s).include? 'http_version'
|
28
|
-
|
28
|
+
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def to_http_version_s(which = :full)
|
33
33
|
self.class.to_http_version_s(self.http_version, which)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
end
|
37
37
|
end
|
@@ -9,19 +9,19 @@ module NginxTail
|
|
9
9
|
|
10
10
|
def self.included(base) # :nodoc:
|
11
11
|
base.class_eval do
|
12
|
-
|
12
|
+
|
13
13
|
@@known_ip_addresses = []
|
14
14
|
|
15
15
|
# mainly (solely?) for testing purposes...
|
16
16
|
def self.known_ip_addresses()
|
17
17
|
@@known_ip_addresses.dup
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# mainly (solely?) for testing purposes...
|
21
21
|
def self.reset_known_ip_addresses()
|
22
22
|
while !@@known_ip_addresses.empty? ; @@known_ip_addresses.pop ; end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def self.add_known_ip_address(known_ip_address)
|
26
26
|
(@@known_ip_addresses << known_ip_address).uniq!
|
27
27
|
end
|
@@ -32,13 +32,13 @@ module NginxTail
|
|
32
32
|
|
33
33
|
# this ensures the below module methods actually make sense...
|
34
34
|
raise "Class #{base.name} should implement instance method 'remote_addr'" unless base.instance_methods.map(&:to_s).include? 'remote_addr'
|
35
|
-
|
35
|
+
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def known_ip_address?
|
40
40
|
self.class.known_ip_address?(self.remote_addr)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
end
|
44
44
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module LocalIpAddresses
|
3
|
-
|
3
|
+
|
4
4
|
#
|
5
5
|
# local IP addresses, for filtering and formatting purposes
|
6
6
|
#
|
@@ -11,17 +11,17 @@ module NginxTail
|
|
11
11
|
base.class_eval do
|
12
12
|
|
13
13
|
@@local_ip_addresses = []
|
14
|
-
|
14
|
+
|
15
15
|
# mainly (solely?) for testing purposes...
|
16
16
|
def self.local_ip_addresses()
|
17
17
|
@@local_ip_addresses.dup
|
18
18
|
end
|
19
|
-
|
19
|
+
|
20
20
|
# mainly (solely?) for testing purposes...
|
21
21
|
def self.reset_local_ip_addresses()
|
22
22
|
while !@@local_ip_addresses.empty? ; @@local_ip_addresses.pop ; end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def self.add_local_ip_address(local_ip_address)
|
26
26
|
(@@local_ip_addresses << local_ip_address).uniq!
|
27
27
|
end
|
@@ -32,13 +32,13 @@ module NginxTail
|
|
32
32
|
|
33
33
|
# this ensures the below module methods actually make sense...
|
34
34
|
raise "Class #{base.name} should implement instance method 'remote_addr'" unless base.instance_methods.map(&:to_s).include? 'remote_addr'
|
35
|
-
|
35
|
+
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
def local_ip_address?
|
40
40
|
self.class.local_ip_address?(self.remote_addr)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
end
|
44
44
|
end
|
data/lib/ntail/log_line.rb
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module ProxyAddresses
|
3
|
-
|
3
|
+
|
4
4
|
def self.included(base) # :nodoc:
|
5
5
|
base.class_eval do
|
6
6
|
|
7
7
|
# this ensures the below module methods actually make sense...
|
8
8
|
raise "Class #{base.name} should implement instance method 'proxy_addresses'" unless base.instance_methods.map(&:to_s).include? 'proxy_addresses'
|
9
|
-
|
9
|
+
|
10
10
|
end
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
end
|
14
14
|
end
|
data/lib/ntail/remote_addr.rb
CHANGED
@@ -24,7 +24,7 @@ module NginxTail
|
|
24
24
|
end
|
25
25
|
record ? record[5] : 'N/A'
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
def self.to_city_s(remote_addr)
|
29
29
|
record = if defined? GeoIP # ie. if the optional GeoIP gem is installed
|
30
30
|
if File.exists?('/usr/share/GeoIP/GeoIPCity.dat') # ie. if the GeoIP city database is installed
|
@@ -33,7 +33,7 @@ module NginxTail
|
|
33
33
|
end
|
34
34
|
record ? record[7] : 'N/A'
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
# this ensures the below module methods actually make sense...
|
38
38
|
raise "Class #{base.name} should implement instance method 'remote_addr'" unless base.instance_methods.map(&:to_s).include? 'remote_addr'
|
39
39
|
|
@@ -51,6 +51,6 @@ module NginxTail
|
|
51
51
|
def to_city_s()
|
52
52
|
self.class.to_city_s(self.remote_addr)
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
end
|
56
56
|
end
|
data/lib/ntail/remote_user.rb
CHANGED
@@ -18,12 +18,12 @@ module NginxTail
|
|
18
18
|
def self.reset_authenticated_users
|
19
19
|
while !@@authenticated_users.empty? ; @@authenticated_users.pop ; end
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
# mainly (solely?) for testing purposes...
|
23
23
|
def self.authenticated_users
|
24
24
|
@@authenticated_users.dup
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def self.add_authenticated_user(authenticated_user)
|
28
28
|
raise "Cannot add unkown remote user" if self.unknown_remote_user? authenticated_user
|
29
29
|
(@@authenticated_users << authenticated_user).uniq!
|
@@ -36,7 +36,7 @@ module NginxTail
|
|
36
36
|
def self.remote_user?(remote_user)
|
37
37
|
!self.unknown_remote_user?(remote_user)
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def self.authenticated_user?(remote_user)
|
41
41
|
self.remote_user?(remote_user) && @@authenticated_users.include?(remote_user)
|
42
42
|
end
|
@@ -54,7 +54,7 @@ module NginxTail
|
|
54
54
|
def remote_user?
|
55
55
|
self.class.remote_user?(self.remote_user)
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
def authenticated_user?
|
59
59
|
self.class.authenticated_user?(self.remote_user)
|
60
60
|
end
|
data/lib/ntail/request.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module Request
|
3
|
-
|
3
|
+
|
4
4
|
UNKNOWN_REQUEST = "-".freeze # the 'default' nginx value for $request variable
|
5
|
-
|
5
|
+
|
6
6
|
def self.included(base) # :nodoc:
|
7
7
|
base.class_eval do
|
8
8
|
|
@@ -12,7 +12,7 @@ module NginxTail
|
|
12
12
|
|
13
13
|
# this ensures the below module methods actually make sense...
|
14
14
|
raise "Class #{base.name} should implement instance method 'request'" unless base.instance_methods.map(&:to_s).include? 'request'
|
15
|
-
|
15
|
+
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -28,6 +28,6 @@ module NginxTail
|
|
28
28
|
"%s %s" % [self.to_http_method_s, self.to_uri_s]
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
end
|
33
33
|
end
|
data/lib/ntail/status.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module Status
|
3
|
-
|
3
|
+
|
4
4
|
NGINX_MAGIC_STATUS = '499' # ex-standard HTTP response code specific to nginx, in addition to http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
|
5
|
-
|
5
|
+
|
6
6
|
def self.included(base) # :nodoc:
|
7
7
|
base.class_eval do
|
8
8
|
|
@@ -11,25 +11,25 @@ module NginxTail
|
|
11
11
|
# (status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_TO_OBJ[status.to_s] <= Net::HTTPInformation
|
12
12
|
(status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_CLASS_TO_OBJ[(status.to_i / 100).to_s] == Net::HTTPInformation
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
# Successful 2xx
|
16
16
|
def self.success_status?(status)
|
17
17
|
# (status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_TO_OBJ[status.to_s] <= Net::HTTPSuccess
|
18
18
|
(status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_CLASS_TO_OBJ[(status.to_i / 100).to_s] == Net::HTTPSuccess
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
# Redirection 3xx
|
22
22
|
def self.redirect_status?(status)
|
23
23
|
# (status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_TO_OBJ[status.to_s] <= Net::HTTPRedirection
|
24
24
|
(status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_CLASS_TO_OBJ[(status.to_i / 100).to_s] == Net::HTTPRedirection
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
# Client Error 4xx
|
28
28
|
def self.client_error_status?(status)
|
29
29
|
# (status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_TO_OBJ[status.to_s] <= Net::HTTPClientError
|
30
30
|
(status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_CLASS_TO_OBJ[(status.to_i / 100).to_s] == Net::HTTPClientError
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
# Internal Server Error 5xx
|
34
34
|
def self.server_error_status?(status)
|
35
35
|
# (status.to_s != NGINX_MAGIC_STATUS) and Net::HTTPResponse::CODE_TO_OBJ[status.to_s] <= Net::HTTPServerError
|
@@ -38,7 +38,7 @@ module NginxTail
|
|
38
38
|
|
39
39
|
# this ensures the below module methods actually make sense...
|
40
40
|
raise "Class #{base.name} should implement instance method 'status'" unless base.instance_methods.map(&:to_s).include? 'status'
|
41
|
-
|
41
|
+
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
@@ -61,7 +61,7 @@ module NginxTail
|
|
61
61
|
def server_error_status?
|
62
62
|
self.class.server_error_status?(self.status)
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
data/lib/ntail/time_local.rb
CHANGED
@@ -2,7 +2,7 @@ require 'date'
|
|
2
2
|
|
3
3
|
module NginxTail
|
4
4
|
module TimeLocal
|
5
|
-
|
5
|
+
|
6
6
|
def self.included(base) # :nodoc:
|
7
7
|
base.class_eval do
|
8
8
|
|
@@ -15,17 +15,17 @@ module NginxTail
|
|
15
15
|
def self.to_date(time_local)
|
16
16
|
DateTime.strptime(time_local, '%d/%b/%Y:%T %z')
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def self.to_date_s(time_local, format = "%Y-%m-%d %X")
|
20
20
|
self.to_date(time_local).strftime(format)
|
21
21
|
end
|
22
22
|
|
23
23
|
# this ensures the below module methods actually make sense...
|
24
24
|
raise "Class #{base.name} should implement instance method 'time_local'" unless base.instance_methods.map(&:to_s).include? 'time_local'
|
25
|
-
|
25
|
+
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
def to_date
|
30
30
|
self.class.to_date(self.time_local)
|
31
31
|
end
|
@@ -33,6 +33,6 @@ module NginxTail
|
|
33
33
|
def to_date_s
|
34
34
|
self.class.to_date_s(self.time_local)
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
38
38
|
end
|
data/lib/ntail/uri.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module NginxTail
|
2
2
|
module Uri
|
3
|
-
|
3
|
+
|
4
4
|
def self.included(base) # :nodoc:
|
5
5
|
base.class_eval do
|
6
6
|
|
@@ -90,10 +90,10 @@ module NginxTail
|
|
90
90
|
|
91
91
|
# this ensures the below module methods actually make sense...
|
92
92
|
raise "Class #{base.name} should implement instance method 'uri'" unless base.instance_methods.map(&:to_s).include? 'uri'
|
93
|
-
|
93
|
+
|
94
94
|
end
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def to_uri_s
|
98
98
|
self.class.to_uri_s(self.uri)
|
99
99
|
end
|
@@ -105,6 +105,6 @@ module NginxTail
|
|
105
105
|
def static_uri?
|
106
106
|
self.class.static_uri?(self.uri)
|
107
107
|
end
|
108
|
-
|
108
|
+
|
109
109
|
end
|
110
110
|
end
|
data/ntail.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "ntail"
|
8
|
-
s.version = "1.3.
|
8
|
+
s.version = "1.3.2"
|
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 = "2014-
|
12
|
+
s.date = "2014-03-14"
|
13
13
|
s.description = "A tail(1)-like utility for nginx log files. It supports parsing, filtering and formatting individual log lines."
|
14
14
|
s.email = "pvandenberk@mac.com"
|
15
15
|
s.executables = ["ntail"]
|
data/spec/application_spec.rb
CHANGED
@@ -13,7 +13,7 @@ describe NginxTail::Application do
|
|
13
13
|
it "has a default 'exit' value of 0" do
|
14
14
|
NginxTail::Application.new.exit.should eq(0)
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
it "has a default 'running' value of true" do
|
18
18
|
NginxTail::Application.new.running.should eq(true)
|
19
19
|
end
|
@@ -39,5 +39,5 @@ describe NginxTail::Application do
|
|
39
39
|
it "has a 'pattern' that can be set via options" do
|
40
40
|
NginxTail::Application.new(['--apache']).pattern.should eq(:apache)
|
41
41
|
end
|
42
|
-
|
42
|
+
|
43
43
|
end
|
data/test/helper.rb
CHANGED
@@ -20,26 +20,26 @@ class Test::Unit::TestCase
|
|
20
20
|
def random_ip_address
|
21
21
|
((1..4).map { Kernel.rand(256) }).join('.')
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def local_ip_address
|
25
25
|
# http://en.wikipedia.org/wiki/IP_address#IPv4_private_addresses
|
26
26
|
(['192', '168'] + (1..2).map { Kernel.rand(256) }).join('.')
|
27
27
|
end
|
28
28
|
|
29
|
-
#
|
29
|
+
#
|
30
30
|
# http://wiki.nginx.org/NginxHttpLogModule#log_format
|
31
31
|
#
|
32
32
|
# There is a predefined log format called "combined":
|
33
|
-
#
|
33
|
+
#
|
34
34
|
# log_format combined '$remote_addr - $remote_user [$time_local] '
|
35
35
|
# '"$request" $status $body_bytes_sent '
|
36
36
|
# '"$http_referer" "$http_user_agent"';
|
37
|
-
#
|
37
|
+
#
|
38
38
|
|
39
39
|
LOG_FORMAT_COMBINED = '%s - %s [%s] ' \
|
40
40
|
'"%s" %d %d ' \
|
41
41
|
'"%s" "%s"'
|
42
|
-
|
42
|
+
|
43
43
|
DEFAULT_VALUES = {
|
44
44
|
:remote_addr => '72.46.130.42',
|
45
45
|
:remote_user => '-',
|
@@ -54,9 +54,9 @@ class Test::Unit::TestCase
|
|
54
54
|
:http_user_agent => 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10',
|
55
55
|
:proxy_addresses => nil
|
56
56
|
}
|
57
|
-
|
57
|
+
|
58
58
|
REQUEST_FORMAT = '%s %s %s'
|
59
|
-
|
59
|
+
|
60
60
|
def random_raw_line(options = {})
|
61
61
|
options = DEFAULT_VALUES.merge options
|
62
62
|
options[:request] ||= REQUEST_FORMAT % [
|
@@ -76,19 +76,19 @@ class Test::Unit::TestCase
|
|
76
76
|
# TODO implement support for :proxy_addresses
|
77
77
|
]
|
78
78
|
end
|
79
|
-
|
79
|
+
|
80
80
|
def random_log_line(options = {})
|
81
81
|
NginxTail::LogLine.new(random_raw_line(options))
|
82
82
|
end
|
83
|
-
|
83
|
+
|
84
84
|
def bad_request_raw_line
|
85
85
|
# a "bad request", resulting in a 400 status, is logged by nginx as follows:
|
86
86
|
# 121.8.101.138 - - [28/Dec/2010:23:50:58 +0000] "-" 400 0 "-" "-"
|
87
87
|
'121.8.101.138 - - [28/Dec/2010:23:50:58 +0000] "-" 400 0 "-" "-"'
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
def bad_request_log_line
|
91
91
|
NginxTail::LogLine.new(bad_request_raw_line)
|
92
92
|
end
|
93
|
-
|
93
|
+
|
94
94
|
end
|
@@ -3,70 +3,70 @@ require 'helper'
|
|
3
3
|
class TestFormatting < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "NginxTail::Formatting" do
|
6
|
-
|
6
|
+
|
7
7
|
should "correctly format remote_addr using the %a taken" do
|
8
8
|
remote_addr = random_ip_address
|
9
9
|
log_line = random_log_line(:remote_addr => remote_addr)
|
10
10
|
NginxTail::LogLine.format = "%a"
|
11
11
|
assert_equal "%15s" % remote_addr, log_line.to_s(:color => false)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
should "correctly format remote_user using the %u taken" do
|
15
15
|
remote_user = 'me_myself_and_i'
|
16
16
|
log_line = random_log_line(:remote_user => remote_user)
|
17
17
|
NginxTail::LogLine.format = "%u"
|
18
18
|
assert_equal remote_user, log_line.to_s(:color => false)
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
should "correctly format time_local using the %t taken" do
|
22
22
|
time_local = '25/Feb/2011:07:53:29 +0000'
|
23
23
|
log_line = random_log_line(:time_local => time_local)
|
24
24
|
NginxTail::LogLine.format = "%t"
|
25
25
|
assert_equal '2011-02-25 07:53:29', log_line.to_s(:color => false)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
should "correctly format request using the %r taken" do
|
29
29
|
request = 'GET / HTTP/1.1'
|
30
30
|
log_line = random_log_line(:request => request)
|
31
31
|
NginxTail::LogLine.format = "%r"
|
32
32
|
assert_equal 'GET /', log_line.to_s(:color => false)
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
should "correctly format status using the %s taken" do
|
36
36
|
status = '200'
|
37
37
|
log_line = random_log_line(:status => status)
|
38
38
|
NginxTail::LogLine.format = "%s"
|
39
39
|
assert_equal status, log_line.to_s(:color => false)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
should "correctly format body_bytes_sent using the %b taken" do
|
43
43
|
body_bytes_sent = '31415'
|
44
44
|
log_line = random_log_line(:body_bytes_sent => body_bytes_sent)
|
45
45
|
NginxTail::LogLine.format = "%b"
|
46
46
|
assert_equal body_bytes_sent, log_line.to_s(:color => false)
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
should "correctly format http_referer using the %R taken" do
|
50
50
|
http_referer = 'http://www.google.com/search?q=ntail'
|
51
51
|
log_line = random_log_line(:http_referer => http_referer)
|
52
52
|
NginxTail::LogLine.format = "%R"
|
53
53
|
assert_equal 'www.google.com', log_line.to_s(:color => false)
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
should "correctly format http_user_agent using the %U taken" do
|
57
57
|
http_user_agent = 'Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.102 Safari/534.13'
|
58
58
|
log_line = random_log_line(:http_user_agent => http_user_agent)
|
59
59
|
NginxTail::LogLine.format = "%U"
|
60
60
|
assert_equal '(Chrome, OS X 10.6)', log_line.to_s(:color => false)
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
# should "correctly format proxy_addresses using the %p taken" do
|
64
64
|
# proxy_addresses = '"127.0.0.1"'
|
65
65
|
# log_line = random_log_line(:proxy_addresses => proxy_addresses)
|
66
66
|
# NginxTail::LogLine.format = "%p"
|
67
67
|
# assert_equal proxy_addresses, log_line.to_s(:color => false)
|
68
68
|
# end
|
69
|
-
|
69
|
+
|
70
70
|
end
|
71
71
|
|
72
72
|
end
|
@@ -3,48 +3,48 @@ require 'helper'
|
|
3
3
|
class TestHttpMethod < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
context "(with Sickill::Rainbow enabled)" do
|
8
|
-
|
8
|
+
|
9
9
|
setup do
|
10
10
|
Sickill::Rainbow.enabled = true
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
should "color-code the HTTP method" do
|
14
|
-
|
14
|
+
|
15
15
|
# read-only methods are never color-coded...
|
16
16
|
log_line = random_log_line(:http_method => 'GET')
|
17
17
|
assert_equal "GET", log_line.to_http_method_s
|
18
|
-
|
19
|
-
# methods that change state are ALWAYS color-coded if Rainbow is enabled...
|
18
|
+
|
19
|
+
# methods that change state are ALWAYS color-coded if Rainbow is enabled...
|
20
20
|
log_line = random_log_line(:http_method => 'POST')
|
21
21
|
assert_not_equal "POST", log_line.to_http_method_s
|
22
22
|
assert_equal "POST".inverse, log_line.to_http_method_s
|
23
|
-
|
23
|
+
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
context "(with Sickill::Rainbow disabled)" do
|
29
29
|
|
30
30
|
setup do
|
31
31
|
Sickill::Rainbow.enabled = false
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
should "NOT color-code the HTTP method" do
|
35
|
-
|
35
|
+
|
36
36
|
# read-only methods are never color-coded...
|
37
37
|
log_line = random_log_line(:http_method => 'GET')
|
38
38
|
assert_equal "GET", log_line.to_http_method_s
|
39
|
-
|
39
|
+
|
40
40
|
# methods that change state are NOT color-coded if Rainbow is disabled...
|
41
41
|
log_line = random_log_line(:http_method => 'POST')
|
42
42
|
assert_equal "POST", log_line.to_http_method_s
|
43
|
-
|
43
|
+
|
44
44
|
end
|
45
|
-
|
45
|
+
|
46
46
|
end
|
47
|
-
|
47
|
+
|
48
48
|
end
|
49
49
|
|
50
|
-
end
|
50
|
+
end
|
@@ -3,17 +3,17 @@ require 'helper'
|
|
3
3
|
class TestHttpReferer < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
setup do
|
8
8
|
@http_referer = "http://example.com/index.html"
|
9
9
|
@log_line = random_log_line(:http_referer => @http_referer)
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
teardown do
|
13
13
|
# undo any changes the test may have made
|
14
14
|
NginxTail::LogLine.reset_internal_referers
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
should "have empty list of internal referers without configuration" do
|
18
18
|
assert NginxTail::LogLine.internal_referers.empty?
|
19
19
|
end
|
@@ -52,13 +52,13 @@ class TestHttpReferer < Test::Unit::TestCase
|
|
52
52
|
assert @log_line.external_referer?
|
53
53
|
|
54
54
|
NginxTail::LogLine.add_internal_referer(/http:\/\/example\.com/)
|
55
|
-
|
55
|
+
|
56
56
|
assert NginxTail::LogLine.internal_referer?(@http_referer)
|
57
57
|
assert !NginxTail::LogLine.external_referer?(@http_referer)
|
58
58
|
assert @log_line.internal_referer?
|
59
59
|
assert !@log_line.external_referer?
|
60
60
|
end
|
61
|
-
|
61
|
+
|
62
62
|
should "parse and format the unknownHTTP referer" do
|
63
63
|
http_referer = NginxTail::HttpReferer::UNKNOWN_REFERER
|
64
64
|
assert_equal http_referer, NginxTail::LogLine.to_referer_s(http_referer)
|
@@ -69,9 +69,9 @@ class TestHttpReferer < Test::Unit::TestCase
|
|
69
69
|
to_referer_s = NginxTail::LogLine.to_referer_s(@http_referer)
|
70
70
|
assert_equal "example.com", to_referer_s
|
71
71
|
# parsed from a raw log line
|
72
|
-
assert_equal "example.com", @log_line.to_referer_s
|
72
|
+
assert_equal "example.com", @log_line.to_referer_s
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
end
|
76
76
|
|
77
77
|
end
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
class TestHttpUserAgent < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
should "correctly identify search bot user agent" do
|
8
8
|
search_bot_user_agent = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
9
9
|
# directly via the helper function
|
@@ -23,7 +23,7 @@ class TestHttpUserAgent < Test::Unit::TestCase
|
|
23
23
|
assert !log_line.search_bot?
|
24
24
|
assert !log_line.to_agent.search_bot?
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
end
|
28
28
|
|
29
29
|
end
|
@@ -15,7 +15,7 @@ class TestKnownIpAddresses < Test::Unit::TestCase
|
|
15
15
|
NginxTail::LogLine.add_known_ip_address(first_ip_address = random_ip_address)
|
16
16
|
assert_equal 1, NginxTail::LogLine.known_ip_addresses.size
|
17
17
|
assert NginxTail::LogLine.known_ip_addresses.include?(first_ip_address)
|
18
|
-
|
18
|
+
|
19
19
|
NginxTail::LogLine.add_known_ip_address(second_ip_address = random_ip_address)
|
20
20
|
assert_equal 2, NginxTail::LogLine.known_ip_addresses.size
|
21
21
|
assert NginxTail::LogLine.known_ip_addresses.include?(second_ip_address)
|
@@ -24,20 +24,20 @@ class TestKnownIpAddresses < Test::Unit::TestCase
|
|
24
24
|
should "avoid duplicates in list of known IP addresses" do
|
25
25
|
NginxTail::LogLine.add_known_ip_address(known_ip_address = random_ip_address)
|
26
26
|
assert_equal 1, NginxTail::LogLine.known_ip_addresses.size
|
27
|
-
|
27
|
+
|
28
28
|
NginxTail::LogLine.add_known_ip_address(known_ip_address)
|
29
29
|
assert_equal 1, NginxTail::LogLine.known_ip_addresses.size
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
should "recognize a known IP address after configuration" do
|
33
33
|
remote_address = random_ip_address
|
34
34
|
log_line = random_log_line(:remote_addr => remote_address)
|
35
|
-
|
35
|
+
|
36
36
|
assert !NginxTail::LogLine.known_ip_address?(remote_address)
|
37
37
|
assert !log_line.known_ip_address?
|
38
|
-
|
38
|
+
|
39
39
|
NginxTail::LogLine.add_known_ip_address(remote_address)
|
40
|
-
|
40
|
+
|
41
41
|
assert NginxTail::LogLine.known_ip_address?(remote_address)
|
42
42
|
assert log_line.known_ip_address?
|
43
43
|
end
|
@@ -15,7 +15,7 @@ class TestLocalIpAddresses < Test::Unit::TestCase
|
|
15
15
|
NginxTail::LogLine.add_local_ip_address(first_ip_address = local_ip_address)
|
16
16
|
assert_equal 1, NginxTail::LogLine.local_ip_addresses.size
|
17
17
|
assert NginxTail::LogLine.local_ip_addresses.include?(first_ip_address)
|
18
|
-
|
18
|
+
|
19
19
|
NginxTail::LogLine.add_local_ip_address(second_ip_address = local_ip_address)
|
20
20
|
assert_equal 2, NginxTail::LogLine.local_ip_addresses.size
|
21
21
|
assert NginxTail::LogLine.local_ip_addresses.include?(second_ip_address)
|
@@ -24,20 +24,20 @@ class TestLocalIpAddresses < Test::Unit::TestCase
|
|
24
24
|
should "avoid duplicates in list of known IP addresses" do
|
25
25
|
NginxTail::LogLine.add_local_ip_address(local_ip_address = local_ip_address)
|
26
26
|
assert_equal 1, NginxTail::LogLine.local_ip_addresses.size
|
27
|
-
|
27
|
+
|
28
28
|
NginxTail::LogLine.add_local_ip_address(local_ip_address)
|
29
29
|
assert_equal 1, NginxTail::LogLine.local_ip_addresses.size
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
should "recognize a known IP address after configuration" do
|
33
33
|
remote_address = local_ip_address
|
34
34
|
log_line = random_log_line(:remote_addr => remote_address)
|
35
|
-
|
35
|
+
|
36
36
|
assert !NginxTail::LogLine.local_ip_address?(remote_address)
|
37
37
|
assert !log_line.local_ip_address?
|
38
|
-
|
38
|
+
|
39
39
|
NginxTail::LogLine.add_local_ip_address(remote_address)
|
40
|
-
|
40
|
+
|
41
41
|
assert NginxTail::LogLine.local_ip_address?(remote_address)
|
42
42
|
assert log_line.local_ip_address?
|
43
43
|
end
|
data/test/ntail/test_log_line.rb
CHANGED
@@ -3,28 +3,28 @@ require 'helper'
|
|
3
3
|
class TestLogLine < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "NginxTail::LogLine" do
|
6
|
-
|
6
|
+
|
7
7
|
should "initialize itself correctly from a parsable log line" do
|
8
8
|
raw_line = random_raw_line
|
9
9
|
log_line = NginxTail::LogLine.new(raw_line)
|
10
10
|
assert_equal raw_line, log_line.raw_line
|
11
11
|
assert log_line.parsable
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
should "initialize itself correctly from a non-parsable log line" do
|
15
15
|
raw_line = "foo bar blegga"
|
16
16
|
log_line = NginxTail::LogLine.new(raw_line)
|
17
17
|
assert_equal raw_line, log_line.raw_line
|
18
18
|
assert !log_line.parsable
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
should "implement non-abbreviated alias for $remote_addr" do
|
22
22
|
remote_addr = random_ip_address
|
23
23
|
log_line = random_log_line(:remote_addr => remote_addr)
|
24
24
|
assert_equal remote_addr, log_line.remote_addr
|
25
25
|
assert_equal remote_addr, log_line.remote_address
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
should "implement a getter method for each (sub-)component" do
|
29
29
|
(NginxTail::LogLine::COMPONENTS + NginxTail::LogLine::SUBCOMPONENTS).each do |component|
|
30
30
|
getter_method = component.to_s
|
@@ -38,7 +38,7 @@ class TestLogLine < Test::Unit::TestCase
|
|
38
38
|
assert !NginxTail::LogLine.instance_methods.map(&:to_s).include?(setter_method), "setter '#{setter_method}' should NOT exist"
|
39
39
|
end
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
should "include an extension module for each (sub-)component" do
|
43
43
|
(NginxTail::LogLine::COMPONENTS + NginxTail::LogLine::SUBCOMPONENTS).each do |component|
|
44
44
|
ntail_module = NginxTail::Inflections.component_to_ntail_module(component)
|
@@ -46,7 +46,7 @@ class TestLogLine < Test::Unit::TestCase
|
|
46
46
|
assert NginxTail::LogLine.included_modules.include?(ntail_module), "module '#{ntail_module.name}' should be included"
|
47
47
|
end
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
end
|
51
51
|
|
52
52
|
end
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
class TestRemoteAddr < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
setup do
|
8
8
|
@remote_addr = "192.0.32.10"
|
9
9
|
@log_line = random_log_line(:remote_addr => @remote_addr)
|
@@ -36,7 +36,7 @@ class TestRemoteAddr < Test::Unit::TestCase
|
|
36
36
|
# parsed from a raw log line
|
37
37
|
assert ["www.example.com", "192.0.32.10"].include? @log_line.to_host_s
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
should "convert the request's remote address into a country string" do
|
41
41
|
return unless File.exists?('/usr/share/GeoIP/GeoIP.dat')
|
42
42
|
# directly via the helper function
|
@@ -45,7 +45,7 @@ class TestRemoteAddr < Test::Unit::TestCase
|
|
45
45
|
# parsed from a raw log line
|
46
46
|
assert_equal "United States", @log_line.to_country_s
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
should "convert the request's remote address into a city string" do
|
50
50
|
return unless File.exists?('/usr/share/GeoIP/GeoIPCity.dat')
|
51
51
|
# directly via the helper function
|
@@ -54,7 +54,7 @@ class TestRemoteAddr < Test::Unit::TestCase
|
|
54
54
|
# parsed from a raw log line
|
55
55
|
assert_equal "Marina Del Rey", @log_line.to_city_s
|
56
56
|
end
|
57
|
-
|
57
|
+
|
58
58
|
end
|
59
59
|
|
60
60
|
end
|
@@ -10,18 +10,18 @@ class TestRemoteUser < Test::Unit::TestCase
|
|
10
10
|
should "have empty list of authenticated users without configuration" do
|
11
11
|
assert NginxTail::LogLine.authenticated_users.empty?
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
should "correctly identify the default/unknown remote user" do
|
15
15
|
unknown_remote_user = NginxTail::RemoteUser::UNKNOWN_REMOTE_USER
|
16
16
|
log_line = random_log_line(:remote_user => unknown_remote_user)
|
17
|
-
|
17
|
+
|
18
18
|
assert NginxTail::LogLine.unknown_remote_user?(unknown_remote_user)
|
19
19
|
assert !NginxTail::LogLine.remote_user?(unknown_remote_user)
|
20
20
|
assert !NginxTail::LogLine.authenticated_user?(unknown_remote_user)
|
21
|
-
|
21
|
+
|
22
22
|
assert log_line.unknown_remote_user?
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
should "not allow the default/unknown remote user to be added" do
|
26
26
|
assert_raise RuntimeError do
|
27
27
|
NginxTail::LogLine.add_authenticated_user(NginxTail::RemoteUser::UNKNOWN_REMOTE_USER)
|
@@ -32,7 +32,7 @@ class TestRemoteUser < Test::Unit::TestCase
|
|
32
32
|
NginxTail::LogLine.add_authenticated_user(first_remote_user = "john_doe")
|
33
33
|
assert_equal 1, NginxTail::LogLine.authenticated_users.size
|
34
34
|
assert NginxTail::LogLine.authenticated_users.include?(first_remote_user)
|
35
|
-
|
35
|
+
|
36
36
|
NginxTail::LogLine.add_authenticated_user(second_referer = "jane_doe")
|
37
37
|
assert_equal 2, NginxTail::LogLine.authenticated_users.size
|
38
38
|
assert NginxTail::LogLine.authenticated_users.include?(second_referer)
|
@@ -41,7 +41,7 @@ class TestRemoteUser < Test::Unit::TestCase
|
|
41
41
|
should "avoid duplicates in list of authenticated users" do
|
42
42
|
NginxTail::LogLine.add_authenticated_user(authenticated_user = "john_doe")
|
43
43
|
assert_equal 1, NginxTail::LogLine.authenticated_users.size
|
44
|
-
|
44
|
+
|
45
45
|
NginxTail::LogLine.add_authenticated_user(authenticated_user)
|
46
46
|
assert_equal 1, NginxTail::LogLine.authenticated_users.size
|
47
47
|
end
|
@@ -54,7 +54,7 @@ class TestRemoteUser < Test::Unit::TestCase
|
|
54
54
|
assert !NginxTail::LogLine.authenticated_user?(remote_user)
|
55
55
|
assert log_line.remote_user?
|
56
56
|
assert !log_line.authenticated_user?
|
57
|
-
|
57
|
+
|
58
58
|
NginxTail::LogLine.add_authenticated_user(remote_user)
|
59
59
|
assert NginxTail::LogLine.remote_user?(remote_user)
|
60
60
|
assert NginxTail::LogLine.authenticated_user?(remote_user)
|
data/test/ntail/test_request.rb
CHANGED
@@ -3,24 +3,24 @@ require 'helper'
|
|
3
3
|
class TestRequest < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
should "do something reasonable for bad requests" do
|
8
|
-
|
8
|
+
|
9
9
|
log_line = bad_request_log_line
|
10
10
|
assert_equal "-", log_line.request
|
11
|
-
|
11
|
+
|
12
12
|
assert_nil log_line.http_method
|
13
13
|
assert_nil log_line.uri
|
14
14
|
assert_nil log_line.http_version
|
15
|
-
|
15
|
+
|
16
16
|
assert_equal "", log_line.to_http_method_s
|
17
17
|
assert_equal "-", log_line.to_uri_s
|
18
18
|
assert_equal "", log_line.to_http_version_s
|
19
|
-
|
19
|
+
|
20
20
|
assert_equal "-", log_line.to_request_s
|
21
|
-
|
21
|
+
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
end
|
25
25
|
|
26
|
-
end
|
26
|
+
end
|
data/test/ntail/test_status.rb
CHANGED
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
class TestStatus < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
should "correctly identify the nginx 499 status code" do
|
8
8
|
status = NginxTail::Status::NGINX_MAGIC_STATUS # 499
|
9
9
|
# directly via the helper function
|
@@ -20,7 +20,7 @@ class TestStatus < Test::Unit::TestCase
|
|
20
20
|
assert !log_line.client_error_status?
|
21
21
|
assert !log_line.server_error_status?
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
end
|
25
25
|
|
26
|
-
end
|
26
|
+
end
|
@@ -3,7 +3,7 @@ require 'helper'
|
|
3
3
|
class TestTimeLocal < Test::Unit::TestCase
|
4
4
|
|
5
5
|
context "ntail" do
|
6
|
-
|
6
|
+
|
7
7
|
setup do
|
8
8
|
@time_local = "13/Apr/2010:04:45:51 +0100"
|
9
9
|
@log_line = random_log_line(:time_local => @time_local)
|
@@ -22,9 +22,9 @@ class TestTimeLocal < Test::Unit::TestCase
|
|
22
22
|
to_date_s = NginxTail::LogLine.to_date_s(@time_local)
|
23
23
|
assert_equal "2010-04-13 04:45:51", to_date_s
|
24
24
|
# parsed from a raw log line
|
25
|
-
assert_equal "2010-04-13 04:45:51", @log_line.to_date_s
|
25
|
+
assert_equal "2010-04-13 04:45:51", @log_line.to_date_s
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
end
|
29
29
|
|
30
|
-
end
|
30
|
+
end
|
data/test/ntail/test_uri.rb
CHANGED
@@ -8,14 +8,14 @@ class TestUri < Test::Unit::TestCase
|
|
8
8
|
# undo any changes the test may have made
|
9
9
|
NginxTail::LogLine.reset_automatic_files
|
10
10
|
end
|
11
|
-
|
11
|
+
|
12
12
|
should "correctly identify a default automatic request" do
|
13
13
|
# directly via the helper function
|
14
14
|
# parsed from a raw log line
|
15
15
|
log_line = random_log_line(:uri => '/index.html')
|
16
|
-
assert !log_line.automatic_uri?
|
16
|
+
assert !log_line.automatic_uri?
|
17
17
|
log_line = random_log_line(:uri => '/robots.txt')
|
18
|
-
assert log_line.automatic_uri?
|
18
|
+
assert log_line.automatic_uri?
|
19
19
|
end
|
20
20
|
|
21
21
|
should "correctly identify a custom automatic request" do
|
@@ -24,9 +24,9 @@ class TestUri < Test::Unit::TestCase
|
|
24
24
|
log_line = random_log_line(:uri => '/blegga.html')
|
25
25
|
assert !log_line.automatic_uri?
|
26
26
|
NginxTail::LogLine.add_automatic_file('blegga.html')
|
27
|
-
assert log_line.automatic_uri?
|
27
|
+
assert log_line.automatic_uri?
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
end
|
31
31
|
|
32
|
-
end
|
32
|
+
end
|
data/test/test_ntail.rb
CHANGED
@@ -5,10 +5,10 @@ class TestNtail < Test::Unit::TestCase
|
|
5
5
|
should "have namespaced classes" do
|
6
6
|
assert_equal "constant", defined? NginxTail
|
7
7
|
assert NginxTail.is_a? Module
|
8
|
-
|
8
|
+
|
9
9
|
assert_equal "constant", defined? NginxTail::LogLine
|
10
10
|
assert NginxTail::LogLine.is_a? Class
|
11
|
-
|
11
|
+
|
12
12
|
assert_equal "constant", defined? NginxTail::Application
|
13
13
|
assert NginxTail::Application.is_a? Class
|
14
14
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ntail
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2014-
|
12
|
+
date: 2014-03-14 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rainbow
|
@@ -294,7 +294,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
294
294
|
version: '0'
|
295
295
|
segments:
|
296
296
|
- 0
|
297
|
-
hash:
|
297
|
+
hash: 1237207687887993838
|
298
298
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
299
299
|
none: false
|
300
300
|
requirements:
|