Welcome, guest! Login / Register - Why register?
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&#40;$route_to_file&#41;
    {
        return file&#40;$route_to_file&#41;;
    }

    /**
     * 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&#40;$route_to_file&#41;;

           $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

Your Name: Code Language: