329 lines
11 KiB
PHP
329 lines
11 KiB
PHP
<?php
|
|
|
|
use Illuminate\Support\Facades\Log;
|
|
use Illuminate\Support\Facades\Storage;
|
|
use Carbon\Carbon;
|
|
|
|
/**
|
|
* Log scheduler execution
|
|
*
|
|
* @param string $action Action: 'schedule_run_started', 'schedule_run_completed', 'command_scheduled'
|
|
* @param array $data Additional data
|
|
* @return void
|
|
*/
|
|
function logSchedulerExecution(string $action, array $data = [])
|
|
{
|
|
try {
|
|
$timestamp = now()->toDateTimeString();
|
|
$logData = [
|
|
'timestamp' => $timestamp,
|
|
'action' => $action,
|
|
'data' => $data,
|
|
];
|
|
|
|
$message = "[Scheduler] {$action}";
|
|
if (!empty($data)) {
|
|
$message .= " | " . json_encode($data, JSON_UNESCAPED_UNICODE);
|
|
}
|
|
|
|
Log::info($message, $logData);
|
|
|
|
// Write to dedicated notification log file
|
|
// Use storage_path() to write directly to storage/logs/ directory
|
|
$logDir = storage_path('logs');
|
|
$logFile = $logDir . '/notifications-' . date('Y-m-d') . '.log';
|
|
|
|
// Determine status for log file
|
|
$status = 'scheduled';
|
|
if ($action === 'command_finished') {
|
|
$status = 'finished';
|
|
} elseif ($action === 'schedule_run_started') {
|
|
$status = 'started';
|
|
} elseif ($action === 'schedule_run_completed') {
|
|
$status = 'completed';
|
|
}
|
|
|
|
$logLine = sprintf(
|
|
"[%s] %s | SCHEDULER | %s\n",
|
|
$timestamp,
|
|
str_pad($status, 10),
|
|
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
);
|
|
|
|
// Use file_put_contents with FILE_APPEND flag
|
|
file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX);
|
|
|
|
} catch (\Exception $e) {
|
|
Log::error('Failed to write scheduler log', [
|
|
'error' => $e->getMessage(),
|
|
'action' => $action
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log notification command execution
|
|
*
|
|
* @param string $commandName Command name (e.g., 'notifications:check-deleted-joints')
|
|
* @param string $status Status: 'started', 'completed', 'skipped', 'error'
|
|
* @param array $data Additional data to log
|
|
* @return void
|
|
*/
|
|
function logNotificationCommand(string $commandName, string $status, array $data = [])
|
|
{
|
|
try {
|
|
$timestamp = now()->toDateTimeString();
|
|
$logData = [
|
|
'timestamp' => $timestamp,
|
|
'command' => $commandName,
|
|
'status' => $status,
|
|
'data' => $data,
|
|
];
|
|
|
|
// Log to Laravel's default log
|
|
$message = "[Notification Command] {$commandName} - {$status}";
|
|
if (!empty($data)) {
|
|
$message .= " | " . json_encode($data, JSON_UNESCAPED_UNICODE);
|
|
}
|
|
|
|
switch ($status) {
|
|
case 'started':
|
|
Log::info($message, $logData);
|
|
break;
|
|
case 'completed':
|
|
Log::info($message, $logData);
|
|
break;
|
|
case 'skipped':
|
|
Log::info($message, $logData);
|
|
break;
|
|
case 'error':
|
|
Log::error($message, $logData);
|
|
break;
|
|
default:
|
|
Log::info($message, $logData);
|
|
}
|
|
|
|
// Also write to dedicated notification log file
|
|
// Use storage_path() to write directly to storage/logs/ directory
|
|
$logDir = storage_path('logs');
|
|
$logFile = $logDir . '/notifications-' . date('Y-m-d') . '.log';
|
|
$logLine = sprintf(
|
|
"[%s] %s | %s | %s\n",
|
|
$timestamp,
|
|
str_pad($status, 10),
|
|
str_pad($commandName, 50),
|
|
json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
|
|
);
|
|
|
|
// Use file_put_contents with FILE_APPEND flag
|
|
file_put_contents($logFile, $logLine, FILE_APPEND | LOCK_EX);
|
|
|
|
} catch (\Exception $e) {
|
|
// Fallback to Laravel log if file write fails
|
|
Log::error('Failed to write notification log', [
|
|
'error' => $e->getMessage(),
|
|
'command' => $commandName,
|
|
'status' => $status
|
|
]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Log notification command start
|
|
*
|
|
* @param string $commandName
|
|
* @return void
|
|
*/
|
|
function logNotificationStart(string $commandName)
|
|
{
|
|
logNotificationCommand($commandName, 'started', [
|
|
'time' => now()->toTimeString(),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Log notification command completion
|
|
*
|
|
* @param string $commandName
|
|
* @param int $sentCount Number of notifications sent
|
|
* @param int $recordCount Number of records found
|
|
* @param int $newCount Number of new records (if applicable)
|
|
* @param float|null $duration Execution duration in seconds
|
|
* @return void
|
|
*/
|
|
function logNotificationComplete(string $commandName, int $sentCount = 0, int $recordCount = 0, int $newCount = 0, ?float $duration = null)
|
|
{
|
|
logNotificationCommand($commandName, 'completed', [
|
|
'sent_count' => $sentCount,
|
|
'record_count' => $recordCount,
|
|
'new_count' => $newCount,
|
|
'duration_seconds' => $duration ? round($duration, 2) : null,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Log notification command skip
|
|
*
|
|
* @param string $commandName
|
|
* @param string $reason Reason for skipping
|
|
* @return void
|
|
*/
|
|
function logNotificationSkip(string $commandName, string $reason)
|
|
{
|
|
logNotificationCommand($commandName, 'skipped', [
|
|
'reason' => $reason,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Log notification command error
|
|
*
|
|
* @param string $commandName
|
|
* @param string $errorMessage
|
|
* @param array $context Additional context
|
|
* @return void
|
|
*/
|
|
function logNotificationError(string $commandName, string $errorMessage, array $context = [])
|
|
{
|
|
logNotificationCommand($commandName, 'error', array_merge([
|
|
'error' => $errorMessage,
|
|
], $context));
|
|
}
|
|
|
|
/**
|
|
* Get notification log summary for a specific date
|
|
*
|
|
* @param string|null $date Date in Y-m-d format (default: today)
|
|
* @return array
|
|
*/
|
|
function getNotificationLogSummary(?string $date = null): array
|
|
{
|
|
$date = $date ?: date('Y-m-d');
|
|
$logFile = storage_path('logs/notifications-' . $date . '.log');
|
|
|
|
if (!file_exists($logFile)) {
|
|
return [
|
|
'date' => $date,
|
|
'total_executions' => 0,
|
|
'completed' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'total_notifications_sent' => 0,
|
|
'commands' => [],
|
|
];
|
|
}
|
|
|
|
$content = file_get_contents($logFile);
|
|
$lines = explode("\n", trim($content));
|
|
|
|
$summary = [
|
|
'date' => $date,
|
|
'total_executions' => 0,
|
|
'completed' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'total_notifications_sent' => 0,
|
|
'commands' => [],
|
|
];
|
|
|
|
foreach ($lines as $line) {
|
|
if (empty(trim($line))) continue;
|
|
|
|
// Parse log line: [timestamp] status | command | data
|
|
// Handle both command logs and scheduler logs
|
|
if (preg_match('/\[([^\]]+)\]\s+(\w+)\s+\|\s+([^\|]+)\s+\|\s+(.+)/', $line, $matches)) {
|
|
$timestamp = $matches[1];
|
|
$status = trim($matches[2]);
|
|
$command = trim($matches[3]);
|
|
$dataJson = trim($matches[4]);
|
|
|
|
// Check if it's a scheduler log
|
|
if ($command === 'SCHEDULER') {
|
|
$data = json_decode($dataJson, true);
|
|
if (isset($data['command'])) {
|
|
// Scheduler log for a specific command
|
|
$scheduledCommand = $data['command'];
|
|
|
|
if ($status === 'scheduled') {
|
|
// Command was scheduled to run
|
|
if (!isset($summary['commands'][$scheduledCommand])) {
|
|
$summary['commands'][$scheduledCommand] = [
|
|
'executions' => 0,
|
|
'completed' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'total_sent' => 0,
|
|
'scheduled_count' => 0,
|
|
];
|
|
}
|
|
$summary['commands'][$scheduledCommand]['scheduled_count']++;
|
|
}
|
|
// Note: 'finished' status is just informational, actual completion is logged by command itself
|
|
}
|
|
continue;
|
|
}
|
|
|
|
$summary['total_executions']++;
|
|
|
|
if ($status === 'completed') {
|
|
$summary['completed']++;
|
|
$data = json_decode($dataJson, true);
|
|
if (isset($data['sent_count'])) {
|
|
$summary['total_notifications_sent'] += $data['sent_count'];
|
|
}
|
|
|
|
if (!isset($summary['commands'][$command])) {
|
|
$summary['commands'][$command] = [
|
|
'executions' => 0,
|
|
'completed' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'total_sent' => 0,
|
|
'scheduled_count' => 0,
|
|
];
|
|
}
|
|
|
|
$summary['commands'][$command]['executions']++;
|
|
$summary['commands'][$command]['completed']++;
|
|
if (isset($data['sent_count'])) {
|
|
$summary['commands'][$command]['total_sent'] += $data['sent_count'];
|
|
}
|
|
} elseif ($status === 'skipped') {
|
|
$summary['skipped']++;
|
|
|
|
if (!isset($summary['commands'][$command])) {
|
|
$summary['commands'][$command] = [
|
|
'executions' => 0,
|
|
'completed' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'total_sent' => 0,
|
|
'scheduled_count' => 0,
|
|
];
|
|
}
|
|
|
|
$summary['commands'][$command]['executions']++;
|
|
$summary['commands'][$command]['skipped']++;
|
|
} elseif ($status === 'error') {
|
|
$summary['errors']++;
|
|
|
|
if (!isset($summary['commands'][$command])) {
|
|
$summary['commands'][$command] = [
|
|
'executions' => 0,
|
|
'completed' => 0,
|
|
'skipped' => 0,
|
|
'errors' => 0,
|
|
'total_sent' => 0,
|
|
'scheduled_count' => 0,
|
|
];
|
|
}
|
|
|
|
$summary['commands'][$command]['executions']++;
|
|
$summary['commands'][$command]['errors']++;
|
|
}
|
|
}
|
|
}
|
|
|
|
return $summary;
|
|
}
|