Class: Racknga::NginxAccessLogParser

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/racknga/nginx_access_log_parser.rb

Overview

Supported formats:

* combined (default format)
* combined_with_time (custom format for Passenger)

Configurations in nginx:

* combined
  log_format combined '$remote_addr - $remote_user [$time_local]  '
                      '"$request" $status $body_bytes_sent '
                      '"$http_referer" "$http_user_agent"';
  access_log log/access.log combined

* combined_with_time
  log_format combined_with_time '$remote_addr - $remote_user '
                                '[$time_local, $upstream_http_x_runtime, $request_time]  '
                                '"$request" $status $body_bytes_sent '
                                '"$http_referer" "$http_user_agent"';
  access_log log/access.log combined_with_time

Direct Known Subclasses

ReversedNginxAccessLogParser

Defined Under Namespace

Classes: FormatError

Constant Summary collapse

REMOTE_ADDRESS =
'(?:\d{1,3}\.){3}\d{1,3}'
REMOTE_USER =
'[^ ]+'
TIME_LOCAL =
'[^ ]+ \+\d{4}'
RUNTIME =
'(?:[\d.]+|-)'
REQUEST_TIME =
'[\d.]+'
REQUEST =
'.*?'
STATUS =
'\d{3}'
BODY_BYTES_SENT =
'\d+'
HTTP_REFERER =
'.*?'
HTTP_USER_AGENT =

'(?:\\"|[^\"])*?'
LOG_FORMAT =
/\A(#{REMOTE_ADDRESS}) - (#{REMOTE_USER}) \[(#{TIME_LOCAL})(?:, (#{RUNTIME}), (#{REQUEST_TIME}))?\]  "(#{REQUEST})" (#{STATUS}) (#{BODY_BYTES_SENT}) "(#{HTTP_REFERER})" "(#{HTTP_USER_AGENT})"\n\z/

Instance Method Summary collapse

Constructor Details

#initialize(line_reader) ⇒ NginxAccessLogParser

Returns a new instance of NginxAccessLogParser.



45
46
47
# File 'lib/racknga/nginx_access_log_parser.rb', line 45

def initialize(line_reader)
  @line_reader = line_reader
end

Instance Method Details

#eachObject



49
50
51
52
53
54
# File 'lib/racknga/nginx_access_log_parser.rb', line 49

def each
  @line_reader.each do |line|
    line.force_encoding("UTF-8")
    yield(parse_line(line)) if line.valid_encoding?
  end
end

#parse_line(line) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/racknga/nginx_access_log_parser.rb', line 68

def parse_line(line)
  if line =~ LOG_FORMAT
    last_match = Regexp.last_match
    options = {}
    options[:remote_address] = last_match[1]
    options[:remote_user] = last_match[2]
    parse_time_local(last_match[3], options)
    options[:runtime] = last_match[4].to_f
    options[:request_time] = last_match[5].to_f
    options[:request] = last_match[6]
    options[:status] = last_match[7].to_i
    options[:body_bytes_sent] = last_match[8].to_i
    options[:http_referer] = last_match[9]
    options[:http_user_agent] = last_match[10]
    LogEntry.new(options)
  else
    raise FormatError.new("ill-formatted log entry: #{line.inspect} !~ #{LOG_FORMAT}")
  end
end

#parse_time_local(token, options) ⇒ Object



88
89
90
91
# File 'lib/racknga/nginx_access_log_parser.rb', line 88

def parse_time_local(token, options)
  day, month, year, hour, minute, second, _time_zone = token.split(/[\/: ]/)
  options[:time_local] = Time.local(year, month, day, hour, minute, second)
end