Merge pull request '(FIX): Needed some work on the logging and handlers.' (#81) from dev into master
All checks were successful
Deploy application with Docker / build_and_deploy (push) Successful in 1m3s

Reviewed-on: #81
This commit is contained in:
Hayden Hargreaves 2026-01-27 12:37:58 -07:00
commit 6b2b17b0ba
4 changed files with 50 additions and 15 deletions

1
.gitignore vendored
View File

@ -1,3 +1,4 @@
/flake.lock
/.env
/*.dump
/*.log

View File

@ -1,12 +1,12 @@
package main
import "github.com/haydenhargreaves/Potion/internal/app/server"
import (
"github.com/haydenhargreaves/Potion/internal/app/server"
)
const PORT = 3000
func main() {
s := server.Init(PORT).Setup()
defer s.DB.Close()
s.Start()
}

View File

@ -4,7 +4,10 @@ import (
"database/sql"
"fmt"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"github.com/a-h/templ/examples/integration-gin/gintemplrenderer"
"github.com/gin-contrib/cors"
@ -20,22 +23,24 @@ import (
)
type Server struct {
port int
Router *gin.Engine
config cors.Config
DB *sql.DB
deps domain.InjectedDependencies
logs []logging.Logger
port int
Router *gin.Engine
config cors.Config
DB *sql.DB
deps domain.InjectedDependencies
logs []logging.Logger
cleanupFuncs []func() error
}
// Init initializes the server with the provided port. CORS settings are defined here.
// A pointer to a server object is returned which allows for method chaining.
func Init(port int) *Server {
server := &Server{
Router: gin.New(), // Not default anymore, to allow for custom logger
port: port,
config: cors.DefaultConfig(),
logs: []logging.Logger{},
Router: gin.New(), // Not default anymore, to allow for custom logger
port: port,
config: cors.DefaultConfig(),
logs: []logging.Logger{},
cleanupFuncs: []func() error{},
}
// Default logger which logs everything
@ -66,7 +71,33 @@ func Init(port int) *Server {
// Start starts the server on the port provided when the server was initialized
func (s *Server) Start() {
logging.LogAll(s.logs, logging.LogLevelDebug, "Server started on :%d\n", s.port)
s.Router.Run(fmt.Sprintf(":%d", s.port))
// Create channel that only listens for SIGINT and SIGTERM
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
go func() {
if err := s.Router.Run(fmt.Sprintf(":%d", s.port)); err != nil {
logging.LogAll(s.logs, logging.LogLevelFatal, "Server failed: %s\n", err)
}
}()
// Block until we get a message on the quit channel
<-quit
logging.LogAll(s.logs, logging.LogLevelInfo, "Shutting down server...\n")
s.cleanup()
logging.LogAll(s.logs, logging.LogLevelInfo, "Server exited\n")
}
func (s *Server) cleanup() {
for _, cleanup := range s.cleanupFuncs {
// NOTE: Ignoring error
cleanup()
}
if s.DB != nil {
s.DB.Close()
}
}
// TODO: (9/4/2025) Abstract these functions and cleanup. This is fucking messy...
@ -121,7 +152,7 @@ func (s *Server) Setup() *Server {
} else {
logging.LogAll(s.logs, logging.LogLevelDebug, "Initialized file logger on file '%s'\n", cfg.LogFilePath)
s.logs = append(s.logs, fileLogger)
defer cleanup()
s.cleanupFuncs = append(s.cleanupFuncs, cleanup)
}
}

View File

@ -11,6 +11,7 @@ import (
type FileLogger struct {
writer io.Writer
file *os.File
filter logging.LogLevel
}
@ -34,6 +35,7 @@ func NewFileLogger(filepath string, filter logging.LogLevel) (logging.Logger, fu
logger := &FileLogger{
writer: f,
file: f,
filter: filter,
}
@ -55,4 +57,5 @@ func (l *FileLogger) Log(level logging.LogLevel, format string, v ...any) {
fullFormat := fmt.Sprintf("%-13s %s | %s\n", "["+level+"]", timestamp, format)
bytes := fmt.Appendf(nil, fullFormat, v...)
l.writer.Write(bytes)
l.file.Sync()
}