first commit
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
<?php
|
||||
|
||||
require_once '../core/LogReader/Exception.php';
|
||||
|
||||
abstract class LogReader_Abstract {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var SplFileObject
|
||||
*/
|
||||
protected $_file;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_filename;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var LogReader_Storage_Interface
|
||||
*/
|
||||
protected $_storage;
|
||||
|
||||
public function __construct($filename = '', $storage = null) {
|
||||
if ($filename) {
|
||||
$this->setFile($filename);
|
||||
}
|
||||
if ($storage) {
|
||||
$this->setStorage($storage);
|
||||
}
|
||||
}
|
||||
|
||||
public function setFile($filename) {
|
||||
$this->_filename = $filename;
|
||||
if (!is_file($filename)) {
|
||||
throw new LogReader_Exception("File '$filename' does not exist");
|
||||
}
|
||||
if (!is_readable($filename)) {
|
||||
throw new LogReader_Exception("File '$filename' is not readable");
|
||||
}
|
||||
$this->_file = new SplFileObject($filename);
|
||||
}
|
||||
|
||||
public function setStorage(LogReader_Storage_Interface $storage) {
|
||||
$this->_storage = $storage;
|
||||
}
|
||||
|
||||
abstract public function read();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return LogReader_Storage_Interface
|
||||
*/
|
||||
public function getStorage() {
|
||||
return $this->_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFilename() {
|
||||
return $this->_filename;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
require_once 'LogReader/Abstract.php';
|
||||
require_once 'LogReader/Item/ApachePhp.php';
|
||||
|
||||
class LogReader_ApachePhp extends LogReader_Abstract {
|
||||
|
||||
public function read() {
|
||||
$item = new LogReader_Item_ApachePhp();
|
||||
while (!$this->_file->eof()) {
|
||||
|
||||
if (preg_match('/^\[(?<date>.+?)\] \[(?:.+?)\] \[client (?<client>.+?)\] (?<php_type>PHP)?(?<message>.+?)(, referer: (?<referer>.+))?$/', $this->_file->fgets(), $matches)) {
|
||||
$date = $matches['date'];
|
||||
$message = $matches['message'];
|
||||
|
||||
if (preg_match('/^(Stack trace|[\d])/', trim($message))) {
|
||||
//this line is part of stack trace
|
||||
$item->appendStackTrace($message);
|
||||
} else {
|
||||
$this->_save($item);
|
||||
|
||||
$item = new LogReader_Item_ApachePhp();
|
||||
|
||||
$timestamp = date('Y-m-d H:i:s', strtotime($date));
|
||||
$item->setTimestamp($timestamp);
|
||||
if (!empty($matches['php_type'])) {
|
||||
$type = $this->_getType($message);
|
||||
} else {
|
||||
$type = 'Apache';
|
||||
}
|
||||
$item->setType($type);
|
||||
if (isset($matches['referer'])) {
|
||||
$item->setReferer($matches['referer']);
|
||||
}
|
||||
if (isset($matches['client'])) {
|
||||
$item->setClientIp($matches['client']);
|
||||
}
|
||||
$item->setMessage($message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->_save($item);
|
||||
}
|
||||
|
||||
protected function _getType($message) {
|
||||
if (preg_match('/^([a-zA-Z0-9 ]+): /', $message, $matches) && isset($matches[1])) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
protected function _save(LogReader_Item_ApachePhp $item) {
|
||||
if ($item->getMessage() && $this->_storage) {
|
||||
$stackTrace = $item->getStackTrace();
|
||||
$messagesArray = array_merge(array($item->getMessage()), $stackTrace);
|
||||
$item->setMessage(implode("\n", $messagesArray));
|
||||
$this->_storage->save($item);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
class LogReader_Exception extends Exception {}
|
||||
@@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
abstract class LogReader_Item_Abstract {
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_timestamp;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_type;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_message;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
protected $_isNew;
|
||||
|
||||
/**
|
||||
* Unique id to distinct errors
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getId() {
|
||||
return md5($this->getMessage());
|
||||
}
|
||||
|
||||
public function getTimestamp() {
|
||||
return $this->_timestamp;
|
||||
}
|
||||
|
||||
public function getType() {
|
||||
return $this->_type;
|
||||
}
|
||||
|
||||
public function getMessage() {
|
||||
return $this->_message;
|
||||
}
|
||||
|
||||
public function setTimestamp($timestamp) {
|
||||
$this->_timestamp = $timestamp;
|
||||
}
|
||||
|
||||
public function setType($type) {
|
||||
$this->_type = $type;
|
||||
}
|
||||
|
||||
public function setMessage($message) {
|
||||
$this->_message = $message;
|
||||
}
|
||||
|
||||
public function getIsNew() {
|
||||
return $this->_isNew;
|
||||
}
|
||||
|
||||
public function setIsNew($isNew) {
|
||||
$this->_isNew = $isNew;
|
||||
}
|
||||
|
||||
public function populate($data) {
|
||||
foreach ($data as $prop => $value) {
|
||||
if (property_exists($this, $prop)) {
|
||||
$this->$prop = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
require_once 'LogReader/Item/Abstract.php';
|
||||
|
||||
class LogReader_Item_ApachePhp extends LogReader_Item_Abstract {
|
||||
|
||||
protected $_clientIp;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_stackTrace = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_referer = '';
|
||||
|
||||
|
||||
public function getReferer() {
|
||||
return $this->_referer;
|
||||
}
|
||||
|
||||
public function setReferer($referer) {
|
||||
$this->_referer = $referer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $line
|
||||
*/
|
||||
public function appendStackTrace($line) {
|
||||
$this->_stackTrace[] = $line;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getStackTrace() {
|
||||
return $this->_stackTrace;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $clientIp
|
||||
*/
|
||||
public function setClientIp($clientIp) {
|
||||
$this->_clientIp = $clientIp;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getClientIp() {
|
||||
return $this->_clientIp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
require_once '../core/LogReader/Item/Abstract.php';
|
||||
|
||||
class LogReader_Item_Nginx extends LogReader_Item_Abstract {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_referrer = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_request = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $_host = '';
|
||||
|
||||
|
||||
public function getRequest() {
|
||||
return $this->_request;
|
||||
}
|
||||
|
||||
public function getHost() {
|
||||
return $this->_host;
|
||||
}
|
||||
|
||||
public function setRequest($request) {
|
||||
$this->_request = $request;
|
||||
}
|
||||
|
||||
public function setHost($host) {
|
||||
$this->_host = $host;
|
||||
}
|
||||
|
||||
|
||||
public function getReferrer() {
|
||||
return $this->_referrer;
|
||||
}
|
||||
|
||||
public function setReferrer($referer) {
|
||||
$this->_referrer = $referer;
|
||||
}
|
||||
|
||||
public function getRequestUrl() {
|
||||
$request = preg_replace('/^GET (.+) HTTP.+/', '$1', $this->getRequest());
|
||||
$url = 'http://' . $this->getHost() . $request;
|
||||
return $url;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
require_once '../core/LogReader/Abstract.php';
|
||||
require_once '../core/LogReader/Item/Nginx.php';
|
||||
|
||||
class LogReader_Nginx extends LogReader_Abstract {
|
||||
|
||||
|
||||
public function read() {
|
||||
//2014/03/28 15:17:15 [error] 13385#0: *197692 open() "/var/www/logo.png" failed (2: No such file or directory), client: 192.168.1.1, server: cs.google.com, request: "GET /static/img/logo.png HTTP/1.1", host: "cs.google.com", referrer: "http://google.com"
|
||||
while (!$this->_file->eof()) {
|
||||
if (preg_match('/^(?<date>[0-9\/]+ [0-9:]+) \[.+?\] .+? .+? (?<message>.+), client: .+?,(.+)request: "(?<request>.+)", host: "(?<host>.+?)"(, referrer: "(?<referrer>.+)")?/', $this->_file->fgets(), $matches)) {
|
||||
$item = new LogReader_Item_Nginx();
|
||||
|
||||
$timestamp = date('Y-m-d H:i:s', strtotime($matches['date']));
|
||||
$item->setTimestamp($timestamp);
|
||||
$message = $matches['message'];
|
||||
$type = $this->_getType($message);
|
||||
$item->setType($type);
|
||||
$item->setMessage($message);
|
||||
$item->setRequest($matches['request']);
|
||||
$item->setHost($matches['host']);
|
||||
if (isset($matches['referrer'])) {
|
||||
$item->setReferrer($matches['referrer']);
|
||||
}
|
||||
|
||||
if ($this->_storage) {
|
||||
$this->_storage->save($item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected function _getType($message) {
|
||||
if (preg_match('/^([a-zA-Z0-9 ()]+) "/', $message, $matches) && isset($matches[1])) {
|
||||
return trim($matches[1]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
require_once '../core/LogReader/Storage/Interface.php';
|
||||
|
||||
class LogReader_Storage_Array implements LogReader_Storage_Interface {
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_data = array();
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function load() {
|
||||
return $this->_data;
|
||||
}
|
||||
|
||||
public function save(\LogReader_Item_Abstract $item) {
|
||||
$this->_data[] = $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns unique errors
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function loadUnique() {
|
||||
$uniqRows = array();
|
||||
foreach ($this->_data as $item) {
|
||||
$itemId = $item->getId();
|
||||
if (isset($uniqRows[$itemId])) {
|
||||
$newTime = strtotime($item->getTimestamp());
|
||||
$oldTime = strtotime($uniqRows[$itemId]->getTimestamp());
|
||||
if ($newTime > $oldTime) {
|
||||
$uniqRows[$itemId] = $item;
|
||||
}
|
||||
} else {
|
||||
$uniqRows[$item->getId()] = $item;
|
||||
}
|
||||
}
|
||||
|
||||
uasort($uniqRows, function($a, $b) {
|
||||
return strtotime($a->getTimestamp()) > strtotime($b->getTimestamp());
|
||||
});
|
||||
|
||||
return $uniqRows;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
require_once '../core/LogReader/Item/Abstract.php';
|
||||
|
||||
interface LogReader_Storage_Interface {
|
||||
|
||||
public function save(LogReader_Item_Abstract $item);
|
||||
|
||||
public function load();
|
||||
|
||||
public function loadUnique();
|
||||
}
|
||||
Reference in New Issue
Block a user