ntail 0.0.11 → 0.0.12
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +5 -0
- data/Gemfile.lock +37 -4
- data/README.md +158 -0
- data/Rakefile +24 -11
- data/VERSION +1 -1
- data/bin/ntail +1 -1
- data/lib/ntail/application.rb +74 -97
- data/lib/ntail/body_bytes_sent.rb +2 -2
- data/lib/ntail/formatting.rb +157 -44
- data/lib/ntail/formatting.treetop +44 -15
- data/lib/ntail/http_method.rb +2 -2
- data/lib/ntail/http_referer.rb +2 -2
- data/lib/ntail/http_user_agent.rb +3 -1
- data/lib/ntail/http_version.rb +20 -5
- data/lib/ntail/known_ip_addresses.rb +2 -2
- data/lib/ntail/local_ip_addresses.rb +2 -2
- data/lib/ntail/log_line.rb +90 -42
- data/lib/ntail/node.rb +3 -0
- data/lib/ntail/options.rb +82 -0
- data/lib/ntail/proxy_addresses.rb +2 -2
- data/lib/ntail/remote_addr.rb +2 -2
- data/lib/ntail/remote_user.rb +2 -2
- data/lib/ntail/request.rb +2 -2
- data/lib/ntail/status.rb +1 -1
- data/lib/ntail/time_local.rb +2 -2
- data/lib/ntail/uri.rb +8 -1
- data/lib/ntail.rb +18 -3
- data/ntail.gemspec +29 -6
- data/spec/application_spec.rb +23 -0
- data/spec/spec_helper.rb +9 -0
- data/test/helper.rb +4 -1
- data/test/ntail/test_formatting.rb +72 -0
- data/test/ntail/test_http_version.rb +36 -0
- data/test/ntail/test_log_line.rb +5 -4
- data/test/ntail/test_remote_addr.rb +25 -3
- data/test/test_ntail.rb +7 -0
- metadata +125 -43
- data/README.rdoc +0 -99
data/lib/ntail/log_line.rb
CHANGED
@@ -6,34 +6,47 @@ require 'rainbow'
|
|
6
6
|
module NginxTail
|
7
7
|
class LogLine
|
8
8
|
|
9
|
-
def self.component_to_module_name(component)
|
10
|
-
# this mimicks the ActiveSupport::Inflector.camelize() method in Rails...
|
11
|
-
component.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
12
|
-
end
|
13
|
-
|
14
|
-
def self.component_to_ntail_module(component)
|
15
|
-
# this mimicks the ActiveSupport::Inflector.constantize() method in Rails...
|
16
|
-
NginxTail.const_get(self.component_to_module_name(component))
|
17
|
-
end
|
18
|
-
|
19
9
|
attr_reader :raw_line
|
20
10
|
attr_reader :parsable
|
11
|
+
attr_reader :filename
|
12
|
+
attr_reader :line_number
|
13
|
+
|
14
|
+
COMPONENTS = [ # formatting token:
|
15
|
+
|
16
|
+
# NGINX
|
17
|
+
|
18
|
+
:remote_addr, # %a
|
19
|
+
:remote_user, # %u
|
20
|
+
:time_local, # %t
|
21
|
+
:request, # %r
|
22
|
+
:status, # %s
|
23
|
+
:body_bytes_sent, # %b
|
24
|
+
:http_referer, # %R
|
25
|
+
:http_user_agent, # %U
|
26
|
+
:proxy_addresses, # %p
|
27
|
+
|
28
|
+
# APACHE
|
29
|
+
|
30
|
+
:server_name, # %V
|
31
|
+
# :remote_addr, # %h
|
32
|
+
:remote_log_name, # %l
|
33
|
+
# :remote_user, # %u
|
34
|
+
# :time_local, # %t
|
35
|
+
# :request, # %r
|
36
|
+
# :status, # %s
|
37
|
+
# :body_bytes_sent, # %b
|
38
|
+
# :http_referer, # %%{Referer}i
|
39
|
+
# :http_user_agent, # %%{User-agent}i
|
40
|
+
:http_cookie, # %{Cookie}i
|
41
|
+
:time_taken, # %D
|
21
42
|
|
22
|
-
COMPONENTS = [
|
23
|
-
:remote_addr,
|
24
|
-
:remote_user,
|
25
|
-
:time_local,
|
26
|
-
:request,
|
27
|
-
:status,
|
28
|
-
:body_bytes_sent,
|
29
|
-
:http_referer,
|
30
|
-
:http_user_agent,
|
31
|
-
:proxy_addresses,
|
32
43
|
]
|
33
|
-
|
44
|
+
|
34
45
|
COMPONENTS.each do |symbol|
|
35
46
|
attr_reader symbol
|
36
|
-
|
47
|
+
if (module_for_symbol = Inflections.component_to_ntail_module(symbol))
|
48
|
+
include module_for_symbol
|
49
|
+
end
|
37
50
|
end
|
38
51
|
|
39
52
|
include KnownIpAddresses # module to identify known IP addresses
|
@@ -44,23 +57,47 @@ module NginxTail
|
|
44
57
|
:uri,
|
45
58
|
:http_version,
|
46
59
|
]
|
47
|
-
|
60
|
+
|
48
61
|
SUBCOMPONENTS.each do |symbol|
|
49
62
|
attr_reader symbol
|
50
|
-
include component_to_ntail_module(symbol)
|
63
|
+
include Inflections.component_to_ntail_module(symbol)
|
51
64
|
end
|
52
65
|
|
66
|
+
#
|
67
|
+
# http://httpd.apache.org/docs/2.0/mod/mod_log_config.html - we currently only support the following custom log format...
|
68
|
+
#
|
69
|
+
# "%V %h %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" \"%{Cookie}i\" %I %O %D %{deflate_ratio}n%%"
|
70
|
+
#
|
71
|
+
|
72
|
+
APACHE_LOG_PATTERN = Regexp.compile(/\A([\S]*) ([\S]+) ([\S]+|-) ([\S]+|-) \[([^\]]+)\] "(.*)" ([\d]+) ([\d]+|-) "(.*?)" "(.*?)" "(.*?)" [\d]+ [\d]+ ([\d]+) .*\Z/)
|
73
|
+
|
53
74
|
#
|
54
75
|
# http://wiki.nginx.org/NginxHttpLogModule#log_format - we currently only support the default "combined" log format...
|
55
76
|
#
|
56
77
|
|
57
78
|
NGINX_LOG_PATTERN = Regexp.compile(/\A(\S+) - (\S+) \[([^\]]+)\] "([^"]+)" (\S+) (\S+) "([^"]*?)" "([^"]*?)"( "([^"]*?)")?\Z/)
|
79
|
+
|
80
|
+
#
|
81
|
+
# the actual pattern used for line matching, either nginx (default) or apache
|
82
|
+
#
|
83
|
+
|
84
|
+
@@log_pattern = NGINX_LOG_PATTERN
|
85
|
+
|
86
|
+
def self.set_log_pattern(nginx_format)
|
87
|
+
@@log_pattern = nginx_format ? NGINX_LOG_PATTERN : APACHE_LOG_PATTERN
|
88
|
+
end
|
89
|
+
|
58
90
|
NGINX_REQUEST_PATTERN = Regexp.compile(/\A(\S+) (.*?) (\S+)\Z/)
|
59
91
|
NGINX_PROXY_PATTERN = Regexp.compile(/\A "([^"]*)"\Z/)
|
60
92
|
|
61
|
-
def initialize(line)
|
62
|
-
@
|
63
|
-
|
93
|
+
def initialize(line, filename = nil, line_number = nil)
|
94
|
+
@filename = filename ; @line_number = line_number
|
95
|
+
@parsable = if @@log_pattern.match(@raw_line = line)
|
96
|
+
if @@log_pattern == NGINX_LOG_PATTERN
|
97
|
+
@remote_addr, @remote_user, @time_local, @request, @status, @body_bytes_sent, @http_referer, @http_user_agent, @proxy_addresses = $~.captures
|
98
|
+
elsif @@log_pattern == APACHE_LOG_PATTERN
|
99
|
+
@server_name, @remote_addr, @remote_log_name, @remote_user, @time_local, @request, @status, @body_bytes_sent, @http_referer, @http_user_agent, @http_cookie, @time_taken = $~.captures
|
100
|
+
end
|
64
101
|
if NGINX_REQUEST_PATTERN.match(@request)
|
65
102
|
# counter example (ie. HTTP request that cannot by parsed)
|
66
103
|
# 91.203.96.51 - - [21/Dec/2010:05:26:53 +0000] "-" 400 0 "-" "-"
|
@@ -74,35 +111,46 @@ module NginxTail
|
|
74
111
|
false
|
75
112
|
end
|
76
113
|
end
|
77
|
-
|
114
|
+
|
78
115
|
alias_method :remote_address, :remote_addr # a non-abbreviated alias, for convenience and readability...
|
79
|
-
|
116
|
+
|
80
117
|
# for now, until we make it fancier...
|
81
118
|
def method_missing(method, *params)
|
82
119
|
raw_line.send method, *params
|
83
120
|
end
|
84
|
-
|
121
|
+
|
85
122
|
@@parser = FormattingParser.new
|
86
|
-
|
87
|
-
|
123
|
+
|
124
|
+
@@result = @@format = nil
|
125
|
+
|
126
|
+
def self.format= format
|
127
|
+
unless @@result = @@parser.parse(@@format = format)
|
128
|
+
raise @@parser.terminal_failures.join("\n")
|
129
|
+
else
|
130
|
+
def @@result.value(log_line, color)
|
131
|
+
elements.map { |element| element.value(log_line, color) }.join
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
self.format = "%t - %a - %s - %r - %U - %R"
|
137
|
+
|
138
|
+
def to_s(options = {})
|
139
|
+
|
88
140
|
# simple but boring:
|
89
141
|
# raw_line.to_s
|
90
|
-
|
142
|
+
|
143
|
+
# a bit less boring:
|
144
|
+
color = options[:color] && if redirect_status?
|
91
145
|
:yellow
|
92
146
|
elsif !success_status?
|
93
147
|
:red
|
94
148
|
else
|
95
149
|
:default
|
96
150
|
end
|
97
|
-
|
98
|
-
|
99
|
-
else
|
100
|
-
def result.value(log_line, color)
|
101
|
-
elements.map { |element| element.value(log_line, color) }.join
|
102
|
-
end
|
103
|
-
end
|
104
|
-
result.value(self, color)
|
151
|
+
@@result.value(self, color)
|
152
|
+
|
105
153
|
end
|
106
|
-
|
154
|
+
|
107
155
|
end # class LogLine
|
108
156
|
end # module NginxTail
|
data/lib/ntail/node.rb
CHANGED
@@ -0,0 +1,82 @@
|
|
1
|
+
module NginxTail
|
2
|
+
module Options
|
3
|
+
|
4
|
+
def parse_options(argv, defaults = {})
|
5
|
+
|
6
|
+
options = OpenStruct.new(defaults)
|
7
|
+
|
8
|
+
OptionParser.new do |opts|
|
9
|
+
|
10
|
+
opts.banner = "Usage: ntail {options} {file(s)}"
|
11
|
+
opts.separator ""
|
12
|
+
opts.separator "Options are ..."
|
13
|
+
|
14
|
+
opts.on '--verbose', '-v', "Run verbosely (log messages to STDERR)." do |value|
|
15
|
+
options.verbose = true
|
16
|
+
end
|
17
|
+
|
18
|
+
opts.on '--filter', '-f CODE', "Ruby code block for filtering (parsed) lines - needs to return true or false." do |value|
|
19
|
+
options.filter = value
|
20
|
+
end
|
21
|
+
|
22
|
+
opts.on '--execute', '-e CODE', "Ruby code block for processing each (parsed) line." do |value|
|
23
|
+
options.code = value
|
24
|
+
end
|
25
|
+
|
26
|
+
opts.on '--line-number', '-l LINE_NUMBER', "Only process the line with the given line number" do |value|
|
27
|
+
options.line_number = value.to_i
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on '--dry-run', '-n', "Dry-run: process files, but don't actually parse the lines" do |value|
|
31
|
+
options.dry_run = true
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on '--parse-only', '-p', "Parse only: parse all lines, but don't actually process them" do |value|
|
35
|
+
options.parse_only = true
|
36
|
+
end
|
37
|
+
|
38
|
+
opts.on '--raw', '-r', "Parse lines, and - for parseable ones - print out the raw input" do |value|
|
39
|
+
options.raw = true
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on '--apache', "Try to match lines using the Apache log format instead of nginx (the default)" do |value|
|
43
|
+
options.nginx = false
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on '--sleep [SECONDS]', '-s', Float, "Sleeps for the given number of seconds before processing the next line (--raw only)" do |value|
|
47
|
+
options.sleep = value
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on '--progress', '-p', String, "In-flight progress animation during parsing" do |value|
|
51
|
+
unless $stdout.tty?
|
52
|
+
Sickill::Rainbow.enabled = true
|
53
|
+
options.progress = true
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
opts.on '--static-repo [REPO]', String, "Add [REPO] to the list of static repos" do |value|
|
58
|
+
NginxTail::LogLine.add_static_repo(value)
|
59
|
+
end
|
60
|
+
|
61
|
+
opts.on '--persist', '-P', String, "Persist the parsed lines for future use" do |value|
|
62
|
+
options.persist = true
|
63
|
+
end
|
64
|
+
|
65
|
+
opts.on '--version', '-V', "Display the program version." do |value|
|
66
|
+
puts "#{NTAIL_NAME}, version #{NTAIL_VERSION}"
|
67
|
+
options.running = false
|
68
|
+
end
|
69
|
+
|
70
|
+
opts.on_tail("-h", "--help", "-H", "Display this help message.") do
|
71
|
+
puts opts
|
72
|
+
options.running = false
|
73
|
+
end
|
74
|
+
|
75
|
+
end.parse!(argv)
|
76
|
+
|
77
|
+
return options
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
end # module Options
|
82
|
+
end # module NginxTail
|
@@ -5,10 +5,10 @@ module NginxTail
|
|
5
5
|
base.class_eval do
|
6
6
|
|
7
7
|
# this ensures the below module methods actually make sense...
|
8
|
-
raise "Class #{base.name} should implement instance method 'proxy_addresses'" unless base.instance_methods.include? 'proxy_addresses'
|
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
|
-
end
|
14
|
+
end
|
data/lib/ntail/remote_addr.rb
CHANGED
@@ -35,7 +35,7 @@ module NginxTail
|
|
35
35
|
end
|
36
36
|
|
37
37
|
# this ensures the below module methods actually make sense...
|
38
|
-
raise "Class #{base.name} should implement instance method 'remote_addr'" unless base.instance_methods.include? 'remote_addr'
|
38
|
+
raise "Class #{base.name} should implement instance method 'remote_addr'" unless base.instance_methods.map(&:to_s).include? 'remote_addr'
|
39
39
|
|
40
40
|
end
|
41
41
|
end
|
@@ -53,4 +53,4 @@ module NginxTail
|
|
53
53
|
end
|
54
54
|
|
55
55
|
end
|
56
|
-
end
|
56
|
+
end
|
data/lib/ntail/remote_user.rb
CHANGED
@@ -42,7 +42,7 @@ module NginxTail
|
|
42
42
|
end
|
43
43
|
|
44
44
|
# this ensures the below module methods actually make sense...
|
45
|
-
raise "Class #{base.name} should implement instance method 'remote_user'" unless base.instance_methods.include? 'remote_user'
|
45
|
+
raise "Class #{base.name} should implement instance method 'remote_user'" unless base.instance_methods.map(&:to_s).include? 'remote_user'
|
46
46
|
|
47
47
|
end
|
48
48
|
end
|
@@ -60,4 +60,4 @@ module NginxTail
|
|
60
60
|
end
|
61
61
|
|
62
62
|
end
|
63
|
-
end
|
63
|
+
end
|
data/lib/ntail/request.rb
CHANGED
@@ -11,7 +11,7 @@ module NginxTail
|
|
11
11
|
end
|
12
12
|
|
13
13
|
# this ensures the below module methods actually make sense...
|
14
|
-
raise "Class #{base.name} should implement instance method 'request'" unless base.instance_methods.include? 'request'
|
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
|
@@ -30,4 +30,4 @@ module NginxTail
|
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
33
|
-
end
|
33
|
+
end
|
data/lib/ntail/status.rb
CHANGED
@@ -37,7 +37,7 @@ module NginxTail
|
|
37
37
|
end
|
38
38
|
|
39
39
|
# this ensures the below module methods actually make sense...
|
40
|
-
raise "Class #{base.name} should implement instance method 'status'" unless base.instance_methods.include? 'status'
|
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
|
data/lib/ntail/time_local.rb
CHANGED
@@ -21,7 +21,7 @@ module NginxTail
|
|
21
21
|
end
|
22
22
|
|
23
23
|
# this ensures the below module methods actually make sense...
|
24
|
-
raise "Class #{base.name} should implement instance method 'time_local'" unless base.instance_methods.include? 'time_local'
|
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
|
@@ -35,4 +35,4 @@ module NginxTail
|
|
35
35
|
end
|
36
36
|
|
37
37
|
end
|
38
|
-
end
|
38
|
+
end
|
data/lib/ntail/uri.rb
CHANGED
@@ -64,15 +64,22 @@ module NginxTail
|
|
64
64
|
html
|
65
65
|
images
|
66
66
|
javascripts
|
67
|
+
js
|
67
68
|
movies
|
68
69
|
newsletters
|
69
70
|
pictures
|
70
71
|
stylesheets
|
72
|
+
css
|
71
73
|
xml
|
72
74
|
}
|
73
75
|
|
74
76
|
@@static_uris = @@static_repos.map { |repo| Regexp.compile("^\/#{repo}\/") }
|
75
77
|
|
78
|
+
def self.add_static_repo(repo)
|
79
|
+
# TODO make this DRY...
|
80
|
+
@@static_uris << Regexp.compile("^\/#{repo}\/")
|
81
|
+
end
|
82
|
+
|
76
83
|
def self.static_uri?(uri)
|
77
84
|
!@@static_uris.detect { |static_uri_regexp| uri.match(static_uri_regexp) }.nil?
|
78
85
|
end
|
@@ -82,7 +89,7 @@ module NginxTail
|
|
82
89
|
end
|
83
90
|
|
84
91
|
# this ensures the below module methods actually make sense...
|
85
|
-
raise "Class #{base.name} should implement instance method 'uri'" unless base.instance_methods.include? 'uri'
|
92
|
+
raise "Class #{base.name} should implement instance method 'uri'" unless base.instance_methods.map(&:to_s).include? 'uri'
|
86
93
|
|
87
94
|
end
|
88
95
|
end
|
data/lib/ntail.rb
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
NTAIL_NAME = 'ntail'
|
2
2
|
NTAIL_VERSION = '0.0.1'
|
3
3
|
|
4
|
+
# module methods to be used as functions...
|
5
|
+
module NginxTail
|
6
|
+
module Inflections
|
7
|
+
def self.component_to_module_name(component)
|
8
|
+
# this mimicks the ActiveSupport::Inflector.camelize() method in Rails...
|
9
|
+
component.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
|
10
|
+
end
|
11
|
+
def self.component_to_ntail_module(component)
|
12
|
+
# this mimicks the ActiveSupport::Inflector.constantize() method in Rails...
|
13
|
+
NginxTail.const_get(self.component_to_module_name(component)) rescue nil
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
4
18
|
# so-called components...
|
5
19
|
require 'ntail/remote_addr'
|
6
20
|
require 'ntail/remote_user'
|
@@ -26,7 +40,8 @@ require 'ntail/node.rb'
|
|
26
40
|
require 'ntail/formatting.rb'
|
27
41
|
|
28
42
|
# the core classes...
|
29
|
-
require 'ntail/log_line'
|
30
|
-
require 'ntail/
|
43
|
+
require 'ntail/log_line.rb'
|
44
|
+
require 'ntail/options.rb'
|
45
|
+
require 'ntail/application.rb'
|
31
46
|
|
32
|
-
# That's all, Folks!
|
47
|
+
# That's all, Folks!
|
data/ntail.gemspec
CHANGED
@@ -5,25 +5,25 @@
|
|
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.12"
|
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-
|
12
|
+
s.date = %q{2011-08-08}
|
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}
|
16
16
|
s.executables = ["ntail"]
|
17
17
|
s.extra_rdoc_files = [
|
18
18
|
"LICENSE.txt",
|
19
|
-
"README.
|
19
|
+
"README.md"
|
20
20
|
]
|
21
21
|
s.files = [
|
22
22
|
".document",
|
23
23
|
"Gemfile",
|
24
24
|
"Gemfile.lock",
|
25
25
|
"LICENSE.txt",
|
26
|
-
"README.
|
26
|
+
"README.md",
|
27
27
|
"Rakefile",
|
28
28
|
"VERSION",
|
29
29
|
"bin/ntail",
|
@@ -40,6 +40,7 @@ Gem::Specification.new do |s|
|
|
40
40
|
"lib/ntail/local_ip_addresses.rb",
|
41
41
|
"lib/ntail/log_line.rb",
|
42
42
|
"lib/ntail/node.rb",
|
43
|
+
"lib/ntail/options.rb",
|
43
44
|
"lib/ntail/proxy_addresses.rb",
|
44
45
|
"lib/ntail/remote_addr.rb",
|
45
46
|
"lib/ntail/remote_user.rb",
|
@@ -48,10 +49,14 @@ Gem::Specification.new do |s|
|
|
48
49
|
"lib/ntail/time_local.rb",
|
49
50
|
"lib/ntail/uri.rb",
|
50
51
|
"ntail.gemspec",
|
52
|
+
"spec/application_spec.rb",
|
53
|
+
"spec/spec_helper.rb",
|
51
54
|
"test/helper.rb",
|
55
|
+
"test/ntail/test_formatting.rb",
|
52
56
|
"test/ntail/test_http_method.rb",
|
53
57
|
"test/ntail/test_http_referer.rb",
|
54
58
|
"test/ntail/test_http_user_agent.rb",
|
59
|
+
"test/ntail/test_http_version.rb",
|
55
60
|
"test/ntail/test_known_ip_addresses.rb",
|
56
61
|
"test/ntail/test_local_ip_addresses.rb",
|
57
62
|
"test/ntail/test_log_line.rb",
|
@@ -66,13 +71,17 @@ Gem::Specification.new do |s|
|
|
66
71
|
s.homepage = %q{http://github.com/pvdb/ntail}
|
67
72
|
s.licenses = ["MIT"]
|
68
73
|
s.require_paths = ["lib"]
|
69
|
-
s.rubygems_version = %q{1.
|
74
|
+
s.rubygems_version = %q{1.5.2}
|
70
75
|
s.summary = %q{A tail(1)-like utility for nginx log files}
|
71
76
|
s.test_files = [
|
77
|
+
"spec/application_spec.rb",
|
78
|
+
"spec/spec_helper.rb",
|
72
79
|
"test/helper.rb",
|
80
|
+
"test/ntail/test_formatting.rb",
|
73
81
|
"test/ntail/test_http_method.rb",
|
74
82
|
"test/ntail/test_http_referer.rb",
|
75
83
|
"test/ntail/test_http_user_agent.rb",
|
84
|
+
"test/ntail/test_http_version.rb",
|
76
85
|
"test/ntail/test_known_ip_addresses.rb",
|
77
86
|
"test/ntail/test_local_ip_addresses.rb",
|
78
87
|
"test/ntail/test_log_line.rb",
|
@@ -86,37 +95,51 @@ Gem::Specification.new do |s|
|
|
86
95
|
]
|
87
96
|
|
88
97
|
if s.respond_to? :specification_version then
|
89
|
-
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
90
98
|
s.specification_version = 3
|
91
99
|
|
92
100
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
93
101
|
s.add_runtime_dependency(%q<rainbow>, [">= 0"])
|
94
102
|
s.add_runtime_dependency(%q<user-agent>, [">= 0"])
|
95
103
|
s.add_runtime_dependency(%q<treetop>, ["~> 1.4.9"])
|
104
|
+
s.add_runtime_dependency(%q<sequel>, [">= 0"])
|
105
|
+
s.add_runtime_dependency(%q<mongoid>, [">= 0"])
|
106
|
+
s.add_runtime_dependency(%q<sqlite3-ruby>, [">= 0"])
|
107
|
+
s.add_development_dependency(%q<rake>, [">= 0.9.2"])
|
96
108
|
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
97
109
|
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
98
110
|
s.add_development_dependency(%q<jeweler>, ["~> 1.5.1"])
|
99
111
|
s.add_development_dependency(%q<rcov>, [">= 0"])
|
100
112
|
s.add_development_dependency(%q<geoip>, [">= 0"])
|
113
|
+
s.add_development_dependency(%q<rspec>, [">= 2.5"])
|
101
114
|
else
|
102
115
|
s.add_dependency(%q<rainbow>, [">= 0"])
|
103
116
|
s.add_dependency(%q<user-agent>, [">= 0"])
|
104
117
|
s.add_dependency(%q<treetop>, ["~> 1.4.9"])
|
118
|
+
s.add_dependency(%q<sequel>, [">= 0"])
|
119
|
+
s.add_dependency(%q<mongoid>, [">= 0"])
|
120
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
121
|
+
s.add_dependency(%q<rake>, [">= 0.9.2"])
|
105
122
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
106
123
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
107
124
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
108
125
|
s.add_dependency(%q<rcov>, [">= 0"])
|
109
126
|
s.add_dependency(%q<geoip>, [">= 0"])
|
127
|
+
s.add_dependency(%q<rspec>, [">= 2.5"])
|
110
128
|
end
|
111
129
|
else
|
112
130
|
s.add_dependency(%q<rainbow>, [">= 0"])
|
113
131
|
s.add_dependency(%q<user-agent>, [">= 0"])
|
114
132
|
s.add_dependency(%q<treetop>, ["~> 1.4.9"])
|
133
|
+
s.add_dependency(%q<sequel>, [">= 0"])
|
134
|
+
s.add_dependency(%q<mongoid>, [">= 0"])
|
135
|
+
s.add_dependency(%q<sqlite3-ruby>, [">= 0"])
|
136
|
+
s.add_dependency(%q<rake>, [">= 0.9.2"])
|
115
137
|
s.add_dependency(%q<shoulda>, [">= 0"])
|
116
138
|
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
117
139
|
s.add_dependency(%q<jeweler>, ["~> 1.5.1"])
|
118
140
|
s.add_dependency(%q<rcov>, [">= 0"])
|
119
141
|
s.add_dependency(%q<geoip>, [">= 0"])
|
142
|
+
s.add_dependency(%q<rspec>, [">= 2.5"])
|
120
143
|
end
|
121
144
|
end
|
122
145
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe NginxTail::Application do
|
4
|
+
|
5
|
+
%w{ exit running interrupted }.each do |option|
|
6
|
+
it "should respond to #{option} option method" do
|
7
|
+
NginxTail::Application.new.should respond_to(option.to_sym)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
it "has a default 'exit' value of 0" do
|
12
|
+
NginxTail::Application.new.exit.should eq(0)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "has a default 'running' value of true" do
|
16
|
+
NginxTail::Application.new.running.should eq(true)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "has a default 'interrupted' value of false" do
|
20
|
+
NginxTail::Application.new.interrupted.should eq(false)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/test/helper.rb
CHANGED
@@ -12,6 +12,7 @@ require 'shoulda'
|
|
12
12
|
|
13
13
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
14
14
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
15
|
+
|
15
16
|
require 'ntail'
|
16
17
|
|
17
18
|
class Test::Unit::TestCase
|
@@ -50,7 +51,8 @@ class Test::Unit::TestCase
|
|
50
51
|
:status => 200,
|
51
52
|
:body_bytes_sent => 6918,
|
52
53
|
:http_referer => 'http://www.google.com/search?q=example',
|
53
|
-
: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'
|
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
|
+
:proxy_addresses => nil
|
54
56
|
}
|
55
57
|
|
56
58
|
REQUEST_FORMAT = '%s %s %s'
|
@@ -71,6 +73,7 @@ class Test::Unit::TestCase
|
|
71
73
|
options[:body_bytes_sent],
|
72
74
|
options[:http_referer],
|
73
75
|
options[:http_user_agent],
|
76
|
+
# TODO implement support for :proxy_addresses
|
74
77
|
]
|
75
78
|
end
|
76
79
|
|