Files
crm.clientright.ru/ParseAndCreateEvent.php
Fedor cfe586182a Улучшено логирование и увеличены таймауты в ParseAndCreateEvent.php
- Увеличен таймаут cURL с 60 до 180 секунд (3 минуты)
- Добавлен таймаут соединения 30 секунд
- Детальное логирование ошибок cURL с кодами и описанием
- Добавлено логирование времени выполнения каждого этапа
- Добавлено логирование использования памяти
- Улучшена обработка ошибок JSON с выводом проблемных данных
- Добавлена статистика общего времени выполнения скрипта
2025-10-29 10:21:41 +03:00

290 lines
13 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
/**
* Обёртка для парсинга ответа от parscourt.php и создания события
*
* Принимает те же параметры что и parscourt.php
* Вызывает parscourt.php, получает JSON с last_event
* И создаёт событие через CreateCourtEvent.php
*
* Этот скрипт можно дёргать из workflow вместо parscourt.php
*/
// Устанавливаем рабочую директорию
chdir(__DIR__);
// Логирование
function log_wrapper($level, $message) {
$log_file = 'logs/parse_and_create_event.log';
$timestamp = date('Y-m-d H:i:s');
$log_entry = "{$timestamp} - {$level}: {$message}\n";
file_put_contents($log_file, $log_entry, FILE_APPEND | LOCK_EX);
}
try {
$scriptStartTime = microtime(true);
log_wrapper('INFO', '=== НАЧАЛО ОБРАБОТКИ ===');
log_wrapper('DEBUG', "Память на старте: " . round(memory_get_usage() / 1024 / 1024, 2) . " МБ");
// Получаем параметры (из POST, GET или argv)
$params = array_merge($_GET, $_POST);
// Если параметров нет, пробуем argv (для вызова через CLI)
if (empty($params) && !empty($argv)) {
for ($i = 1; $i < count($argv); $i++) {
if (strpos($argv[$i], '=') !== false) {
list($key, $value) = explode('=', $argv[$i], 2);
$params[$key] = $value;
}
}
}
log_wrapper('DEBUG', "Параметры: " . json_encode($params, JSON_UNESCAPED_UNICODE));
// Проверяем обязательные параметры
if (empty($params['project_id'])) {
throw new Exception('Параметр project_id обязателен');
}
$projectId = $params['project_id'];
// Формируем параметры для parscourt.php
$parscourtParams = [
'project_id' => $projectId,
'status' => $params['status'] ?? '',
'link1' => $params['link1'] ?? '',
'link2' => $params['link2'] ?? '',
'link3' => $params['link3'] ?? '',
'case_number' => $params['case_number'] ?? '02-15800/2025', // Дефолтный номер дела для тестирования
'uid' => $params['uid'] ?? '',
'use_new_parser' => $params['use_new_parser'] ?? 'true',
'skip_duplicate_check' => $params['skip_duplicate_check'] ?? 'false'
];
log_wrapper('INFO', "Вызываем parscourt.php для проекта $projectId");
// Формируем URL для вызова parscourt.php
$domain = $_SERVER['HTTP_HOST'] ?? 'crm.clientright.ru';
$protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'https'; // Всегда https для production
$parscourtUrl = $protocol . '://' . $domain . '/parscourt.php?' . http_build_query($parscourtParams);
log_wrapper('DEBUG', "URL: $parscourtUrl");
// Вызываем через cURL с POST (parscourt.php принимает POST параметры)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $protocol . '://' . $domain . '/parscourt.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($parscourtParams));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 180); // Увеличен таймаут до 3 минут
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30); // Таймаут на установку соединения
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Для production HTTPS
log_wrapper('DEBUG', "Отправляем cURL запрос к parscourt.php...");
$startTime = microtime(true);
$output = curl_exec($ch);
$execTime = round(microtime(true) - $startTime, 2);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$curlError = curl_error($ch);
$curlErrno = curl_errno($ch);
$curlInfo = curl_getinfo($ch);
curl_close($ch);
log_wrapper('DEBUG', "cURL выполнен за {$execTime} сек, HTTP код: $httpCode");
if ($curlErrno !== 0) {
log_wrapper('ERROR', "cURL ошибка #{$curlErrno}: {$curlError}");
log_wrapper('DEBUG', "cURL info: " . json_encode($curlInfo, JSON_UNESCAPED_UNICODE));
throw new Exception("Ошибка cURL при вызове parscourt.php: [{$curlErrno}] {$curlError}");
}
if ($httpCode !== 200) {
log_wrapper('ERROR', "Неожиданный HTTP код: $httpCode");
log_wrapper('DEBUG', "Первые 500 символов ответа: " . substr($output, 0, 500));
throw new Exception("Ошибка вызова parscourt.php: HTTP $httpCode");
}
$outputSize = strlen($output);
log_wrapper('DEBUG', "Получен ответ от parscourt.php (размер: {$outputSize} байт)");
log_wrapper('DEBUG', "Ответ от parscourt.php: $output");
// Парсим JSON ответ
$parscourtResponse = json_decode($output, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$jsonError = json_last_error_msg();
log_wrapper('ERROR', "Ошибка декодирования JSON: {$jsonError}");
log_wrapper('DEBUG', "Первые 1000 символов проблемного ответа: " . substr($output, 0, 1000));
throw new Exception('Ошибка декодирования JSON от parscourt.php: ' . $jsonError);
}
log_wrapper('DEBUG', "Распарсенный ответ: " . json_encode($parscourtResponse, JSON_UNESCAPED_UNICODE));
// Проверяем наличие last_event и что он не пустой
if (empty($parscourtResponse['last_event']) ||
!isset($parscourtResponse['last_event']['Наименование']) ||
empty($parscourtResponse['last_event']['Наименование'])) {
log_wrapper('WARNING', 'Нет данных о событиях (last_event пустой или без названия)');
$response = [
'success' => true,
'message' => 'Парсинг выполнен, но нет новых событий',
'event_created' => false
];
header('Content-Type: application/json; charset=utf-8');
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit(0);
}
$lastEvent = $parscourtResponse['last_event'];
// Извлекаем данные события (пробуем оба варианта ключей)
$eventName = $lastEvent['Наименование'] ?? $lastEvent['name'] ?? 'Судебное заседание';
$eventDate = $lastEvent['Дата'] ?? $lastEvent['date'] ?? '';
$eventTime = $lastEvent['Время'] ?? $lastEvent['time'] ?? '';
$location = $lastEvent['Место'] ?? $lastEvent['location'] ?? '';
$result = $lastEvent['Результат'] ?? $lastEvent['result'] ?? '';
$basis = $lastEvent['Основание'] ?? $lastEvent['basis'] ?? '';
$note = $lastEvent['Примечание'] ?? $lastEvent['note'] ?? '';
$publicationDate = $lastEvent['Дата размещения'] ?? $lastEvent['publication_date'] ?? '';
log_wrapper('DEBUG', "Извлеченные данные: eventName='$eventName', eventDate='$eventDate', eventTime='$eventTime'");
log_wrapper('INFO', "Событие извлечено: $eventName ($eventDate $eventTime)");
// Проверяем что дата не пустая
if (empty($eventDate)) {
log_wrapper('WARNING', 'Дата события пустая, пропускаем создание');
$response = [
'success' => true,
'message' => 'Событие не создано: дата отсутствует',
'event_created' => false
];
header('Content-Type: application/json; charset=utf-8');
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit(0);
}
// Формируем данные для CreateCourtEvent.php
log_wrapper('DEBUG', "Перед формированием данных: eventName='$eventName', result='$result'");
$eventData = [
'project_id' => $projectId,
'event_name' => $eventName,
'event_date' => $eventDate,
'event_time' => $eventTime,
'location' => $location,
'result' => $result,
'basis' => $basis,
'note' => $note,
'publication_date' => $publicationDate
];
log_wrapper('INFO', "Создаём событие через CreateCourtEvent_v2.php");
log_wrapper('DEBUG', "Данные события: " . json_encode($eventData, JSON_UNESCAPED_UNICODE));
// Вызываем CreateCourtEvent_v2.php через CLI
$createEventCommand = 'php ' . __DIR__ . '/CreateCourtEvent_v2.php';
$eventDataJson = json_encode($eventData, JSON_UNESCAPED_UNICODE);
// Передаём данные через временный файл
$tempFile = tempnam(sys_get_temp_dir(), 'event_data_');
file_put_contents($tempFile, $eventDataJson);
log_wrapper('DEBUG', "Временный файл создан: $tempFile");
log_wrapper('DEBUG', "Запускаем команду: cat $tempFile | $createEventCommand");
$startTimeEvent = microtime(true);
$createEventOutput = shell_exec('cat ' . escapeshellarg($tempFile) . ' | ' . $createEventCommand . ' 2>&1');
$execTimeEvent = round(microtime(true) - $startTimeEvent, 2);
log_wrapper('DEBUG', "CreateCourtEvent_v2.php выполнен за {$execTimeEvent} сек");
// Удаляем временный файл
unlink($tempFile);
log_wrapper('DEBUG', "Временный файл удалён");
log_wrapper('DEBUG', "Ответ от CreateCourtEvent_v2.php (длина: " . strlen($createEventOutput) . " байт): $createEventOutput");
// Фильтруем PHP Notice из ответа
$cleanOutput = preg_replace('/^PHP Notice:.*$/m', '', $createEventOutput);
$cleanOutput = trim($cleanOutput);
log_wrapper('DEBUG', "Очищенный ответ (длина: " . strlen($cleanOutput) . " байт)");
$createEventResponse = json_decode($cleanOutput, true);
if (json_last_error() !== JSON_ERROR_NONE) {
$jsonError = json_last_error_msg();
log_wrapper('ERROR', "Ошибка декодирования JSON от CreateCourtEvent_v2.php: {$jsonError}");
log_wrapper('DEBUG', "Проблемный ответ: $cleanOutput");
throw new Exception('Ошибка декодирования JSON от CreateCourtEvent_v2.php: ' . $jsonError);
}
if (empty($createEventResponse['success'])) {
$errorMsg = $createEventResponse['error'] ?? 'Неизвестная ошибка';
log_wrapper('ERROR', "CreateCourtEvent_v2.php вернул ошибку: $errorMsg");
throw new Exception('Ошибка создания события: ' . $errorMsg);
}
log_wrapper('SUCCESS', "Событие создано: " . $createEventResponse['event_id']);
// Формируем финальный ответ
$response = [
'success' => true,
'message' => 'Парсинг выполнен и событие создано',
'event_created' => true,
'event_id' => $createEventResponse['event_id'],
'event_name' => $eventName,
'event_date' => $eventDate,
'event_time' => $eventTime,
'project_id' => $projectId
];
$totalTime = round(microtime(true) - $scriptStartTime, 2);
$memoryUsed = round(memory_get_usage() / 1024 / 1024, 2);
$memoryPeak = round(memory_get_peak_usage() / 1024 / 1024, 2);
log_wrapper('SUCCESS', "=== ОБРАБОТКА ЗАВЕРШЕНА УСПЕШНО ===");
log_wrapper('INFO', "Общее время выполнения: {$totalTime} сек");
log_wrapper('DEBUG', "Память использовано: {$memoryUsed} МБ (пик: {$memoryPeak} МБ)");
header('Content-Type: application/json; charset=utf-8');
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit(0);
} catch (Exception $e) {
$error_message = $e->getMessage();
$totalTime = isset($scriptStartTime) ? round(microtime(true) - $scriptStartTime, 2) : 0;
$memoryUsed = round(memory_get_usage() / 1024 / 1024, 2);
log_wrapper('ERROR', "=== ОШИБКА ОБРАБОТКИ ===");
log_wrapper('ERROR', "Сообщение: $error_message");
log_wrapper('ERROR', "Файл: " . $e->getFile() . " (строка " . $e->getLine() . ")");
log_wrapper('ERROR', "Стек вызовов:");
log_wrapper('ERROR', $e->getTraceAsString());
log_wrapper('INFO', "Время до ошибки: {$totalTime} сек");
log_wrapper('DEBUG', "Память использовано: {$memoryUsed} МБ");
log_wrapper('ERROR', '=== КОНЕЦ ЛОГА ОШИБКИ ===');
$response = [
'success' => false,
'error' => $error_message,
'timestamp' => date('Y-m-d H:i:s'),
'execution_time' => $totalTime
];
header('Content-Type: application/json; charset=utf-8');
http_response_code(500);
echo json_encode($response, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit(1);
}
?>