diff --git a/.gitignore b/.gitignore index 0a6dbb3cb2..28e3f36ab6 100644 --- a/.gitignore +++ b/.gitignore @@ -4,7 +4,7 @@ !/.gitignore !/.editorconfig !/.scrutinizer.yml - +!/.travis.yml # Others # ########## diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..1ab38ae3fb --- /dev/null +++ b/.travis.yml @@ -0,0 +1,11 @@ +language: php php: + - '5.3' + - '5.4' + - '5.5' + - '5.6' + - '7.0' + - hhvm + +matrix: + allow_failures: + - php: 7.0 diff --git a/includes/syslog.php b/includes/syslog.php index 4cecba55fa..a84a79a499 100644 --- a/includes/syslog.php +++ b/includes/syslog.php @@ -52,38 +52,25 @@ function process_syslog($entry, $update) { $os = get_cache($entry['host'], 'os'); if (in_array($os, array('ios', 'iosxe', 'catos'))) { - $matches = array(); - // if (preg_match('#%(?P.*):( ?)(?P.*)#', $entry['msg'], $matches)) { - // $entry['msg'] = $matches['msg']; - // $entry['program'] = $matches['program']; - // } - // unset($matches); - if (strstr($entry['msg'], '%')) { - $entry['msg'] = preg_replace('/^%(.+?):\ /', '\\1||', $entry['msg']); - list(,$entry['msg']) = explode(': %', $entry['msg']); - $entry['msg'] = '%'.$entry['msg']; - $entry['msg'] = preg_replace('/^%(.+?):\ /', '\\1||', $entry['msg']); + // multipart message + if(strpos($entry['msg'], ':') !== false) { + /* Split the following examples + * %CARD-SEVERITY-MSG:SLOT %FACILITY-SEVERITY-MNEMONIC: Message-text + * %FACILITY-SUBFACILITY-SEVERITY-MNEMONIC: Message-text + */ + $matches = array(); + if(preg_match('/^(?%?[A-Za-z\d\-_]+(:[A-Z]* %[A-Z\d\-_]+)?): ?(?.*)/', $entry['msg'], $matches)) { + $entry['program'] = $matches['program']; + $entry['msg'] = $matches['msg']; + } + unset($matches); } else { - $entry['msg'] = preg_replace('/^.*[0-9]:/', '', $entry['msg']); - $entry['msg'] = preg_replace('/^[0-9][0-9]\ [A-Z]{3}:/', '', $entry['msg']); - $entry['msg'] = preg_replace('/^(.+?):\ /', '\\1||', $entry['msg']); - } - - $entry['msg'] = preg_replace('/^.+\.[0-9]{3}:/', '', $entry['msg']); - $entry['msg'] = preg_replace('/^.+-Traceback=/', 'Traceback||', $entry['msg']); - - list($entry['program'], $entry['msg']) = explode('||', $entry['msg']); - $entry['msg'] = preg_replace('/^[0-9]+:/', '', $entry['msg']); - - if (!$entry['program']) { - $entry['msg'] = preg_replace('/^([0-9A-Z\-]+?):\ /', '\\1||', $entry['msg']); - list($entry['program'], $entry['msg']) = explode('||', $entry['msg']); - } - - if (!$entry['msg']) { - $entry['msg'] = $entry['program']; - unset($entry['program']); + // if this looks like a program (no groups of 2 or more lowercase letters), move it to program + if (!preg_match('/[(a-z)]{2,}/', $entry['msg'])) { + $entry['program'] = $entry['msg']; + unset($entry['msg']); + } } } else if ($os == 'linux' and get_cache($entry['host'], 'version') == 'Point') { diff --git a/misc/notifications.rss b/misc/notifications.rss index f4baa96ca4..5d094945b1 100644 --- a/misc/notifications.rss +++ b/misc/notifications.rss @@ -12,5 +12,10 @@ This is the first notification. We will post these whenever an upcoming major change is about to happen. Tue, 19 Jan 2016 12:00:00 +0000 + + Cisco syslog parsing changes + We have overhauled the Cisco syslog parsing. Please monitor your syslog entries from Cisco IOS, IOSXR, and CatOS devices. If you notice any issues please open a new issue on GitHub and include the original syslog message. + Thu, 03 Mar 2016 12:00:00 +0000 + diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000000..26bc37ed3b --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,8 @@ + + + + + ./tests/ + + + diff --git a/tests/SyslogTest.php b/tests/SyslogTest.php new file mode 100644 index 0000000000..02d6e22dab --- /dev/null +++ b/tests/SyslogTest.php @@ -0,0 +1,90 @@ + +fillLine($line); + $data = array(); + $data['input'] = $entry; + unset($entry['msg']); // empty msg + $data['result'] = array_merge($entry, $resultDelta); + return $data; + } + + public function testCiscoSyslog() + { + // populate fake $dev_cache and $config + global $config, $dev_cache; + $dev_cache['1.1.1.1'] = ['device_id' => 1, 'os' => 'ios', 'version' => 1];; + $confg = array(); + $config['syslog_filter'] = array(); + + // populate test data + $testdata = array(); + + // ---- IOS ---- + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||%CARD-SEVERITY-MSG:SLOT %FACILITY-SEVERITY-MNEMONIC: Message-text||", + ['device_id'=>1, 'program'=>'%CARD-SEVERITY-MSG:SLOT %FACILITY-SEVERITY-MNEMONIC', 'msg'=>'Message-text'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||%FACILITY-SUBFACILITY-SEVERITY-MNEMONIC: Message-text||", + ['device_id'=>1, 'program'=>'%FACILITY-SUBFACILITY-SEVERITY-MNEMONIC', 'msg'=>'Message-text'] + ); + + // ---- CatOS ---- + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||%IP-3-UDP_SOCKOVFL:UDP socket overflow||", + ['device_id'=>1, 'program'=>'%IP-3-UDP_SOCKOVFL', 'msg'=>'UDP socket overflow'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||DTP-1-ILGLCFG: Illegal config (on, isl--on,dot1q) on Port [mod/port]||", + ['device_id'=>1, 'program'=>'DTP-1-ILGLCFG', 'msg'=>'Illegal config (on, isl--on,dot1q) on Port [mod/port]'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||Cannot enable text mode config if ACL config is cleared from nvram||", + ['device_id'=>1, 'program'=>'', 'msg'=>'Cannot enable text mode config if ACL config is cleared from nvram'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||%PAGP-5-PORTFROMSTP / %PAGP-5-PORTTOSTP||", + ['device_id'=>1, 'program'=>'%PAGP-5-PORTFROMSTP / %PAGP-5-PORTTOSTP'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||%SYS-3-EOBC_CHANNELREINIT||", + ['device_id'=>1, 'program'=>'%SYS-3-EOBC_CHANNELREINIT'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||%SYS-4-MODHPRESET:||", + ['device_id'=>1, 'program'=>'%SYS-4-MODHPRESET', 'msg'=>''] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||InbandPingProcessFailure:Module x not responding over inband||", + ['device_id'=>1, 'program'=>'INBANDPINGPROCESSFAILURE', 'msg'=>'Module x not responding over inband'] + ); + $testdata[] = $this->createData( + "1.1.1.1||user||info||info||0e||2016-02-28 00:23:34||RxSBIF_SEQ_NUM_ERROR:slot=x||", + ['device_id'=>1, 'program'=>'RXSBIF_SEQ_NUM_ERROR', 'msg'=>'slot=x'] + ); + + + // run tests + foreach($testdata as $data) { + $res = process_syslog($data['input'], 0); + $this->assertEquals($data['result'], $res); + } + } +} +