Psst.. new poll here.
Psst.. new forums here.
Microsoft is blocking us again (TY IP Reputation!) so just use oauth login instead. :)
Paste
Pasted as PHP by parser ( 15 years ago )
<?php
/**
* Парсит лог vindicia и зависывает распарсенные данные в БД
*
* @uses sfBaseTask
* @author Paramonov Anton Nikolaevich <[email protected]>
*/
class VindiciaLogParserTask extends sfBaseTask
{
private $logs_directory = 'log/vindicia_calls'; // путь к логам
protected function configure()
{
$this->namespace = 'vindicia';
$this->name = 'ParseLogs';
$this->briefDescription = 'Парсит лог vindicia и зависывает распарсенные данные в БД';
$this->detailedDescription = '';
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application', 'frontend'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environement', 'prod')
));
}
protected function execute($arguments = array(), $options = array())
{
psContext::createInstance($this->configuration);
sfConfig::set('sf_debug', false);
$dirs_name = $this->getDirsName();
$files_name = $this->getLogFilesName($dirs_name);
$files_name = $this->removeParseFilesName($files_name);
$this->removeDateFilesName($files_name);
$this->parseLogFiles($files_name);
}
/**
* getDirsName Получает наименования директорий из которых необходимо брать файлы логов
* и записывает пути к этим директориям в массив
*
* @access private
* @return array
*/
private function getDirsName()
{
$d = dir($this->logs_directory);
while ($entry = $d->read())
{
if (!preg_match('/(\d{4})-(\d{2})-(\d{2}).log/', $entry) and
preg_match('/(\d{4})-(\d{2})-(\d{2})/', $entry))
{
$dirs_name[] = $this->logs_directory . '/' . $entry;
}
}
$d->close();
return $dirs_name;
}
/**
* getLogFilesName Получает параметром массив строк (пути к директориям содержащим логи) и
* возвращает массив путей к логам.
*
* @access private
* @param array $dirs_name
* @return array
*/
private function getLogFilesName($dirs_name)
{
foreach($dirs_name as $route)
{
$d = dir($route);
while ($entry = $d->read())
{
if(preg_match('/(\d{2}).log/', $entry))
$files_name[] = $route . '/' . $entry;
}
}
return $files_name;
}
/**
* removeParseFilesName Получает на вход массив имён файлов, удаляет оттуда уже распарсенные и
* возвращает обратно
*
* @access private
* @param array $files_name
* @return array
*/
private function removeParseFilesName($files_name)
{
$db = sfDbSimple::getInstance('vindicia_queries_log_index');
$path = $db->query('SELECT DISTINCT path FROM vindicia_queries_log_index');
foreach ($path as $value)
{
$b = array_search($this->logs_directory . $value['path'], $files_name);
if($b !== false)
{
unset($files_name[$b]);
}
}
return $files_name;
}
/**
* removeDateFilesName Получает на вход массив имён файлов, удаляет оттуда пути до логов которые
* пишутся в данный момент исходя из того, что имя директории -- дата, когда
* писался лог, а имя файла -- час, когда он писался.
*
* @param array $files_name
* @return array
*/
private function removeDateFilesName($files_name)
{
$dir_name = date('Y-m-d');
$log_name = date('H') . '.log';
$path = '/' . $dir_name . '/' . $log_name;
$b = array_search($this->logs_directory . $path, $files_name);
if($b !== false)
{
unset($files_name[$b]);
}
return $files_name;
}
/**
* getLogFile Вспомогательный метод для parseLogFile. Параметром получает путь к файлу
* лога и построчно извлекает содержимое файла в массив.
*
* @access private
* @param string $route_to_file
* @return array
*/
private function getLogFile($route_to_file)
{
return file($route_to_file);
}
/**
* parseLogFiles Получает на вход массив путей к логам парсит их и записывает данные в БД
*
* @access private
* @param array $files_name
*/
private function parseLogFiles($files_name)
{
$objects_and_methods = array();
$i = 0;
foreach ($files_name as $route_to_file)
{
echo '[' . $i=$i+1 . ']' . $route_to_file . "\n";
$file = $this->getLogFile($route_to_file);
$params = $this->getAllParams($file);
$this->recordLogToDb($params, str_replace($this->logs_directory, '', $route_to_file));
}
}
/**
* getAllParams Получает на вход массив строк файла логов и достаёт нужные параметры
*
* @access private
* @param array $file
* @todo пухлый метод, раскидать логику по вспомогательным методам
* @return array
*/
private function getAllParams($file)
{
$identif = ''; // идентификатор для if-ов
$v = ''; // если serialize раскидан на несколько строк пишем сюда value
$length = 0; // для учёта длинны запроса
$query_ident = 0; // для учёта отступа запроса от начала файла
foreach ($file as $value)
{
if (preg_match('/-----BEGIN PGP MESSAGE-----/', $value))
{
$identif = 'PGP';
}
if ($identif == 'PGP' or $identif == 'PGPEND')
{
if ($identif == 'PGPEND')
{
$value = $v . $value;
$identif = 'RECIEVED';
}
$v .= $value;
if (preg_match('/-----END PGP MESSAGE-----/', $value))
{
$identif = 'PGPEND';
}
}
if ($identif == 'SENT' and $value != '')
{
$length += strlen($value);
$object_and_methods = $this->getOAndM($value);
$all_params['object'] = $object_and_methods[0];
$all_params['method'] = $object_and_methods[1];
$all_params['userId'] = $this->getUserId($value);
$all_params = array_merge($all_params, $sent_params);
$identif = '';
}
if (preg_match('/SENT/', $value))
{
$length += strlen($value);
$sent_params = $this->getSentParams($value);
$identif = 'SENT';
}
if ($identif == 'RECIEVED')
{
$length += strlen($value);
$all_params['length'] = $length;
$all_params['queryIdent'] = $query_ident;
$query_ident += $length;
$length = 0;
$obj = unserialize($value);
$identif = '';
$all_params['returnCode'] = $obj->return->returnCode;
$all_params['returnString'] = $obj->return->returnString;
if(isset($obj->transaction))
{
$all_params['transactionId'] = $obj->transaction->merchantTransactionId . "\n";
}
else
{
$all_params['transactionId'] = 0;
}
if($all_params['object'] == 'AutoBill' and $all_params['method'] == 'update')
{
$all_params['autoBillId'] = $obj->autobill->merchantAutoBillId;
}
else
{
$all_params['autoBillId'] = 0;
}
$return_params[] = $all_params;
}
if (preg_match('/RECIEVED/', $value))
{
$length += strlen($value);
if (preg_match('/(\d{1,4})\.(\d{1,3})/', $value, $sec))
{
$all_params['consumed'] = $sec[0];
}
elseif (preg_match('/(\d{1,3})sec/', $value, $sec))
{
$all_params['consumed'] = preg_replace('/[^0-9]+/i', '', $sec[0]);
}
$identif = 'RECIEVED';
}
}
return $return_params;
}
/**
* getSentParams Получает на вход строку с ключевым словом SENT возвращает массив где
* указано время запроса, и его хэш.
*
* @access private
* @param string $value
* @return array
*/
private function getSentParams($value)
{
preg_match('/(\d{2})-(\d{2})-(\d{2}) -- (\d{2})-(\d{2})-(\d{2})/', $value, $date);
$date_time = explode(' -- ', $date[0]);
// меняет местами год и дату в строке даты
$date = explode('-', $date_time[0]);
$date_time[0] = $date[2] . '-' . $date[1] . '-' . $date[0];
// заменяет в строке времени тире на двоеточие
$date_time[1] = str_replace('-', ':', $date_time[1]);
preg_match('/([a-z0-9]){32}/', $value, $hash);
$sent_params['date'] = $date_time[0] . ' ' . $date_time[1];
$sent_params['hash'] = $hash[0];
return $sent_params;
}
/**
* getOAndM Получает на вход строку sent и возвращает массив содержащий объект и
* метод
*
* @access private
* @param string $value
* @return array
*/
private function getOAndM($value)
{
preg_match('/([A-Za-z]{1,50})->([A-Za-z]{1,50})/', $value, $array);
return explode('->', $array[0]);
}
/**
* getUserId Получает на вход строку sent и возвращает userId
*
* @access private
* @param string $sent_string
* @return integer
*/
private function getUserId($sent_string)
{
$sent_serialize = preg_replace('/([A-Za-z]{1,50})->([A-Za-z]{1,50}) : /', '', $sent_string);
$un_sent_serialize = unserialize($sent_serialize);
// merchantAccountId часто отсутсвует если он есть, возвращает значение,
// если нет -- 0
if(isset($un_sent_serialize['parameters']['account']->merchantAccountId))
return $un_sent_serialize['parameters']['account']->merchantAccountId;
else
return 0;
}
/**
* recordLogToDb Получает на вход массив запросов лог-файла и записывает данные в БД
*
* @access private
* @param array $params
* @param string $path_to_file
*/
private function recordLogToDb($params, $path_to_file)
{
foreach($params as $query)
{
$db = sfDbSimple::getInstance('vindicia_queries_log_index');
$db->query('INSERT INTO vindicia_queries_log_index(object, method, user_id, datet, hash,
consumed, length, query_ident, return_code, return_string, path,
transaction_id, autobill_id)
VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', $query['object'],
$query['method'], $query['userId'], $query['date'],
$query['hash'], $query['consumed'], $query['length'],
$query['queryIdent'], $query['returnCode'], $query['returnString'],
$path_to_file, $query['transactionId'], $query['autoBillId']);
}
}
}
Revise this Paste