package log import ( "bufio" "fmt" "jannex/log-manager/modules/cache" "jannex/log-manager/modules/config" "jannex/log-manager/modules/loghandler" "jannex/log-manager/modules/structs" "jannex/log-manager/modules/utils" "github.com/gofiber/fiber/v2" futils "github.com/gofiber/fiber/v2/utils" "github.com/google/uuid" "github.com/valyala/fasthttp" ) func AddLog(c *fiber.Ctx) error { // swagger:operation POST /v1/log log addLog // --- // summary: Add a log to the log file. You can specify multiple logs at once // consumes: // - application/json // produces: // - application/json // parameters: // - name: body // in: body // description: The log to add // required: true // schema: // "$ref": "#/definitions/LogBody" // responses: // '200': // description: Successfully added log // '400': // description: Invalid request body var body structs.LogBody if err := utils.BodyParserHelper(c, &body); err != nil { return c.SendStatus(fiber.StatusBadRequest) } loghandler.AddLog(body) return c.SendStatus(fiber.StatusOK) } func GetLog(c *fiber.Ctx) error { // swagger:operation GET /v1/logs/{type} logs getLog // --- // summary: Get the log file for the specified type // consumes: // - application/json // produces: // - application/json // parameters: // - name: type // in: path // description: The type of log to get // required: true // type: string // - name: d // in: query // description: The date of the log to get // required: false // type: string // - name: f // in: query // description: The filter to apply to the log // required: false // type: string // responses: // '200': // description: Successfully got log. Returns an array of strings // '400': // description: Invalid request body // '422': // description: No log file found for the specified type or date var params structs.GetLogParams if err := utils.ParamsParserHelper(c, ¶ms); err != nil { return c.SendStatus(fiber.StatusBadRequest) } var query structs.GetLogQuery if err := utils.QueryParserHelper(c, &query); err != nil { return c.SendStatus(fiber.StatusBadRequest) } fmt.Println("params", params, "query", query) // no type specified if params.Type == "" { return c.SendStatus(fiber.StatusBadRequest) } // no date specified -> return all available files if query.D == "" { availableLogs, err := loghandler.GetAvailableLogFiles(params.Type) if err != nil { return c.SendStatus(fiber.StatusUnprocessableEntity) } return c.JSON(availableLogs) } logs, err := loghandler.GetLogByDate(params.Type, query.D) if err != nil { return c.SendStatus(fiber.StatusUnprocessableEntity) } return c.JSON(logs) } func GetAvailableLogTypes(c *fiber.Ctx) error { // swagger:operation GET /v1/log/types log getAvailableLogTypes // --- // summary: Get the available log types // consumes: // - application/json // produces: // - application/json // responses: // '200': // description: Successfully got log types. Returns an array of strings logTypes := loghandler.GetAvailableLogTypes() return c.JSON(logTypes) } func SSE(c *fiber.Ctx) error { if !config.Cfg.SSEServerEnabled { return c.SendStatus(fiber.StatusNotFound) } logType := futils.CopyString(c.Params("logType")) date := futils.CopyString(c.Params("date")) c.Set("Content-Type", "text/event-stream") c.Set("Cache-Control", "no-cache") c.Set("Connection", "keep-alive") c.Set("Transfer-Encoding", "chunked") c.Context().SetBodyStreamWriter(fasthttp.StreamWriter(func(w *bufio.Writer) { var sseclient structs.SSEClient sseclient.MessageChannel = make(chan structs.SSEClientChannelMessage) sseclient.LogType = logType sseclient.Date = date clientId := uuid.New() cache.SSEClients[clientId] = sseclient for message := range sseclient.MessageChannel { fmt.Fprintf(w, "data: %s\n\n", message.Message) err := w.Flush() if err != nil { // Refreshing page in web browser will establish a new // SSE connection, but only (the last) one is alive, so // dead connections must be closed here. for id, sseClient := range cache.SSEClients { if id == message.ClientId { close(sseClient.MessageChannel) delete(cache.SSEClients, id) } } } } })) return nil }