From 8f8d41413ff775b6d721059783a0e2de4f90f50c Mon Sep 17 00:00:00 2001 From: Bobby Date: Sat, 7 Mar 2026 15:09:42 +0530 Subject: feat: add configuration management and server setup - Implemented configuration file creation and loading in config.go. - Added default configuration content embedded in embed.go. - Introduced logging middleware for HTTP requests. - Created Makefile for build and setup automation. - Integrated Tailwind CSS and HTMX for frontend styling and interactivity. - Developed basic authentication flow with login and dashboard pages. - Enhanced error handling and user feedback in templates. - Updated dependencies in go.mod and go.sum. --- middleware/constants.go | 5 ++++ middleware/globals.go | 12 ++++++++ middleware/logging.go | 71 ++++++++++++++++++++++++++++++++++++++++++++++++ middleware/middleware.go | 3 ++ 4 files changed, 91 insertions(+) create mode 100644 middleware/constants.go create mode 100644 middleware/globals.go create mode 100644 middleware/logging.go (limited to 'middleware') diff --git a/middleware/constants.go b/middleware/constants.go new file mode 100644 index 0000000..dc6505b --- /dev/null +++ b/middleware/constants.go @@ -0,0 +1,5 @@ +package middleware + +const ( + LOG_PREFIX = "HTTP" +) diff --git a/middleware/globals.go b/middleware/globals.go new file mode 100644 index 0000000..8a186bb --- /dev/null +++ b/middleware/globals.go @@ -0,0 +1,12 @@ +package middleware + +import ( + "dove/config" + + "github.com/gofiber/fiber/v2" +) + +func globals(context *fiber.Ctx) error { + context.Locals("AuthEnabled", config.AuthEnabled) + return context.Next() +} diff --git a/middleware/logging.go b/middleware/logging.go new file mode 100644 index 0000000..15c82b6 --- /dev/null +++ b/middleware/logging.go @@ -0,0 +1,71 @@ +package middleware + +import ( + "fmt" + "strconv" + "strings" + "time" + + "dove/utils/logger" + + "github.com/gofiber/fiber/v2" +) + +func httpLogger() fiber.Handler { + return func(context *fiber.Ctx) error { + startTime := time.Now() + + responseError := context.Next() + + duration := time.Since(startTime) + statusCode := context.Response().StatusCode() + method := context.Method() + path := context.Path() + ipAddress := context.IP() + + paddedMethod := method + if len(method) < 7 { + paddedMethod = method + strings.Repeat(" ", 7-len(method)) + } + + message := fmt.Sprintf( + "%s %-3d %-15s %-10s %s", + paddedMethod, statusCode, "IP: "+ipAddress, "TTR: "+formatDuration(duration), "Path: "+path, + ) + + logByStatus(statusCode, LOG_PREFIX, message) + + return responseError + } +} + +func logByStatus(statusCode int, prefix string, message string) { + switch { + case statusCode >= fiber.StatusInternalServerError: + logger.Errorf(prefix, "%s", message) + case statusCode >= fiber.StatusBadRequest: + logger.Warnf(prefix, "%s", message) + case statusCode >= fiber.StatusMultipleChoices: + logger.Infof(prefix, "%s", message) + case statusCode >= fiber.StatusOK: + logger.Successf(prefix, "%s", message) + default: + logger.Infof(prefix, "%s", message) + } +} + +func formatDuration(duration time.Duration) string { + if duration < time.Microsecond { + return strconv.FormatInt(duration.Nanoseconds(), 10) + "ns" + } + + if duration < time.Millisecond { + return strconv.FormatInt(duration.Nanoseconds()/1_000, 10) + "µs" + } + + if duration < time.Second { + return strconv.FormatFloat(float64(duration.Nanoseconds())/float64(time.Millisecond), 'f', 3, 64) + "ms" + } + + return strconv.FormatFloat(float64(duration.Nanoseconds())/float64(time.Second), 'f', 3, 64) + "s" +} diff --git a/middleware/middleware.go b/middleware/middleware.go index dffc109..88e0820 100644 --- a/middleware/middleware.go +++ b/middleware/middleware.go @@ -7,6 +7,9 @@ import ( ) func Initialize(application *fiber.App) { + application.Use(httpLogger) + application.Use(globals) + switch config.AuthEnabled { case true: application.Use(authentication) -- cgit v1.2.3