Class: NginxTail::LogLine
Constant Summary
collapse
- COMPONENTS =
[
:remote_addr,
:remote_user,
:time_local,
:request,
:status,
:body_bytes_sent,
:http_referer,
:http_user_agent,
:proxy_addresses,
]
- SUBCOMPONENTS =
[
:http_method,
:uri,
:http_version,
]
- NGINX_LOG_PATTERN =
Regexp.compile(/\A(\S+) - (\S+) \[([^\]]+)\] "([^"]+)" (\S+) (\S+) "([^"]*?)" "([^"]*?)"( "([^"]*?)")?\Z/)
- NGINX_REQUEST_PATTERN =
Regexp.compile(/\A(\S+) (.*?) (\S+)\Z/)
- NGINX_PROXY_PATTERN =
Regexp.compile(/\A "([^"]*)"\Z/)
- CONVERSIONS =
[
:to_date,
:to_date_s,
:to_agent,
:to_agent_s,
:to_host_name,
:to_refering_website,
:to_country_s,
:to_city_s,
]
- AUTOMATED_REQUESTS =
“GET /xd_receiver.html HTTP/1.1” “GET /crossdomain.xml HTTP/1.1” “GET /favicon.ico HTTP/1.1” “GET /robots.txt HTTP/1.0”
[
Regexp.compile('^[A-Z]+ \/xd_receiver.html'),
Regexp.compile('^[A-Z]+ \/crossdomain.xml'),
Regexp.compile('^[A-Z]+ \/favicon.ico'),
Regexp.compile('^[A-Z]+ \/robots.txt'),
nil
].compact!
- STATIC_REPOS =
subdirectories of the “public” folder in the web root, which - in a typical Rails setup - are served by nginx
%w{
flash
html
images
javascripts
movies
newsletters
pictures
stylesheets
xml
}
- STATIC_URIS =
STATIC_REPOS.map { |repo| Regexp.compile("^\/#{repo}\/") }
- STATIC_REQUESTS =
STATIC_REPOS.map { |repo| Regexp.compile("^[A-Z]+ \/#{repo}\/") }
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
included, #local_ip_address?
included, #known_ip_address?
Constructor Details
#initialize(line) ⇒ LogLine
Returns a new instance of LogLine.
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
|
# File 'lib/ntail/log_line.rb', line 61
def initialize(line)
@parsable = if NGINX_LOG_PATTERN.match(@raw_line = line)
@remote_addr, @remote_user, @time_local, @request, @status, @body_bytes_sent, @http_referer, @http_user_agent, @proxy_addresses = $~.captures
if NGINX_REQUEST_PATTERN.match(@request)
@http_method, @uri, @http_version = $~.captures
end
if @proxy_addresses and NGINX_PROXY_PATTERN.match(@proxy_addresses)
@proxy_addresses = $~.captures.first.split(/, /)
end
true
else
false
end
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *params) ⇒ Object
for now, until we make it fancier…
81
82
83
|
# File 'lib/ntail/log_line.rb', line 81
def method_missing(method, *params)
raw_line.send method, *params
end
|
Instance Attribute Details
#parsable ⇒ Object
Returns the value of attribute parsable.
20
21
22
|
# File 'lib/ntail/log_line.rb', line 20
def parsable
@parsable
end
|
#raw_line ⇒ Object
Returns the value of attribute raw_line.
19
20
21
|
# File 'lib/ntail/log_line.rb', line 19
def raw_line
@raw_line
end
|
Class Method Details
.automated_request?(request) ⇒ Boolean
201
|
# File 'lib/ntail/log_line.rb', line 201
def self.automated_request?(request) !AUTOMATED_REQUESTS.detect { |automated_request_regexp| request.match(automated_request_regexp) }.nil? end
|
.component_to_module_name(component) ⇒ Object
9
10
11
12
|
# File 'lib/ntail/log_line.rb', line 9
def self.component_to_module_name(component)
component.to_s.gsub(/\/(.?)/) { "::#{$1.upcase}" }.gsub(/(?:^|_)(.)/) { $1.upcase }
end
|
.component_to_ntail_module(component) ⇒ Object
14
15
16
17
|
# File 'lib/ntail/log_line.rb', line 14
def self.component_to_ntail_module(component)
NginxTail.const_get(self.component_to_module_name(component))
end
|
.log_component?(component) ⇒ Boolean
126
127
128
129
|
# File 'lib/ntail/log_line.rb', line 126
def self.log_component?(component)
COMPONENTS.include?(component)
end
|
.log_conversion?(conversion) ⇒ Boolean
131
132
133
134
|
# File 'lib/ntail/log_line.rb', line 131
def self.log_conversion?(conversion)
CONVERSIONS.include?(conversion)
end
|
.log_directive?(directive) ⇒ Boolean
136
137
138
|
# File 'lib/ntail/log_line.rb', line 136
def self.log_directive?(directive)
(directive == :full) or log_conversion?(directive) or log_component?(directive) or log_subcomponent?(directive)
end
|
.log_subcomponent?(subcomponent) ⇒ Boolean
121
122
123
124
|
# File 'lib/ntail/log_line.rb', line 121
def self.log_subcomponent?(subcomponent)
SUBCOMPONENTS.include?(subcomponent)
end
|
.regexp_for_http_referer(http_referer) ⇒ Object
156
157
158
|
# File 'lib/ntail/log_line.rb', line 156
def self.regexp_for_http_referer(http_referer)
Regexp.compile(/" .* "([^"]*#{http_referer}[^"]*)" "/)
end
|
.regexp_for_http_user_agent(http_user_agent) ⇒ Object
160
161
162
|
# File 'lib/ntail/log_line.rb', line 160
def self.regexp_for_http_user_agent(http_user_agent)
Regexp.compile(/ "([^"]*#{http_user_agent}[^"]*)"$/)
end
|
.regexp_for_remote_address(remote_address) ⇒ Object
extraction filters for log line components
144
145
146
|
# File 'lib/ntail/log_line.rb', line 144
def self.regexp_for_remote_address(remote_address)
Regexp.compile(/^(#{remote_address}) /)
end
|
.regexp_for_request(request) ⇒ Object
148
149
150
|
# File 'lib/ntail/log_line.rb', line 148
def self.regexp_for_request(request)
Regexp.compile(/^([^"]+) "([^"]*#{request}[^"]*)" /)
end
|
.regexp_for_status(status) ⇒ Object
152
153
154
|
# File 'lib/ntail/log_line.rb', line 152
def self.regexp_for_status(status)
Regexp.compile(/ "([^"]+)" (#{status}) /)
end
|
.static_request?(request) ⇒ Boolean
228
|
# File 'lib/ntail/log_line.rb', line 228
def self.static_request?(request) !STATIC_REQUESTS.detect { |static_request_regexp| request.match(static_request_regexp) }.nil? end
|
.static_uri?(uri) ⇒ Boolean
223
|
# File 'lib/ntail/log_line.rb', line 223
def self.static_uri?(uri) !STATIC_URIS.detect { |static_uri_regexp| uri.match(static_uri_regexp) }.nil? end
|
.valid_referer?(referer) ⇒ Boolean
183
|
# File 'lib/ntail/log_line.rb', line 183
def self.valid_referer?(referer) true ; end
|
.valid_request?(request) ⇒ Boolean
182
|
# File 'lib/ntail/log_line.rb', line 182
def self.valid_request?(request) true ; end
|
.valid_status?(status) ⇒ Boolean
validation of log line components
168
169
170
171
172
173
|
# File 'lib/ntail/log_line.rb', line 168
def self.valid_status?(status)
if /\A(\d{1,3})\Z/ =~ status
return $~.captures.all? { |i| 100 <= i.to_i and i.to_i < 600 }
end
return false
end
|
.valid_user_agent?(user_agent) ⇒ Boolean
184
|
# File 'lib/ntail/log_line.rb', line 184
def self.valid_user_agent?(user_agent) true ; end
|
.valid_v4?(addr) ⇒ Boolean
175
176
177
178
179
180
|
# File 'lib/ntail/log_line.rb', line 175
def self.valid_v4?(addr)
if /\A(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\Z/ =~ addr
return $~.captures.all? {|i| i.to_i < 256}
end
return false
end
|
Instance Method Details
#automated_request? ⇒ Boolean
202
|
# File 'lib/ntail/log_line.rb', line 202
def automated_request?() self.class.automated_request?(self.request) ; end
|
#static_request? ⇒ Boolean
229
|
# File 'lib/ntail/log_line.rb', line 229
def static_request?() self.class.static_request?(self.request) ; end
|
#static_uri? ⇒ Boolean
224
|
# File 'lib/ntail/log_line.rb', line 224
def static_uri?() self.class.static_uri?(self.uri); end
|
#to_s ⇒ Object
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
# File 'lib/ntail/log_line.rb', line 85
def to_s()
color = if redirect_status?
:yellow
elsif !success_status?
:red
else
:default
end
"%s - %#{Sickill::Rainbow.enabled ? 15 + 9 : 15}s - %s - %s - %s - %s" % [
to_date_s.foreground(color),
remote_address.foreground(color),
status.foreground(color),
to_request_s.foreground(color),
to_agent_s.foreground(color),
to_referer_s.foreground(color).inverse
]
end
|