// Package classification JNX Log Manager API Documentation. // // Schemes: https // Host: jannex // BasePath: /v1 // Version: 1.0.0 // // Consumes: // - application/json // // Produces: // - application/json // // swagger:meta package main import ( "bufio" "fmt" "jannex/log-manager/modules/cache" "jannex/log-manager/modules/config" "jannex/log-manager/modules/structs" "jannex/log-manager/modules/utils" "jannex/log-manager/routers/router" "github.com/gofiber/fiber/v2" "github.com/gofiber/fiber/v2/middleware/cors" "github.com/gofiber/fiber/v2/middleware/logger" futils "github.com/gofiber/fiber/v2/utils" "github.com/google/uuid" "github.com/valyala/fasthttp" ) func init() { config.LoadConfig() utils.ValidatorInit() utils.CreateDirectoryIfNotExists(config.Cfg.LogFolder) } func main() { app := fiber.New(fiber.Config{ BodyLimit: 100 * 1024 * 1024, }) app.Use(cors.New(cors.Config{})) app.Use(logger.New(logger.Config{ Format: "${pid} ${locals:requestid} ${status} - ${latency} ${method} ${path}​\n", })) router.SetupRoutes(app) if config.Cfg.SSEServerEnabled { app.Get("/v1/log/sse/:logType/:date", func(c *fiber.Ctx) error { fmt.Println("GET /:logType/:date", c.Params("logType"), c.Params("date")) 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 fmt.Printf("NEW CLIENT %v", sseclient) fmt.Printf("%d CLIENTS CONNECTED", len(cache.SSEClients)) 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) fmt.Printf("DELETE clientId: %s", id) } } } } })) return nil }) } app.Listen(config.Cfg.Host + ":" + config.Cfg.Port) }