app/Services/ShjSixService.php を削除
Some checks failed
Deploy main / deploy (push) Has been cancelled

This commit is contained in:
go.unhi 2025-10-23 20:37:56 +09:00
parent 8c0413157a
commit a484231216

View File

@ -1,710 +0,0 @@
<?php
namespace App\Services;
use App\Models\Device;
use App\Models\HardwareCheckLog;
use App\Models\PrintJobLog;
use App\Models\Batch\BatchLog;
use App\Models\OperatorQue;
use App\Models\User;
use App\Models\Park;
use App\Services\ShjMailSendService;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;
use Carbon\Carbon;
/**
* SHJ-6 サーバ死活監視処理サービス
*
* サーバとデバイスの死活監視、ハードウェア状態監視、プリンタログ監視を実行
* 異常検出時のメール通知機能を含む統合モニタリングサービス
*/
class ShjSixService
{
/**
* Device モデル
*
* @var Device
*/
protected $deviceModel;
/**
* HardwareCheckLog モデル
*
* @var HardwareCheckLog
*/
protected $hardwareCheckLogModel;
/**
* PrintJobLog モデル
*
* @var PrintJobLog
*/
protected $printJobLogModel;
/**
* BatchLog モデル
*
* @var BatchLog
*/
protected $batchLogModel;
/**
* OperatorQue モデル
*
* @var OperatorQue
*/
protected $operatorQueModel;
/**
* ShjMailSendService
*
* @var ShjMailSendService
*/
protected $mailSendService;
/**
* 固定メールアドレスDB反映NG時用
*
* @var string
*/
const FIXED_EMAIL_ADDRESS = 'system-alert@so-manager.com';
/**
* プリンタログ監視期間(分)
*
* @var int
*/
const PRINTER_LOG_MONITOR_MINUTES = 15;
/**
* コンストラクタ
*
* @param Device $deviceModel
* @param HardwareCheckLog $hardwareCheckLogModel
* @param PrintJobLog $printJobLogModel
* @param BatchLog $batchLogModel
* @param OperatorQue $operatorQueModel
* @param ShjMailSendService $mailSendService
*/
public function __construct(
Device $deviceModel,
HardwareCheckLog $hardwareCheckLogModel,
PrintJobLog $printJobLogModel,
BatchLog $batchLogModel,
OperatorQue $operatorQueModel,
ShjMailSendService $mailSendService
) {
$this->deviceModel = $deviceModel;
$this->hardwareCheckLogModel = $hardwareCheckLogModel;
$this->printJobLogModel = $printJobLogModel;
$this->batchLogModel = $batchLogModel;
$this->operatorQueModel = $operatorQueModel;
$this->mailSendService = $mailSendService;
}
/**
* SHJ-6 サーバ死活監視処理メイン実行
*
* 処理フロー:
* 【処理1】サーバ死活監視DBアクセス
* 【処理2】デバイス管理マスタを取得する
* 【処理3】デバイス毎のハードウェア状態を取得する
* 【処理4】プリンタ制御プログラムログを取得する
* 【判断3】エラーログ有無
* 【処理5】バッチ処理ログを作成する
* 異常時は共通A処理を実行
*
* @return array 処理結果
*/
public function executeServerMonitoring(): array
{
$batchLogId = null;
$warnings = [];
$errorDetails = [];
try {
// バッチ処理開始ログ作成
$batchLog = BatchLog::createBatchLog(
'shj6',
BatchLog::STATUS_START,
[],
'SHJ-6 サーバ死活監視処理開始'
);
$batchLogId = $batchLog->id;
Log::info('SHJ-6 サーバ死活監視処理開始', [
'batch_log_id' => $batchLogId
]);
// 【処理1】サーバ死活監視DBアクセス
$dbAccessResult = $this->checkDatabaseAccess();
if (!$dbAccessResult['success']) {
// DB接続NGの場合は共通A処理実行
$this->executeCommonProcessA($batchLogId, 'DB接続エラー: ' . $dbAccessResult['message']);
return [
'success' => false,
'message' => 'データベース接続エラーが発生しました',
'error_details' => [$dbAccessResult['message']],
'batch_log_id' => $batchLogId
];
}
// 【処理2】デバイス管理マスタを取得する
$devices = $this->getDeviceManagementData();
Log::info('デバイス管理マスタ取得完了', [
'device_count' => count($devices)
]);
// 【処理3】デバイス毎のハードウェア状態を取得する
$hardwareStatusResult = $this->getHardwareStatus($devices);
if (!$hardwareStatusResult['success']) {
// ハードウェア状態取得できなかった場合は共通A処理実行
$this->executeCommonProcessA($batchLogId, 'ハードウェア状態取得エラー: ' . $hardwareStatusResult['message']);
$warnings[] = 'ハードウェア状態の一部で異常を検出しました';
$errorDetails[] = $hardwareStatusResult['message'];
}
// 【処理4】プリンタ制御プログラムログを取得する
$printerLogResult = $this->getPrinterControlLogs();
// 【判断3】エラーログ有無
if ($printerLogResult['has_errors']) {
// エラーログ有の場合は共通A処理実行
$this->executeCommonProcessA($batchLogId, 'プリンタエラーログ検出: ' . $printerLogResult['error_summary']);
$warnings[] = 'プリンタ制御でエラーが検出されました';
$errorDetails[] = $printerLogResult['error_summary'];
}
// 【処理5】バッチ処理ログを作成する
$monitoringSummary = $this->createMonitoringSummary($devices, $hardwareStatusResult, $printerLogResult);
$status = empty($warnings) ? BatchLog::STATUS_SUCCESS : BatchLog::STATUS_WARNING;
$message = empty($warnings) ?
'SHJ-6 サーバ死活監視処理正常完了' :
'SHJ-6 サーバ死活監視処理完了(警告あり)';
$batchLog->update([
'status' => $status,
'end_time' => now(),
'message' => $message,
'success_count' => 1
]);
Log::info('SHJ-6 サーバ死活監視処理完了', [
'batch_log_id' => $batchLogId,
'monitoring_summary' => $monitoringSummary,
'warnings' => $warnings
]);
return [
'success' => true,
'message' => 'SHJ-6 サーバ死活監視処理が完了しました',
'monitoring_summary' => $monitoringSummary,
'warnings' => $warnings,
'error_details' => $errorDetails,
'batch_log_id' => $batchLogId
];
} catch (\Exception $e) {
$errorMessage = 'SHJ-6 サーバ死活監視処理でエラーが発生: ' . $e->getMessage();
if (isset($batchLog) && $batchLog) {
$batchLog->update([
'status' => BatchLog::STATUS_ERROR,
'end_time' => now(),
'message' => $errorMessage,
'error_details' => $e->getMessage(),
'error_count' => 1
]);
}
// 例外発生時も共通A処理実行
$this->executeCommonProcessA($batchLogId, $errorMessage);
Log::error('SHJ-6 サーバ死活監視処理エラー', [
'batch_log_id' => $batchLogId,
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString()
]);
return [
'success' => false,
'message' => $errorMessage,
'error_details' => [$e->getMessage()],
'batch_log_id' => $batchLogId
];
}
}
/**
* 【処理1】サーバ死活監視DBアクセス
*
* @return array アクセス結果
*/
private function checkDatabaseAccess(): array
{
try {
// 設定マスタテーブルへの簡単なクエリでDB接続確認
$result = DB::select('SELECT 1 as test');
if (empty($result)) {
return [
'success' => false,
'message' => 'データベースクエリの結果が空です'
];
}
Log::info('データベース接続確認成功');
return [
'success' => true,
'message' => 'データベース接続正常'
];
} catch (\Exception $e) {
Log::error('データベース接続エラー', [
'error' => $e->getMessage()
]);
return [
'success' => false,
'message' => $e->getMessage()
];
}
}
/**
* 【処理2】デバイス管理マスタを取得する
*
* @return array デバイス情報
*/
private function getDeviceManagementData(): array
{
try {
$devices = DB::table('device')
->select([
'device_id',
'park_id',
'device_type',
'device_subject',
'device_identifier',
'device_work',
'device_workstart',
'device_replace',
'device_remarks',
'operator_id'
])
->where('device_workstart', '<=', now())
->whereNull('device_replace')
->get()
->toArray();
Log::info('デバイス管理マスタ取得完了', [
'device_count' => count($devices)
]);
return $devices;
} catch (\Exception $e) {
Log::error('デバイス管理マスタ取得エラー', [
'error' => $e->getMessage()
]);
throw $e;
}
}
/**
* 【処理3】デバイス毎のハードウェア状態を取得する
*
* @param array $devices デバイス一覧
* @return array ハードウェア状態結果
*/
private function getHardwareStatus(array $devices): array
{
try {
$normalDevices = 0;
$abnormalDevices = 0;
$abnormalDetails = [];
foreach ($devices as $device) {
$latestStatus = HardwareCheckLog::getLatestStatusByDevice($device->device_id);
if (!$latestStatus) {
$abnormalDevices++;
$abnormalDetails[] = "デバイスID {$device->device_id}: ハードウェア状態ログが存在しません";
continue;
}
if ($latestStatus->isNormal()) {
$normalDevices++;
} else {
$abnormalDevices++;
$abnormalDetails[] = "デバイスID {$device->device_id}: {$latestStatus->getStatusNameAttribute()} - {$latestStatus->status_comment}";
}
}
Log::info('ハードウェア状態取得完了', [
'total_devices' => count($devices),
'normal_devices' => $normalDevices,
'abnormal_devices' => $abnormalDevices
]);
return [
'success' => $abnormalDevices === 0,
'total_devices' => count($devices),
'normal_devices' => $normalDevices,
'abnormal_devices' => $abnormalDevices,
'abnormal_details' => $abnormalDetails,
'message' => $abnormalDevices > 0 ?
"{$abnormalDevices}台のデバイスで異常を検出" :
'全デバイス正常'
];
} catch (\Exception $e) {
Log::error('ハードウェア状態取得エラー', [
'error' => $e->getMessage()
]);
return [
'success' => false,
'message' => $e->getMessage(),
'abnormal_details' => ["ハードウェア状態取得中にエラーが発生: " . $e->getMessage()]
];
}
}
/**
* 【処理4】プリンタ制御プログラムログを取得する
*
* @return array プリンタログ結果
*/
private function getPrinterControlLogs(): array
{
try {
// 過去15分間のエラーログを取得
$errorLogs = PrintJobLog::getRecentErrorLogs();
$hasErrors = $errorLogs->count() > 0;
$errorSummary = '';
$errorDetails = [];
if ($hasErrors) {
$errorsByCode = $errorLogs->groupBy('error_code');
$errorSummaryParts = [];
foreach ($errorsByCode as $errorCode => $logs) {
$count = $logs->count();
$errorSummaryParts[] = "エラーコード{$errorCode}: {$count}";
foreach ($logs as $log) {
$errorDetails[] = sprintf(
"[%s] %s - エラーコード: %d, %s",
$log->created_at->format('Y-m-d H:i:s'),
$log->process_name,
$log->error_code,
$log->status_comment
);
}
}
$errorSummary = implode(', ', $errorSummaryParts);
}
Log::info('プリンタ制御プログラムログ取得完了', [
'monitoring_period_minutes' => self::PRINTER_LOG_MONITOR_MINUTES,
'error_logs_count' => $errorLogs->count(),
'has_errors' => $hasErrors
]);
return [
'success' => true,
'has_errors' => $hasErrors,
'error_count' => $errorLogs->count(),
'error_summary' => $errorSummary,
'error_details' => $errorDetails,
'monitoring_period' => self::PRINTER_LOG_MONITOR_MINUTES . '分間'
];
} catch (\Exception $e) {
Log::error('プリンタ制御プログラムログ取得エラー', [
'error' => $e->getMessage()
]);
return [
'success' => false,
'has_errors' => true,
'error_summary' => 'ログ取得エラー: ' . $e->getMessage(),
'error_details' => ["プリンタログ取得中にエラーが発生: " . $e->getMessage()]
];
}
}
/**
* 監視結果サマリーを作成
*
* @param array $devices デバイス一覧
* @param array $hardwareResult ハードウェア結果
* @param array $printerResult プリンタ結果
* @return string 監視サマリー
*/
private function createMonitoringSummary(array $devices, array $hardwareResult, array $printerResult): string
{
$summary = [
'デバイス数: ' . count($devices),
'ハードウェア正常: ' . ($hardwareResult['normal_devices'] ?? 0) . '台',
'ハードウェア異常: ' . ($hardwareResult['abnormal_devices'] ?? 0) . '台',
'プリンタエラー: ' . ($printerResult['error_count'] ?? 0) . '件'
];
return implode(', ', $summary);
}
/**
* 共通A処理監視結果を反映
*
* @param int|null $batchLogId バッチログID
* @param string $alertMessage アラートメッセージ
* @return void
*/
private function executeCommonProcessA(?int $batchLogId, string $alertMessage): void
{
try {
Log::info('共通A処理開始', [
'batch_log_id' => $batchLogId,
'alert_message' => $alertMessage
]);
// 【共通判断1】DB反映可否判定
$canReflectToDb = $this->canReflectToDatabase();
if ($canReflectToDb) {
// 【共通処理1】オペレータキューを登録する
$this->registerOperatorQueue($alertMessage, $batchLogId);
// 【共通処理2】メール送信対象オペレータを取得する
$operators = $this->getMailTargetOperators();
// 【共通判断2】送信対象有無
if (!empty($operators)) {
foreach ($operators as $operator) {
$this->sendAlertMail($operator['email'], $alertMessage, 'オペレータ');
}
}
// 【共通処理3】駐輪場管理者を取得する
$parkManagers = $this->getParkManagers();
// 【共通判断3】送信対象有無
if (!empty($parkManagers)) {
foreach ($parkManagers as $manager) {
$this->sendAlertMail($manager['email'], $alertMessage, '駐輪場管理者');
}
}
} else {
// DB反映NGの場合は固定メールアドレスに送信
$this->sendAlertMail(self::FIXED_EMAIL_ADDRESS, $alertMessage, 'システム管理者');
}
Log::info('共通A処理完了', [
'batch_log_id' => $batchLogId
]);
} catch (\Exception $e) {
Log::error('共通A処理エラー', [
'batch_log_id' => $batchLogId,
'error' => $e->getMessage()
]);
}
}
/**
* DB反映可否判定
*
* @return bool 反映可能かどうか
*/
private function canReflectToDatabase(): bool
{
try {
// 簡単なINSERTテストでDB反映可否を確認
DB::beginTransaction();
$testId = DB::table('operator_que')->insertGetId([
'que_class' => 6,
'que_comment' => 'DB反映テスト',
'que_status' => 0,
'created_at' => now(),
'updated_at' => now()
]);
// テストレコードを削除
DB::table('operator_que')->where('que_id', $testId)->delete();
DB::commit();
return true;
} catch (\Exception $e) {
DB::rollBack();
Log::warning('DB反映不可', ['error' => $e->getMessage()]);
return false;
}
}
/**
* オペレータキューを登録
*
* @param string $alertMessage アラートメッセージ
* @param int|null $batchLogId バッチログID
* @return void
*/
private function registerOperatorQueue(string $alertMessage, ?int $batchLogId): void
{
try {
OperatorQue::create([
'que_class' => 6, // SHJ-6用のクラス
'user_id' => null,
'contract_id' => null,
'park_id' => null,
'que_comment' => $alertMessage,
'que_status' => 0, // 待機中
'que_status_comment' => 'システム監視アラート',
'work_instructions' => "SHJ-6監視処理 BatchLogID: {$batchLogId}",
'created_at' => now(),
'updated_at' => now()
]);
Log::info('オペレータキュー登録完了', [
'batch_log_id' => $batchLogId,
'alert_message' => $alertMessage
]);
} catch (\Exception $e) {
Log::error('オペレータキュー登録エラー', [
'batch_log_id' => $batchLogId,
'error' => $e->getMessage()
]);
}
}
/**
* メール送信対象オペレータを取得
*
* @return array オペレータ一覧
*/
private function getMailTargetOperators(): array
{
try {
// user_typeがオペレータのユーザーを取得仮の条件
$operators = DB::table('users')
->select(['user_id', 'email', 'name'])
->where('user_type', 'operator') // 実際のテーブル構造に合わせて調整
->whereNotNull('email')
->where('email', '!=', '')
->get()
->map(function ($user) {
return [
'user_id' => $user->user_id,
'email' => $user->email,
'name' => $user->name ?? 'オペレータ'
];
})
->toArray();
Log::info('メール送信対象オペレータ取得完了', [
'operator_count' => count($operators)
]);
return $operators;
} catch (\Exception $e) {
Log::error('メール送信対象オペレータ取得エラー', [
'error' => $e->getMessage()
]);
return [];
}
}
/**
* 駐輪場管理者を取得
*
* @return array 駐輪場管理者一覧
*/
private function getParkManagers(): array
{
try {
// 駐輪場管理者を取得(仮の条件)
$managers = DB::table('users')
->select(['user_id', 'email', 'name'])
->where('user_type', 'park_manager') // 実際のテーブル構造に合わせて調整
->whereNotNull('email')
->where('email', '!=', '')
->get()
->map(function ($user) {
return [
'user_id' => $user->user_id,
'email' => $user->email,
'name' => $user->name ?? '駐輪場管理者'
];
})
->toArray();
Log::info('駐輪場管理者取得完了', [
'manager_count' => count($managers)
]);
return $managers;
} catch (\Exception $e) {
Log::error('駐輪場管理者取得エラー', [
'error' => $e->getMessage()
]);
return [];
}
}
/**
* アラートメールを送信
*
* @param string $email メールアドレス
* @param string $alertMessage アラートメッセージ
* @param string $recipientType 受信者タイプ
* @return void
*/
private function sendAlertMail(string $email, string $alertMessage, string $recipientType): void
{
try {
// SHJメール送信機能を使用メールテンプレートID=1を使用、実際の値に調整
$result = $this->mailSendService->executeMailSend(
$email,
'', // 予備メールアドレスは空
1 // システムアラート用メールテンプレートID
);
if ($result['success']) {
Log::info('アラートメール送信成功', [
'email' => $email,
'recipient_type' => $recipientType,
'alert_message' => $alertMessage
]);
} else {
Log::error('アラートメール送信失敗', [
'email' => $email,
'recipient_type' => $recipientType,
'error' => $result['message']
]);
}
} catch (\Exception $e) {
Log::error('アラートメール送信エラー', [
'email' => $email,
'recipient_type' => $recipientType,
'error' => $e->getMessage()
]);
}
}
}