Class: Logeater::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/logeater/parser.rb,
lib/logeater/parser_errors.rb

Defined Under Namespace

Classes: Error, MalformedParameters, MalformedTimestamp, ParserNotImplemented, UnmatchedLine

Constant Summary collapse

LINE_MATCHER =
/^
  [A-Z],\s
\[(?<timestamp>[^\s\]]+)(?:\s[^\]]*)?\]\s+
  (?<log_level>[A-Z]+)\s+\-\-\s:\s+
  (?<message>.*)
$/x.freeze
REQUEST_LINE_MATCHER =
/^
\[(?<subdomain>[^\]]+)\]\s
\[(?<uuid>[\w\-]{36})\]\s+
 (?:\[(?:guest|user\.(?<user_id>\d+)(?<tester_bar>:cph)?)\]\s+)?
  (?<message>.*)
$/x.freeze
REQUEST_STARTED_MATCHER =
/^
  Started\s
  (?<http_method>[A-Z]+)\s
 "(?<path>[^"]+)"\sfor\s
  (?<remote_ip>[\d\.]+)
/x.freeze
REQUEST_CONTROLLER_MATCHER =
/^
  Processing\sby\s
  (?<controller>[A-Za-z0-9:]+)\#
  (?<action>[a-z_0-9]+)\sas\s
  (?<format>.*)
/x.freeze
REQUEST_PARAMETERS_MATCHER =
/^
  Parameters:\s
  (?<params>\{.*\})
$/x.freeze
REQUEST_COMPLETED_MATCHER =
/^
  Completed\s
  (?<http_status>\d\d\d)\s
  (?:(?<http_response>.*)\s)?in\s
  (?<duration>[\d\.]+)(?<units>ms)\b
/x.freeze

Instance Method Summary collapse

Constructor Details

#initializeParser

Returns a new instance of Parser.



132
133
134
135
136
137
138
139
140
# File 'lib/logeater/parser.rb', line 132

def initialize
  @normalized_controller_name = Hash.new do |hash, controller_name|
    hash[controller_name] = controller_name.underscore.gsub(/_controller$/, "")
  end

  @parsed_uri = Hash.new do |hash, uri|
    hash[uri] = Addressable::URI.parse(uri).path
  end
end

Instance Method Details

#log(statement) ⇒ Object



126
127
128
# File 'lib/logeater/parser.rb', line 126

def log(statement)
  $stderr.puts "\e[33m#{statement}\e[0m"
end

#parse!(line) ⇒ Object

optional: (Views: 0.1ms | ActiveRecord: 50.0ms)

Raises:



50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/logeater/parser.rb', line 50

def parse!(line)
  match = line.match LINE_MATCHER
  raise UnmatchedLine.new(line) unless match

  result = {
    type: :generic,
    timestamp: match["timestamp"],
    log_level: match["log_level"],
    message: match["message"]
  }.merge(
    parse_message(match["message"]))
end

#parse_message(message) ⇒ Object



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/logeater/parser.rb', line 63

def parse_message(message)
  match = message.match REQUEST_LINE_MATCHER
  return {} unless match

  message = match["message"]

  { subdomain: match["subdomain"],
    uuid: match["uuid"],
    type: :request_line,
    user_id: match["user_id"] && match["user_id"].to_i,
    tester_bar: !!match["tester_bar"],
    message: message
  }.merge(
    parse_message_extra(message))
end

#parse_message_extra(message) ⇒ Object



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/logeater/parser.rb', line 79

def parse_message_extra(message)
  match = message.match(REQUEST_STARTED_MATCHER)
  return parse_request_started_message(match) if match

  match = message.match(REQUEST_CONTROLLER_MATCHER)
  return parse_request_controller_message(match) if match

  match = message.match(REQUEST_PARAMETERS_MATCHER)
  return parse_request_params_message(match) if match

  match = message.match(REQUEST_COMPLETED_MATCHER)
  return parse_request_completed_message(match) if match

  {}
end

#parse_request_completed_message(match) ⇒ Object



117
118
119
120
121
122
# File 'lib/logeater/parser.rb', line 117

def parse_request_completed_message(match)
  { type: :request_completed,
    http_status: match["http_status"].to_i,
    http_response: match["http_response"],
    duration: match["duration"].to_i }
end

#parse_request_controller_message(match) ⇒ Object



102
103
104
105
106
107
# File 'lib/logeater/parser.rb', line 102

def parse_request_controller_message(match)
  { type: :request_controller,
    controller: normalized_controller_name[match["controller"]],
    action: match["action"],
    format: match["format"] }
end

#parse_request_params_message(match) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/logeater/parser.rb', line 109

def parse_request_params_message(match)
  { type: :request_params,
    params: ParamsParser.new(match["params"]).parse! }
rescue Logeater::Parser::MalformedParameters
  log "Unable to parse parameters: #{match["params"].inspect}"
  { params: match["params"] }
end

#parse_request_started_message(match) ⇒ Object



95
96
97
98
99
100
# File 'lib/logeater/parser.rb', line 95

def parse_request_started_message(match)
  { type: :request_started,
    http_method: match["http_method"],
    path: parsed_uri[match["path"]],
    remote_ip: match["remote_ip"] }
end