From 49dd578e50abfa957aebd8ece5690419502c21fe Mon Sep 17 00:00:00 2001 From: F4ilji Date: Sun, 5 Jul 2026 23:28:23 +0500 Subject: [PATCH] feat(logging): migrate email pipeline to email channel --- .../EmailNews/FetchEmailNewsAction.php | 28 ++++++++-------- .../EmailNews/ProcessMixedFilesAction.php | 32 +++++++++---------- .../EmailNews/ProcessUploadedFilesAction.php | 2 +- .../Tasks/Email/ConnectToImapTask.php | 12 +++---- .../Tasks/Email/DownloadAttachmentsTask.php | 20 ++++++------ .../Tasks/Email/FetchUnreadEmailsTask.php | 6 ++-- .../Tasks/Email/FilterBySenderTask.php | 8 ++--- .../Tasks/Email/MarkEmailAsReadTask.php | 12 +++---- 8 files changed, 60 insertions(+), 60 deletions(-) diff --git a/app/Containers/Dashboard/Actions/EmailNews/FetchEmailNewsAction.php b/app/Containers/Dashboard/Actions/EmailNews/FetchEmailNewsAction.php index f6c1946..d0edff0 100644 --- a/app/Containers/Dashboard/Actions/EmailNews/FetchEmailNewsAction.php +++ b/app/Containers/Dashboard/Actions/EmailNews/FetchEmailNewsAction.php @@ -53,11 +53,11 @@ class FetchEmailNewsAction { // Проверяем, включена ли функция if (!config('email-news.enabled', true)) { - Log::warning('[FetchEmailNewsAction] Функция отключена в конфиге'); + Log::channel('email')->warning('Функция отключена в конфиге'); throw EmailFetchException::featureDisabled(); } - Log::info('[FetchEmailNewsAction] Начало получения новостей из Email'); + Log::channel('email')->info('Начало получения новостей из Email'); $result = [ 'processed_emails' => 0, @@ -82,7 +82,7 @@ class FetchEmailNewsAction $hasMoreEmails = true; while ($hasMoreEmails) { - Log::info('[FetchEmailNewsAction] Обработка batch', [ + Log::channel('email')->info('Обработка batch', [ 'batch' => $result['batches_processed'] + 1, 'batch_size' => self::BATCH_SIZE, 'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . 'MB', @@ -96,7 +96,7 @@ class FetchEmailNewsAction if (empty($emails)) { $hasMoreEmails = false; - Log::info('[FetchEmailNewsAction] Нет больше писем для обработки'); + Log::channel('email')->info('Нет больше писем для обработки'); break; } @@ -127,7 +127,7 @@ class FetchEmailNewsAction $this->collectGarbageIfNeeded(); } - Log::info('[FetchEmailNewsAction] Завершено', [ + Log::channel('email')->info('Завершено', [ 'processed' => $result['processed_emails'], 'created_posts' => $result['created_posts'], 'skipped' => $result['skipped_emails'], @@ -141,7 +141,7 @@ class FetchEmailNewsAction return $result; } catch (\Exception $e) { - Log::error('[FetchEmailNewsAction] Критическая ошибка', [ + Log::channel('email')->error('Критическая ошибка', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); @@ -159,7 +159,7 @@ class FetchEmailNewsAction */ private function processEmail(array $email, Folder $folder): array { - Log::info('[FetchEmailNewsAction:processEmail] Обработка письма', [ + Log::channel('email')->info('Обработка письма', [ 'subject' => $email['subject'] ?? 'unknown', 'from' => $email['from_email'] ?? 'unknown', 'uid' => $email['uid'] ?? 'unknown', @@ -168,7 +168,7 @@ class FetchEmailNewsAction try { // SAFETY: Проверка наличия валидного IMAP message объекта if (!isset($email['message']) || !is_object($email['message'])) { - Log::warning('[FetchEmailNewsAction:processEmail] Отсутствует IMAP message объект', [ + Log::channel('email')->warning('Отсутствует IMAP message объект', [ 'subject' => $email['subject'] ?? 'unknown', ]); @@ -185,7 +185,7 @@ class FetchEmailNewsAction $hasDocument = collect($attachments)->contains(fn($att) => $att->isDocument()); if (!$hasDocument) { - Log::warning('[FetchEmailNewsAction:processEmail] Нет DOC/DOCX файла во вложениях', [ + Log::channel('email')->warning('Нет DOC/DOCX файла во вложениях', [ 'subject' => $email['subject'] ?? 'unknown', ]); @@ -207,7 +207,7 @@ class FetchEmailNewsAction // Помечаем письмо как прочитанное $this->markEmail($email['message'], $folder); - Log::info('[FetchEmailNewsAction:processEmail] Письмо успешно обработано', [ + Log::channel('email')->info('Письмо успешно обработано', [ 'subject' => $email['subject'] ?? 'unknown', 'post_id' => $postResult['post']->id, ]); @@ -218,7 +218,7 @@ class FetchEmailNewsAction 'attachments_count' => count($attachments), ]; } catch (\Exception $e) { - Log::error('[FetchEmailNewsAction:processEmail] Ошибка обработки письма', [ + Log::channel('email')->error('Ошибка обработки письма', [ 'subject' => $email['subject'] ?? 'unknown', 'error' => $e->getMessage(), ]); @@ -244,7 +244,7 @@ class FetchEmailNewsAction $fullPath = storage_path('app/' . $attachment->path); if (!file_exists($fullPath)) { - Log::warning('[FetchEmailNewsAction:convertToUploadedFiles] Файл не найден', [ + Log::channel('email')->warning('Файл не найден', [ 'path' => $attachment->path, ]); continue; @@ -262,7 +262,7 @@ class FetchEmailNewsAction $uploadedFiles[] = $uploadedFile; } - Log::info('[FetchEmailNewsAction:convertToUploadedFiles] Конвертировано файлов', [ + Log::channel('email')->info('Конвертировано файлов', [ 'count' => count($uploadedFiles), ]); @@ -304,7 +304,7 @@ class FetchEmailNewsAction $memoryAfter = round(memory_get_usage(true) / 1024 / 1024, 2); $freed = round(($memoryBefore - $memoryAfter), 2); - Log::info('[FetchEmailNewsAction] Сборка мусора', [ + Log::channel('email')->info('Сборка мусора', [ 'memory_before' => $memoryBefore . 'MB', 'memory_after' => $memoryAfter . 'MB', 'freed' => $freed . 'MB', diff --git a/app/Containers/Dashboard/Actions/EmailNews/ProcessMixedFilesAction.php b/app/Containers/Dashboard/Actions/EmailNews/ProcessMixedFilesAction.php index 0a0d18c..fffb56c 100644 --- a/app/Containers/Dashboard/Actions/EmailNews/ProcessMixedFilesAction.php +++ b/app/Containers/Dashboard/Actions/EmailNews/ProcessMixedFilesAction.php @@ -34,7 +34,7 @@ class ProcessMixedFilesAction // Принудительная очистка памяти перед обработкой gc_collect_cycles(); - Log::info('[ProcessMixedFilesAction] Начало обработки файлов', [ + Log::channel('email')->info('Начало обработки файлов', [ 'files_count' => $files->count(), 'files' => $files->map(fn($f) => $f->getClientOriginalName())->toArray(), 'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . ' MB', @@ -45,11 +45,11 @@ class ProcessMixedFilesAction $mainFile = $this->findMainNewsFileTask->run($files); if (!$mainFile) { - Log::error('[ProcessMixedFilesAction] Не найден файл для извлечения текста'); + Log::channel('email')->error('Не найден файл для извлечения текста'); throw new \RuntimeException('Не найден DOC/DOCX файл для извлечения текста'); } - Log::info('[ProcessMixedFilesAction] Основной файл найден', [ + Log::channel('email')->info('Основной файл найден', [ 'file' => $mainFile->getClientOriginalName(), 'extension' => $mainFile->getClientOriginalExtension(), 'real_path' => $mainFile->getRealPath(), @@ -57,28 +57,28 @@ class ProcessMixedFilesAction ]); // Извлекаем текст из основного файла (поддерживает и .doc, и .docx) - Log::info('[ProcessMixedFilesAction] Начало извлечения текста из документа'); + Log::channel('email')->info('Начало извлечения текста из документа'); try { $extractedText = $this->extractTextFromDocumentTask->run($mainFile); - Log::info('[ProcessMixedFilesAction] Текст извлечен', [ + Log::channel('email')->info('Текст извлечен', [ 'text_length' => strlen($extractedText ?? ''), 'text_preview' => substr($extractedText ?? '', 0, 100), ]); } catch (\Exception $e) { - Log::error('[ProcessMixedFilesAction] Ошибка при извлечении текста', [ + Log::channel('email')->error('Ошибка при извлечении текста', [ 'error' => $e->getMessage(), 'file' => $mainFile->getClientOriginalName(), ]); throw $e; } - Log::info('[ProcessMixedFilesAction] Результат извлечения текста', [ + Log::channel('email')->info('Результат извлечения текста', [ 'text_length' => strlen($extractedText ?? ''), 'has_text' => !empty($extractedText), ]); if (empty($extractedText)) { - Log::warning('[ProcessMixedFilesAction] Пустой текст после извлечения', [ + Log::channel('email')->warning('Пустой текст после извлечения', [ 'file' => $mainFile->getClientOriginalName(), ]); } @@ -93,7 +93,7 @@ class ProcessMixedFilesAction $categories = Category::all(); // Отправляем текст в AI - Log::info('[ProcessMixedFilesAction] Отправка текста в AI сервис', [ + Log::channel('email')->info('Отправка текста в AI сервис', [ 'text_length' => strlen($extractedText ?? ''), 'categories_count' => $categories->count(), ]); @@ -101,7 +101,7 @@ class ProcessMixedFilesAction try { $newsData = $this->callAiServiceTask->run($extractedText, $categories); } catch (\Exception $e) { - Log::error('[ProcessMixedFilesAction] Ошибка вызова AI сервиса', [ + Log::channel('email')->error('Ошибка вызова AI сервиса', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); @@ -109,11 +109,11 @@ class ProcessMixedFilesAction } if (!$newsData) { - Log::error('[ProcessMixedFilesAction] AI сервис вернул пустой ответ'); + Log::channel('email')->error('AI сервис вернул пустой ответ'); throw new \RuntimeException('Не удалось распознать данные через AI сервис. Проверьте логи AI запроса.'); } - Log::info('[ProcessMixedFilesAction] AI данные успешно получены', [ + Log::channel('email')->info('AI данные успешно получены', [ 'title' => $newsData['title'] ?? 'N/A', 'category_id' => $newsData['category_id'] ?? 'N/A', ]); @@ -130,7 +130,7 @@ class ProcessMixedFilesAction */ private function saveFiles(Collection $files, UploadedFile $mainFile): array { - Log::info('[ProcessMixedFilesAction:saveFiles] Начало сохранения файлов', [ + Log::channel('email')->info('Начало сохранения файлов', [ 'total_files' => $files->count(), ]); @@ -151,7 +151,7 @@ class ProcessMixedFilesAction // Если это изображение - сжимаем if ($this->compressImageTask->isImage($file)) { - Log::info('[ProcessMixedFilesAction:saveFiles] Обработка изображения', [ + Log::channel('email')->info('Обработка изображения', [ 'file' => $file->getClientOriginalName(), ]); @@ -161,7 +161,7 @@ class ProcessMixedFilesAction $compressionStats['compressed']++; $compressionStats['saved_bytes'] += $result['original_size'] - $result['size']; - Log::info('[ProcessMixedFilesAction:saveFiles] Изображение сжато', [ + Log::channel('email')->info('Изображение сжато', [ 'file' => $file->getClientOriginalName(), 'original_size' => $this->formatFileSize($result['original_size']), 'compressed_size' => $this->formatFileSize($result['size']), @@ -185,7 +185,7 @@ class ProcessMixedFilesAction } } - Log::info('[ProcessMixedFilesAction:saveFiles] Статистика сжатия', [ + Log::channel('email')->info('Статистика сжатия', [ 'total_images' => $compressionStats['total'], 'compressed' => $compressionStats['compressed'], 'saved' => $this->formatFileSize($compressionStats['saved_bytes']), diff --git a/app/Containers/Dashboard/Actions/EmailNews/ProcessUploadedFilesAction.php b/app/Containers/Dashboard/Actions/EmailNews/ProcessUploadedFilesAction.php index 22efaea..825928d 100644 --- a/app/Containers/Dashboard/Actions/EmailNews/ProcessUploadedFilesAction.php +++ b/app/Containers/Dashboard/Actions/EmailNews/ProcessUploadedFilesAction.php @@ -102,7 +102,7 @@ class ProcessUploadedFilesAction } } - Log::info('[ProcessUploadedFilesAction] Статистика сжатия', [ + Log::channel('email')->info('[ProcessUploadedFilesAction] Статистика сжатия', [ 'total_images' => $compressionStats['total'], 'compressed' => $compressionStats['compressed'], 'saved' => $this->formatFileSize($compressionStats['saved_bytes']), diff --git a/app/Containers/Dashboard/Tasks/Email/ConnectToImapTask.php b/app/Containers/Dashboard/Tasks/Email/ConnectToImapTask.php index 68bee51..7c4bd90 100644 --- a/app/Containers/Dashboard/Tasks/Email/ConnectToImapTask.php +++ b/app/Containers/Dashboard/Tasks/Email/ConnectToImapTask.php @@ -31,7 +31,7 @@ class ConnectToImapTask // Получаем конфиг для webklex/php-imap $imapConfig = config('imap'); - Log::debug('[ConnectToImapTask] Попытка подключения к IMAP', [ + Log::channel('email')->debug('Попытка подключения к IMAP', [ 'account' => $accountName, 'host' => $imapConfig['accounts'][$accountName]['host'] ?? 'unknown', ]); @@ -47,13 +47,13 @@ class ConnectToImapTask $client = $clientManager->account($accountName); $client->connect(); - Log::debug('[ConnectToImapTask] Успешное подключение к IMAP', [ + Log::channel('email')->debug('Успешное подключение к IMAP', [ 'account' => $accountName, ]); return $client; } catch (\Exception $e) { - Log::error('[ConnectToImapTask] Ошибка подключения к IMAP', [ + Log::channel('email')->error('Ошибка подключения к IMAP', [ 'account' => $accountName, 'error' => $e->getMessage(), ]); @@ -72,7 +72,7 @@ class ConnectToImapTask */ public function getFolder(Client $client, string $folderName): Folder { - Log::debug('[ConnectToImapTask] Получение папки', [ + Log::channel('email')->debug('Получение папки', [ 'folder' => $folderName, ]); @@ -95,7 +95,7 @@ class ConnectToImapTask throw EmailFetchException::folderNotFound($folderName); } - Log::debug('[ConnectToImapTask] Папка получена успешно', [ + Log::channel('email')->debug('Папка получена успешно', [ 'folder' => $folderName, 'fullName' => $folder->full_name ?? $folder->name ?? $folderName, ]); @@ -104,7 +104,7 @@ class ConnectToImapTask } catch (EmailFetchException $e) { throw $e; } catch (\Exception $e) { - Log::error('[ConnectToImapTask] Ошибка получения папки', [ + Log::channel('email')->error('Ошибка получения папки', [ 'folder' => $folderName, 'error' => $e->getMessage(), ]); diff --git a/app/Containers/Dashboard/Tasks/Email/DownloadAttachmentsTask.php b/app/Containers/Dashboard/Tasks/Email/DownloadAttachmentsTask.php index bfea73b..6db35ff 100644 --- a/app/Containers/Dashboard/Tasks/Email/DownloadAttachmentsTask.php +++ b/app/Containers/Dashboard/Tasks/Email/DownloadAttachmentsTask.php @@ -33,7 +33,7 @@ class DownloadAttachmentsTask { $disk = $disk ?? config('email-news.attachments_folder', 'email_attachments'); - Log::debug('[DownloadAttachmentsTask] Начало загрузки вложений', [ + Log::channel('email')->debug('Начало загрузки вложений', [ 'message_id' => $message->getMessageId(), 'disk' => $disk, 'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . 'MB', @@ -44,11 +44,11 @@ class DownloadAttachmentsTask $attachments = $message->getAttachments(); if (empty($attachments)) { - Log::warning('[DownloadAttachmentsTask] Вложения не найдены'); + Log::channel('email')->warning('Вложения не найдены'); throw EmailFetchException::noAttachmentsFound(); } - Log::debug('[DownloadAttachmentsTask] Найдено вложений', [ + Log::channel('email')->debug('Найдено вложений', [ 'count' => count($attachments), ]); @@ -60,7 +60,7 @@ class DownloadAttachmentsTask try { // Проверяем размер if ($maxSize > 0 && $attachment->getSize() > $maxSize) { - Log::warning('[DownloadAttachmentsTask] Вложение превышает максимальный размер', [ + Log::channel('email')->warning('Вложение превышает максимальный размер', [ 'filename' => $attachment->getName(), 'size' => $attachment->getSize(), 'max_size' => $maxSize, @@ -83,7 +83,7 @@ class DownloadAttachmentsTask contentId: $attachment->getContentId(), ); - Log::debug('[DownloadAttachmentsTask] Вложение сохранено', [ + Log::channel('email')->debug('Вложение сохранено', [ 'filename' => $attachment->getName(), 'path' => $savedPath, 'size' => $attachment->getSize(), @@ -92,13 +92,13 @@ class DownloadAttachmentsTask // OPTIMIZATION: Логирование памяти для больших вложений if (memory_get_usage(true) > self::MEMORY_LOG_THRESHOLD) { - Log::debug('[DownloadAttachmentsTask] Высокое использование памяти', [ + Log::channel('email')->debug('Высокое использование памяти', [ 'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . 'MB', 'peak_memory' => round(memory_get_peak_usage(true) / 1024 / 1024, 2) . 'MB', ]); } } catch (\Exception $e) { - Log::error('[DownloadAttachmentsTask] Ошибка сохранения вложения', [ + Log::channel('email')->error('Ошибка сохранения вложения', [ 'filename' => $attachment->getName(), 'error' => $e->getMessage(), ]); @@ -107,11 +107,11 @@ class DownloadAttachmentsTask } if (empty($savedAttachments)) { - Log::error('[DownloadAttachmentsTask] Не удалось сохранить ни одно вложение'); + Log::channel('email')->error('Не удалось сохранить ни одно вложение'); throw EmailFetchException::noAttachmentsFound(); } - Log::debug('[DownloadAttachmentsTask] Загрузка вложений завершена', [ + Log::channel('email')->debug('Загрузка вложений завершена', [ 'saved_count' => count($savedAttachments), 'memory_usage' => round(memory_get_usage(true) / 1024 / 1024, 2) . 'MB', ]); @@ -145,7 +145,7 @@ class DownloadAttachmentsTask return $disk . '/' . $filename; } } catch (\Exception $e) { - Log::error('[DownloadAttachmentsTask:saveAttachment] Ошибка сохранения', [ + Log::channel('email')->error('Ошибка сохранения', [ 'filename' => $attachment->getName(), 'error' => $e->getMessage(), ]); diff --git a/app/Containers/Dashboard/Tasks/Email/FetchUnreadEmailsTask.php b/app/Containers/Dashboard/Tasks/Email/FetchUnreadEmailsTask.php index e6e83bd..0a648c0 100644 --- a/app/Containers/Dashboard/Tasks/Email/FetchUnreadEmailsTask.php +++ b/app/Containers/Dashboard/Tasks/Email/FetchUnreadEmailsTask.php @@ -29,7 +29,7 @@ class FetchUnreadEmailsTask { $limit = $limit ?? config('imap.options.fetch_limit', 20); - Log::debug('[FetchUnreadEmailsTask] Получение непрочитанных писем', [ + Log::channel('email')->debug('Получение непрочитанных писем', [ 'folder' => $folder->full_name ?? $folder->name ?? 'unknown', 'limit' => $limit, ]); @@ -75,7 +75,7 @@ class FetchUnreadEmailsTask 'emails_count' => count($emails), ]); - Log::debug('[FetchUnreadEmailsTask] Получены письма', [ + Log::channel('email')->debug('Получены письма', [ 'count' => count($emails), 'folder' => $folder->full_name ?? $folder->name ?? 'unknown', ]); @@ -85,7 +85,7 @@ class FetchUnreadEmailsTask // Пробрасываем наши кастомные исключения throw $e; } catch (\Exception $e) { - Log::error('[FetchUnreadEmailsTask] Ошибка получения писем', [ + Log::channel('email')->error('Ошибка получения писем', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); diff --git a/app/Containers/Dashboard/Tasks/Email/FilterBySenderTask.php b/app/Containers/Dashboard/Tasks/Email/FilterBySenderTask.php index 7396bd8..22340f0 100644 --- a/app/Containers/Dashboard/Tasks/Email/FilterBySenderTask.php +++ b/app/Containers/Dashboard/Tasks/Email/FilterBySenderTask.php @@ -32,13 +32,13 @@ class FilterBySenderTask } } - Log::debug('[FilterBySenderTask] Фильтрация писем', [ + Log::channel('email')->debug('Фильтрация писем', [ 'total_emails' => count($emails), 'allowed_senders' => $allowedSenders, ]); if (empty($allowedSenders)) { - Log::warning('[FilterBySenderTask] Не указан разрешённый отправитель, пропускаем все письма'); + Log::channel('email')->warning('Не указан разрешённый отправитель, пропускаем все письма'); return []; } @@ -54,7 +54,7 @@ class FilterBySenderTask // Логируем только если включено логирование if (config('email-news.log_skipped_emails', true)) { - Log::debug('[FilterBySenderTask] Пропущено письмо от неразрешённого отправителя', [ + Log::channel('email')->debug('Пропущено письмо от неразрешённого отправителя', [ 'from' => $fromEmail, 'subject' => $email['subject'], 'date' => $email['date'], @@ -66,7 +66,7 @@ class FilterBySenderTask $filtered[] = $email; } - Log::debug('[FilterBySenderTask] Фильтрация завершена', [ + Log::channel('email')->debug('Фильтрация завершена', [ 'total' => count($emails), 'filtered' => count($filtered), 'skipped' => $skippedCount, diff --git a/app/Containers/Dashboard/Tasks/Email/MarkEmailAsReadTask.php b/app/Containers/Dashboard/Tasks/Email/MarkEmailAsReadTask.php index 8527cd3..f50ab8b 100644 --- a/app/Containers/Dashboard/Tasks/Email/MarkEmailAsReadTask.php +++ b/app/Containers/Dashboard/Tasks/Email/MarkEmailAsReadTask.php @@ -17,7 +17,7 @@ class MarkEmailAsReadTask */ public function run(object $message): bool { - Log::debug('[MarkEmailAsReadTask] Пометка письма как прочитанного', [ + Log::channel('email')->debug('Пометка письма как прочитанного', [ 'message_id' => $message->getMessageId(), 'subject' => $message->getSubject(), ]); @@ -25,11 +25,11 @@ class MarkEmailAsReadTask try { $message->setFlag('Seen'); - Log::debug('[MarkEmailAsReadTask] Письмо помечено как прочитанное'); + Log::channel('email')->debug('Письмо помечено как прочитанное'); return true; } catch (\Exception $e) { - Log::error('[MarkEmailAsReadTask] Ошибка пометки письма', [ + Log::channel('email')->error('Ошибка пометки письма', [ 'error' => $e->getMessage(), ]); @@ -46,7 +46,7 @@ class MarkEmailAsReadTask */ public function markAndMove(object $message, string $targetFolder): bool { - Log::debug('[MarkEmailAsReadTask] Пометка и перемещение письма', [ + Log::channel('email')->debug('Пометка и перемещение письма', [ 'message_id' => $message->getMessageId(), 'target_folder' => $targetFolder, ]); @@ -58,13 +58,13 @@ class MarkEmailAsReadTask // Перемещаем в другую папку $message->moveToFolder($targetFolder); - Log::debug('[MarkEmailAsReadTask] Письмо обработано и перемещено', [ + Log::channel('email')->debug('Письмо обработано и перемещено', [ 'target_folder' => $targetFolder, ]); return true; } catch (\Exception $e) { - Log::error('[MarkEmailAsReadTask] Ошибка обработки письма', [ + Log::channel('email')->error('Ошибка обработки письма', [ 'error' => $e->getMessage(), ]);