first commit

This commit is contained in:
2024-04-19 14:04:41 +07:00
commit 014283036f
7282 changed files with 1324127 additions and 0 deletions
+67
View File
@@ -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;
}
}
+61
View File
@@ -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);
}
}
}
+3
View File
@@ -0,0 +1,3 @@
<?php
class LogReader_Exception extends Exception {}
+79
View File
@@ -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;
}
}
}
}
+63
View File
@@ -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;
}
}
+57
View File
@@ -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;
}
}
+40
View File
@@ -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]);
}
}
}
+53
View File
@@ -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;
}
}
+12
View File
@@ -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();
}