diff --git a/app/Http/Controllers/PingController.php b/app/Http/Controllers/PingController.php index dd4b675d59..5827756deb 100644 --- a/app/Http/Controllers/PingController.php +++ b/app/Http/Controllers/PingController.php @@ -81,4 +81,34 @@ class PingController extends BaseController return response()->json(SystemHealth::check(), 200); } + + /** + * Get the last error from storage/logs/laravel.log + * + * @return Response| \Illuminate\Http\JsonResponse + * + * @OA\Get( + * path="/api/v1/last_error", + * operationId="getLastError", + * tags={"last_error"}, + * summary="Get the last error from storage/logs/laravel.log", + * description="Get the last error from storage/logs/laravel.log", + * @OA\Parameter(ref="#/components/parameters/X-Requested-With"), + * @OA\Response( + * response=200, + * description="The last error from the logs", + * @OA\Header(header="X-MINIMUM-CLIENT-VERSION", ref="#/components/headers/X-MINIMUM-CLIENT-VERSION"), + * @OA\Header(header="X-RateLimit-Remaining", ref="#/components/headers/X-RateLimit-Remaining"), + * @OA\Header(header="X-RateLimit-Limit", ref="#/components/headers/X-RateLimit-Limit"), + * ) + * ) + */ + public function lastError() + { + if (Ninja::isNinja() || ! auth()->user()->isAdmin()) { + return response()->json(['message' => ctrans('texts.route_not_available'), 'errors' => []], 403); + } + + return response()->json(['last_error' => SystemHealth::lastError()], 200); + } } diff --git a/app/Utils/SystemHealth.php b/app/Utils/SystemHealth.php index 7c01643fe3..96522a0427 100644 --- a/app/Utils/SystemHealth.php +++ b/app/Utils/SystemHealth.php @@ -322,4 +322,23 @@ class SystemHealth { return is_writable(base_path().'/.env'); } + + public static function lastError() + { + $filepath = storage_path('logs/laravel.log'); + $file = escapeshellarg($filepath); + $end_of_file = `tail -n 500 $file`; + + $lines = explode("\n", $end_of_file); + $last_error = ''; + + foreach ($lines as $line) { + // Match the main error, ie. [2024-07-10 12:23:07] production.ERROR: ... + if (substr($line, 0, 2) === '[2') { + $last_error = $line; + } + } + + return $last_error; + } } diff --git a/routes/api.php b/routes/api.php index c370770471..0b0ffa772b 100644 --- a/routes/api.php +++ b/routes/api.php @@ -152,6 +152,7 @@ Route::group(['middleware' => ['throttle:api', 'api_db', 'token_auth', 'locale'] Route::post('check_subdomain', [SubdomainController::class, 'index'])->name('check_subdomain'); Route::get('ping', [PingController::class, 'index'])->name('ping'); Route::get('health_check', [PingController::class, 'health'])->name('health_check'); + Route::get('last_error', [PingController::class, 'lastError'])->name('last_error'); Route::get('activities', [ActivityController::class, 'index']); Route::post('activities/entity', [ActivityController::class, 'entityActivity']);