Olivier Bourdon | 7bf8b53 | 2016-11-15 17:35:37 +0100 | [diff] [blame] | 1 | -- Copyright 2016 Mirantis, Inc. |
| 2 | -- |
| 3 | -- Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | -- you may not use this file except in compliance with the License. |
| 5 | -- You may obtain a copy of the License at |
| 6 | -- |
| 7 | -- http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | -- |
| 9 | -- Unless required by applicable law or agreed to in writing, software |
| 10 | -- distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | -- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | -- See the License for the specific language governing permissions and |
| 13 | -- limitations under the License. |
| 14 | local dt = require "date_time" |
| 15 | local l = require 'lpeg' |
| 16 | l.locale(l) |
| 17 | |
| 18 | local patt = require 'patterns' |
| 19 | local utils = require 'lma_utils' |
| 20 | |
| 21 | local tonumber = tonumber |
| 22 | |
| 23 | local M = {} |
| 24 | setfenv(1, M) -- Remove external access to contain everything in the module |
| 25 | |
| 26 | local function to_secfrac (num) |
| 27 | return tonumber(num) / 1000 |
| 28 | end |
| 29 | |
| 30 | local sp = patt.sp |
| 31 | local spaces = patt.sp^1 |
| 32 | local pgname = patt.programname |
| 33 | local delimeter = l.P": " |
| 34 | local message = l.Cg(patt.Message / utils.chomp, "Message") |
| 35 | local severity = l.Cg(pgname, "Severity") |
| 36 | |
| 37 | -- Common patterns |
| 38 | local modulename = l.Cg(pgname, "Module") |
| 39 | local ip_address = l.Cg((l.digit + patt.dot)^1, "ip_address") |
Simon Pasquier | ee5d9ae | 2017-01-24 08:55:36 +0100 | [diff] [blame] | 40 | local http_status = l.Cg(patt.Number / tonumber, "status") |
Olivier Bourdon | 7bf8b53 | 2016-11-15 17:35:37 +0100 | [diff] [blame] | 41 | local http_request_time = l.Cg(patt.Number, "request_time") |
| 42 | local delim = (patt.sp + patt.dash)^1 |
| 43 | local hostname = l.Cg(patt.programname, "Hostname") |
| 44 | local process_info = l.P"[" * "Thread" * sp * l.Cg(l.digit^1, "ThreadId") * |
| 45 | ", " * "Pid" * sp * l.Cg(l.digit^1, "Pid") * "]" |
| 46 | |
| 47 | -- Timestamp patterns |
| 48 | -- 10/31/2016 03:40:47 AM [contrail-alarm-gen]: blabla |
Olivier Bourdon | 8e8b221 | 2017-08-03 14:19:28 +0200 | [diff] [blame] | 49 | local log_num_month_timestamp = l.Cg(dt.build_strftime_grammar("%m/%d/%Y %r") / dt.time_to_ns, "Timestamp") |
| 50 | local log_short_str_month_timestamp = l.Cg(dt.build_strftime_grammar("%b/%d/%Y %r") / dt.time_to_ns, "Timestamp") |
| 51 | local log_full_str_month_timestamp = l.Cg(dt.build_strftime_grammar("%B/%d/%Y %r") / dt.time_to_ns, "Timestamp") |
| 52 | local log_timestamp = l.Ct(log_num_month_timestamp + log_short_str_month_timestamp + log_full_str_month_timestamp) |
Olivier Bourdon | 7bf8b53 | 2016-11-15 17:35:37 +0100 | [diff] [blame] | 53 | |
| 54 | -- 172.16.10.101 - - [2016-10-31 12:50:36] "POST /subscribe HTTP/1.1" 200 715 0.058196 |
| 55 | local api_timestamp = l.Cg(patt.Timestamp, "Timestamp") |
| 56 | |
| 57 | -- 2016-10-27 Thu 17:50:37:633.908 CEST ctl01 [Thread 140024858027968, Pid 23338]: DnsAgent [SYS_INFO]: blabla |
| 58 | local timezone = dt.timezone + l.P"CET" * l.Cg(l.Cc"+", "offset_sign") * |
| 59 | l.Cg(l.Cc"01" / tonumber, "offset_hour") * l.Cg(l.Cc"00"/ tonumber, "offset_min") |
| 60 | local day_of_week = l.Cg(l.P"Mon" + l.P"Tue" + l.P"Wed" + l.P"Thu" + |
| 61 | l.P"Fri" + l.P"Sat" + l.P"Sun", "day_of_week") |
| 62 | local secfrac_grammar = l.Cg((l.digit^1 * patt.dot * l.digit^1) / to_secfrac, "sec_frac") |
| 63 | local ts_grammar = l.Ct(dt.rfc3339_full_date * patt.sp * day_of_week * sp * |
| 64 | dt.rfc3339_partial_time * ":" * secfrac_grammar * sp * timezone) |
| 65 | local control_timestamp = l.Cg(ts_grammar / dt.time_to_ns, "Timestamp") |
| 66 | |
| 67 | -- Complete grammars |
| 68 | -- 10/31/2016 03:40:47 AM [contrail-alarm-gen]: blabla |
| 69 | LogGrammar = l.Ct(log_timestamp * patt.sp * "[" * modulename * "]:" * patt.sp * message) |
Olivier Bourdon | 8e8b221 | 2017-08-03 14:19:28 +0200 | [diff] [blame] | 70 | -- wokeup and found a line |
| 71 | -- NoSuchProcess: process name:cassandra pid:22192 |
| 72 | -- Exception AssertionError: AssertionError() in <module 'threading' from '/usr/lib/python2.7/threading.pyc'> ignored |
| 73 | -- ... |
| 74 | GenericGrammar = l.Ct(message) |
Olivier Bourdon | 7bf8b53 | 2016-11-15 17:35:37 +0100 | [diff] [blame] | 75 | |
| 76 | -- 172.16.10.101 - - [2016-10-31 12:50:36] "POST /subscribe HTTP/1.1" 200 715 0.058196 |
| 77 | ApiGrammar = l.Ct(ip_address * delim * "["* api_timestamp * "]" * sp * message) |
| 78 | RequestGrammar = l.Ct(l.P'"' * patt.http_request * l.P'"' * sp * http_status * sp * patt.Number * sp * http_request_time) |
| 79 | |
| 80 | -- 2016-10-27 Thu 17:50:37:633.908 CEST ctl01 [Thread 140024858027968, Pid 23338]: DnsAgent [SYS_INFO]: blabla |
| 81 | -- 2016-11-01 Tue 05:24:26:590.824 CET ctl01 [Thread 140310906029824, Pid 18319]: SANDESH: blabla |
| 82 | ControlGrammar = l.Ct(control_timestamp * spaces * hostname * sp * process_info * l.P": " * |
| 83 | modulename * (sp * "[" * severity * "]")^-1 * l.P": "^-1 * message) |
| 84 | |
| 85 | return M |