feat(api): updated docker logs api

- Refactored docker logs endpoint to use container ID directly.
This commit is contained in:
yusing
2025-09-14 00:10:37 +08:00
parent 1e1999b0af
commit 59cae0967a
2 changed files with 24 additions and 19 deletions

View File

@@ -122,7 +122,7 @@ func NewHandler() *gin.Engine {
{
docker.GET("/containers", dockerApi.Containers)
docker.GET("/info", dockerApi.Info)
docker.GET("/logs/:server/:container", dockerApi.Logs)
docker.GET("/logs/:id", dockerApi.Logs)
}
}

View File

@@ -3,6 +3,7 @@ package dockerapi
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/docker/docker/api/types/container"
@@ -10,15 +11,11 @@ import (
"github.com/gin-gonic/gin"
"github.com/rs/zerolog/log"
apitypes "github.com/yusing/go-proxy/internal/api/types"
"github.com/yusing/go-proxy/internal/docker"
"github.com/yusing/go-proxy/internal/net/gphttp/websocket"
"github.com/yusing/go-proxy/internal/task"
)
type LogsPathParams struct {
Server string `uri:"server" binding:"required"`
ContainerID string `uri:"container" binding:"required"`
} // @name LogsPathParams
type LogsQueryParams struct {
Stdout bool `form:"stdout,default=true"`
Stderr bool `form:"stderr,default=true"`
@@ -30,12 +27,11 @@ type LogsQueryParams struct {
// @x-id "logs"
// @BasePath /api/v1
// @Summary Get docker container logs
// @Description Get docker container logs
// @Description Get docker container logs by container id
// @Tags docker,websocket
// @Accept json
// @Produce json
// @Param server path string true "server name"
// @Param container path string true "container id"
// @Param id path string true "container id"
// @Param stdout query bool false "show stdout"
// @Param stderr query bool false "show stderr"
// @Param from query string false "from timestamp"
@@ -44,31 +40,40 @@ type LogsQueryParams struct {
// @Success 200
// @Failure 400 {object} apitypes.ErrorResponse
// @Failure 403 {object} apitypes.ErrorResponse
// @Failure 404 {object} apitypes.ErrorResponse
// @Failure 404 {object} apitypes.ErrorResponse "server not found or container not found"
// @Failure 500 {object} apitypes.ErrorResponse
// @Router /docker/logs/{server}/{container} [get]
// @Router /docker/logs/{id} [get]
func Logs(c *gin.Context) {
var pathParams LogsPathParams
id := c.Param("id")
if id == "" {
c.JSON(http.StatusBadRequest, apitypes.Error("container id is required"))
return
}
var queryParams LogsQueryParams
if err := c.ShouldBindQuery(&queryParams); err != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid query params"))
return
}
if err := c.ShouldBindUri(&pathParams); err != nil {
c.JSON(http.StatusBadRequest, apitypes.Error("invalid path params"))
// TODO: implement levels
dockerHost, ok := docker.GetDockerHostByContainerID(id)
if !ok {
c.JSON(http.StatusNotFound, apitypes.Error(fmt.Sprintf("container %s not found in %s", id, c.GetString("server"))))
return
}
// TODO: implement levels
dockerClient, found, err := getDockerClient(pathParams.Server)
dockerClient, found, err := getDockerClient(dockerHost)
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to get docker client"))
return
}
if !found {
c.JSON(http.StatusNotFound, apitypes.Error("server not found"))
return
}
defer dockerClient.Close()
opts := container.LogsOptions{
@@ -84,7 +89,7 @@ func Logs(c *gin.Context) {
opts.Details = true
}
logs, err := dockerClient.ContainerLogs(c.Request.Context(), pathParams.ContainerID, opts)
logs, err := dockerClient.ContainerLogs(c.Request.Context(), id, opts)
if err != nil {
c.Error(apitypes.InternalServerError(err, "failed to get container logs"))
return
@@ -106,8 +111,8 @@ func Logs(c *gin.Context) {
return
}
log.Err(err).
Str("server", pathParams.Server).
Str("container", pathParams.ContainerID).
Str("server", dockerHost).
Str("container", id).
Msg("failed to de-multiplex logs")
}
}