Merge pull request #5038 from Vann-Dev/main
feat(api): add applications logs api
This commit is contained in:
		@@ -1388,6 +1388,108 @@ class ApplicationsController extends Controller
 | 
			
		||||
        return response()->json($this->removeSensitiveData($application));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[OA\Get(
 | 
			
		||||
        summary: 'Get application logs.',
 | 
			
		||||
        description: 'Get application logs by UUID.',
 | 
			
		||||
        path: '/applications/{uuid}/logs',
 | 
			
		||||
        operationId: 'get-application-logs-by-uuid',
 | 
			
		||||
        security: [
 | 
			
		||||
            ['bearerAuth' => []],
 | 
			
		||||
        ],
 | 
			
		||||
        tags: ['Applications'],
 | 
			
		||||
        parameters: [
 | 
			
		||||
            new OA\Parameter(
 | 
			
		||||
                name: 'uuid',
 | 
			
		||||
                in: 'path',
 | 
			
		||||
                description: 'UUID of the application.',
 | 
			
		||||
                required: true,
 | 
			
		||||
                schema: new OA\Schema(
 | 
			
		||||
                    type: 'string',
 | 
			
		||||
                    format: 'uuid',
 | 
			
		||||
                )
 | 
			
		||||
            ),
 | 
			
		||||
            new OA\Parameter(
 | 
			
		||||
                name: 'lines',
 | 
			
		||||
                in: 'query',
 | 
			
		||||
                description: 'Number of lines to show from the end of the logs.',
 | 
			
		||||
                required: false,
 | 
			
		||||
                schema: new OA\Schema(
 | 
			
		||||
                    type: 'integer',
 | 
			
		||||
                    format: 'int32',
 | 
			
		||||
                    default: 100,
 | 
			
		||||
                )
 | 
			
		||||
            ),
 | 
			
		||||
        ],
 | 
			
		||||
        responses: [
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
                response: 200,
 | 
			
		||||
                description: 'Get application logs by UUID.',
 | 
			
		||||
                content: [
 | 
			
		||||
                    new OA\MediaType(
 | 
			
		||||
                        mediaType: 'application/json',
 | 
			
		||||
                        schema: new OA\Schema(
 | 
			
		||||
                            type: 'object',
 | 
			
		||||
                            properties: [
 | 
			
		||||
                                'logs' => ['type' => 'string'],
 | 
			
		||||
                            ]
 | 
			
		||||
                        )
 | 
			
		||||
                    ),
 | 
			
		||||
                ]
 | 
			
		||||
            ),
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
                response: 401,
 | 
			
		||||
                ref: '#/components/responses/401',
 | 
			
		||||
            ),
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
                response: 400,
 | 
			
		||||
                ref: '#/components/responses/400',
 | 
			
		||||
            ),
 | 
			
		||||
            new OA\Response(
 | 
			
		||||
                response: 404,
 | 
			
		||||
                ref: '#/components/responses/404',
 | 
			
		||||
            ),
 | 
			
		||||
        ]
 | 
			
		||||
    )]
 | 
			
		||||
    public function logs_by_uuid(Request $request)
 | 
			
		||||
    {
 | 
			
		||||
        $teamId = getTeamIdFromToken();
 | 
			
		||||
        if (is_null($teamId)) {
 | 
			
		||||
            return invalidTokenResponse();
 | 
			
		||||
        }
 | 
			
		||||
        $uuid = $request->route('uuid');
 | 
			
		||||
        if (! $uuid) {
 | 
			
		||||
            return response()->json(['message' => 'UUID is required.'], 400);
 | 
			
		||||
        }
 | 
			
		||||
        $application = Application::ownedByCurrentTeamAPI($teamId)->where('uuid', $request->uuid)->first();
 | 
			
		||||
        if (! $application) {
 | 
			
		||||
            return response()->json(['message' => 'Application not found.'], 404);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $containers = getCurrentApplicationContainerStatus($application->destination->server, $application->id);
 | 
			
		||||
 | 
			
		||||
        if ($containers->count() == 0) {
 | 
			
		||||
            return response()->json([
 | 
			
		||||
                'message' => 'Application is not running.',
 | 
			
		||||
            ], 400);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $container = $containers->first();
 | 
			
		||||
 | 
			
		||||
        $status = getContainerStatus($application->destination->server, $container['Names']);
 | 
			
		||||
        if ($status !== 'running') {
 | 
			
		||||
            return response()->json([
 | 
			
		||||
                'message' => 'Application is not running.',
 | 
			
		||||
            ], 400);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        $lines = $request->query->get('lines', 100) ?: 100;
 | 
			
		||||
        $logs = getContainerLogs($application->destination->server, $container['ID'], $lines);
 | 
			
		||||
 | 
			
		||||
        return response()->json([
 | 
			
		||||
            'logs' => $logs,
 | 
			
		||||
        ]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[OA\Delete(
 | 
			
		||||
        summary: 'Delete',
 | 
			
		||||
        description: 'Delete application by UUID.',
 | 
			
		||||
 
 | 
			
		||||
@@ -852,6 +852,23 @@ function validateComposeFile(string $compose, int $server_id): string|Throwable
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function getContainerLogs(Server $server, string $container_id, int $lines = 100): string
 | 
			
		||||
{
 | 
			
		||||
    if ($server->isSwarm()) {
 | 
			
		||||
        $output = instant_remote_process([
 | 
			
		||||
            "docker service logs -n {$lines} {$container_id}",
 | 
			
		||||
        ], $server);
 | 
			
		||||
    } else {
 | 
			
		||||
        $output = instant_remote_process([
 | 
			
		||||
            "docker logs -n {$lines} {$container_id}",
 | 
			
		||||
        ], $server);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $output .= removeAnsiColors($output);
 | 
			
		||||
 | 
			
		||||
    return $output;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function escapeEnvVariables($value)
 | 
			
		||||
{
 | 
			
		||||
    $search = ['\\', "\r", "\t", "\x0", '"', "'"];
 | 
			
		||||
 
 | 
			
		||||
@@ -88,6 +88,7 @@ Route::group([
 | 
			
		||||
    Route::patch('/applications/{uuid}/envs', [ApplicationsController::class, 'update_env_by_uuid'])->middleware(['api.ability:write']);
 | 
			
		||||
    Route::delete('/applications/{uuid}/envs/{env_uuid}', [ApplicationsController::class, 'delete_env_by_uuid'])->middleware(['api.ability:write']);
 | 
			
		||||
    // Route::post('/applications/{uuid}/execute', [ApplicationsController::class, 'execute_command_by_uuid'])->middleware(['ability:write']);
 | 
			
		||||
    Route::get('/applications/{uuid}/logs', [ApplicationsController::class, 'logs_by_uuid'])->middleware(['api.ability:read']);
 | 
			
		||||
 | 
			
		||||
    Route::match(['get', 'post'], '/applications/{uuid}/start', [ApplicationsController::class, 'action_deploy'])->middleware(['api.ability:write']);
 | 
			
		||||
    Route::match(['get', 'post'], '/applications/{uuid}/restart', [ApplicationsController::class, 'action_restart'])->middleware(['api.ability:write']);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user