diff --git a/.gitignore b/.gitignore index 08293a2..ae236fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ KGPZ/ +tmp/ data_git/ cache_geo/ cache_gnd/ diff --git a/app/kgpz.go b/app/kgpz.go index 924ad8e..90c33e4 100644 --- a/app/kgpz.go +++ b/app/kgpz.go @@ -6,6 +6,7 @@ import ( "sync" "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" "github.com/Theodor-Springmann-Stiftung/kgpz_web/providers" ) @@ -44,12 +45,9 @@ func (k *KGPZ) Init() { } func NewKGPZ(config *providers.ConfigProvider) *KGPZ { - if config == nil { - panic("ConfigProvider is nil") - } - + helpers.AssertNonNil(config, "Config is nil") if err := config.Validate(); err != nil { - helpers.MaybePanic(err, "Error validating config") + helpers.Assert(err, "Error validating config") } return &KGPZ{Config: config} @@ -65,10 +63,10 @@ func (k *KGPZ) Serialize() { defer k.gmu.Unlock() issues, err := getXMLFiles(filepath.Join(k.Config.FolderPath, ISSUES_DIR)) - helpers.MaybePanic(err, "Error getting issues") + helpers.Assert(err, "Error getting issues") pieces, err := getXMLFiles(filepath.Join(k.Config.FolderPath, PIECES_DIR)) - helpers.MaybePanic(err, "Error getting pieces") + helpers.Assert(err, "Error getting pieces") lib := providers.NewLibrary( []string{filepath.Join(k.Config.FolderPath, AGENTS_PATH)}, @@ -122,6 +120,7 @@ func (k *KGPZ) IsDebug() bool { func (k *KGPZ) Pull() { go func() { + logging.Info("Pulling Repository...") k.gmu.Lock() if k.Repo == nil { @@ -130,17 +129,13 @@ func (k *KGPZ) Pull() { } err, changed := k.Repo.Pull() - if err != nil { - helpers.LogOnErr(&k.Repo, err, "Error pulling repo") - } + logging.Error(err, "Error pulling GitProvider") // Need to unlock here to prevent deadlock, since Serialize locks the same mutex k.gmu.Unlock() if changed { - if k.IsDebug() { - helpers.LogOnDebug(&k.Repo, "GitProvider changed") - } + logging.ObjDebug(&k.Repo, "Remote changed. Reparsing...") k.Serialize() } }() @@ -149,7 +144,7 @@ func (k *KGPZ) Pull() { func (k *KGPZ) initRepo() { gp, err := providers.NewGitProvider(k.Config.Config.GitURL, k.Config.Config.FolderPath, k.Config.Config.GitBranch) if err != nil { - helpers.LogOnErr(&gp, err, "Error creating GitProvider") + logging.ObjErr(&gp, err, "Error creating GitProvider") return } @@ -158,9 +153,7 @@ func (k *KGPZ) initRepo() { k.gmu.Unlock() k.Pull() - if k.IsDebug() { - helpers.LogOnDebug(&gp, "GitProvider") - } + logging.ObjDebug(&k.Repo, "GitProvider initialized") } func (k *KGPZ) Shutdown() { diff --git a/controllers/years.go b/controllers/years.go index 21e6872..8aa5841 100644 --- a/controllers/years.go +++ b/controllers/years.go @@ -5,9 +5,13 @@ import ( "github.com/gofiber/fiber/v2" ) +const ( + START_YEAR = "1764" +) + func GetYear(kgpz *app.KGPZ) fiber.Handler { return func(c *fiber.Ctx) error { - y := c.Params("year", "1764") + y := c.Params("year", START_YEAR) if len(y) != 4 { return c.SendStatus(fiber.StatusBadRequest) } @@ -16,6 +20,7 @@ func GetYear(kgpz *app.KGPZ) fiber.Handler { if len(issues.Issues) == 0 { return c.SendStatus(fiber.StatusNotFound) } + return c.Render("/", fiber.Map{"model": issues}) } } diff --git a/helpers/errors.go b/helpers/errors.go index 0fb0940..2d8c29a 100644 --- a/helpers/errors.go +++ b/helpers/errors.go @@ -1,24 +1,43 @@ package helpers import ( - "fmt" "os" + + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" ) -func Panic(err error, msg string) { - fmt.Println(msg) - if err != nil { - fmt.Println("Error: ", err) - } - os.Exit(1) -} - -func MaybePanic(err error, msg string) { +func Assert(err error, msg ...string) { if err == nil { return } - fmt.Println(msg) - fmt.Println("Error: ", err) + logging.Error(err, msg...) + os.Exit(1) +} + +func AssertNonNil(obj interface{}, msg ...string) { + if obj != nil { + return + } + + logging.Error(nil, msg...) + os.Exit(1) +} + +func AssertNil(obj interface{}, msg ...string) { + if obj == nil { + return + } + + logging.Error(nil, msg...) + os.Exit(1) +} + +func AssertStr(str string, msg ...string) { + if str != "" { + return + } + + logging.Error(nil, msg...) os.Exit(1) } diff --git a/helpers/evmux.go b/helpers/evmux.go index 6d4778f..067faf0 100644 --- a/helpers/evmux.go +++ b/helpers/evmux.go @@ -1,6 +1,8 @@ package helpers -import "sync" +import ( + "sync" +) type EventMux[T any] struct { // INFO: This is a simple event multiplexer that allows to subscribe to events and to publish them. diff --git a/helpers/logging.go b/helpers/logging.go deleted file mode 100644 index 2609157..0000000 --- a/helpers/logging.go +++ /dev/null @@ -1,26 +0,0 @@ -package helpers - -import "fmt" - -func LogOnDebug[T fmt.Stringer](object *T, msg string) { - if msg != "" { - fmt.Println(msg) - } - - if object != nil { - fmt.Println(*object) - } -} - -func LogOnErr[T fmt.Stringer](object *T, err error, msg string) { - if err != nil { - if msg != "" { - fmt.Println(msg) - } - - if object != nil { - fmt.Println(*object) - } - fmt.Println("Error: ", err) - } -} diff --git a/helpers/logging/logging.go b/helpers/logging/logging.go new file mode 100644 index 0000000..4b44850 --- /dev/null +++ b/helpers/logging/logging.go @@ -0,0 +1,66 @@ +package logging + +import ( + "fmt" + "log/slog" +) + +func ObjDebug[T fmt.Stringer](object *T, msg string) { + if msg != "" { + slog.Debug(msg) + } + + if object != nil { + obj := *object + slog.Debug(obj.String()) + } +} + +func ObjErr[T fmt.Stringer](object *T, err error, msg ...string) { + if err == nil { + return + } + + if len(msg) > 0 { + for _, m := range msg { + slog.Error(m) + } + } + + if object != nil { + obj := *object + slog.Debug(obj.String()) + } + + slog.Error(err.Error()) +} + +func Error(err error, msg ...string) { + if err == nil { + return + } + + if len(msg) > 0 { + for _, m := range msg { + slog.Error(m) + } + } + + slog.Error(err.Error()) +} + +func Info(msg ...string) { + if len(msg) > 0 { + for _, m := range msg { + slog.Info(m) + } + } +} + +func SetDebug() { + slog.SetLogLoggerLevel(slog.LevelDebug) +} + +func SetInfo() { + slog.SetLogLoggerLevel(slog.LevelInfo) +} diff --git a/helpers/parselog.go b/helpers/parselog.go new file mode 100644 index 0000000..1c768b0 --- /dev/null +++ b/helpers/parselog.go @@ -0,0 +1,57 @@ +package helpers + +import "sync" + +type LogMessage struct { + Commit string + File string + Message string + Fatal bool +} + +type ParseLogger struct { + mu sync.Mutex + Messages []LogMessage +} + +func NewParseLog() *ParseLogger { + return &ParseLogger{ + Messages: make([]LogMessage, 0), + } +} + +func (p *ParseLogger) AddMessage(commit, file, message string, fatal bool) { + p.mu.Lock() + defer p.mu.Unlock() + p.Messages = append(p.Messages, LogMessage{ + Commit: commit, + File: file, + Message: message, + Fatal: fatal, + }) +} + +func (p *ParseLogger) Fatal() bool { + p.mu.Lock() + defer p.mu.Unlock() + for _, m := range p.Messages { + if m.Fatal { + return true + } + } + return false +} + +func (p *ParseLogger) GetMessages() []LogMessage { + p.mu.Lock() + defer p.mu.Unlock() + res := make([]LogMessage, len(p.Messages)) + copy(res, p.Messages) + return res +} + +func (p *ParseLogger) Clear() { + p.mu.Lock() + defer p.mu.Unlock() + p.Messages = make([]LogMessage, 0) +} diff --git a/helpers/watcher.go b/helpers/watcher.go index c2adb25..413a5cd 100644 --- a/helpers/watcher.go +++ b/helpers/watcher.go @@ -3,10 +3,10 @@ package helpers import ( "errors" "io/fs" - "log" "path/filepath" "sync" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" "github.com/fsnotify/fsnotify" ) @@ -96,7 +96,6 @@ func (fw *FileWatcher) Watch() error { return } if !event.Has(fsnotify.Chmod) { - log.Println("event:", event) fw.mu.Lock() for _, wf := range fw.wf { wf(event.Name) @@ -107,7 +106,7 @@ func (fw *FileWatcher) Watch() error { if !ok { return } - log.Println("error:", err) + logging.Error(err) } } }() diff --git a/kgpz_web.go b/kgpz_web.go index 54d7204..5560def 100644 --- a/kgpz_web.go +++ b/kgpz_web.go @@ -8,6 +8,7 @@ import ( "github.com/Theodor-Springmann-Stiftung/kgpz_web/app" "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" "github.com/Theodor-Springmann-Stiftung/kgpz_web/providers" "github.com/Theodor-Springmann-Stiftung/kgpz_web/server" ) @@ -31,7 +32,13 @@ const ( func main() { cfg := providers.NewConfigProvider([]string{DEV_CONFIG, DEFAULT_CONFIG}) if err := cfg.Read(); err != nil { - helpers.MaybePanic(err, "Error reading config") + helpers.Assert(err, "Error reading config") + } + + if cfg.Config.Debug { + logging.SetDebug() + } else { + logging.SetInfo() } kgpz := app.NewKGPZ(cfg) @@ -51,17 +58,17 @@ func Start(k *app.KGPZ, s *server.Server) { go func() { sig := <-sigs - fmt.Println("Received signal. Cleaning up.") + logging.Info("Signal received, Cleaning up...") // INFO: here we add cleanup functions if sig == syscall.SIGTERM { s.Stop() - fmt.Println("Server stopped. Waiting for FS.") + logging.Info("Server stopped. Waiting for FS.") } else { s.Kill() - fmt.Println("Server killed. Waiting for FS.") + logging.Info("Server killed. Waiting for FS.") } k.Shutdown() - fmt.Println("FS stopped. Exiting.") + logging.Info("Shutdown complete.") done <- true }() @@ -72,10 +79,8 @@ func Start(k *app.KGPZ, s *server.Server) { var input string fmt.Scanln(&input) if input == "r" { - fmt.Println("Restarting server.") s.Restart() } else if input == "p" { - fmt.Println("Pulling repo.") k.Pull() } else if input == "q" { sigs <- os.Signal(syscall.SIGTERM) @@ -85,5 +90,4 @@ func Start(k *app.KGPZ, s *server.Server) { } <-done - fmt.Println("Cleanup finished. Exiting.") } diff --git a/providers/config.go b/providers/config.go index ddf325f..e588fea 100644 --- a/providers/config.go +++ b/providers/config.go @@ -7,6 +7,7 @@ import ( "strings" "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" "github.com/kelseyhightower/envconfig" ) @@ -68,15 +69,14 @@ func (c *ConfigProvider) Validate() error { func readSettingsFile(cfg *Config, path string) *Config { f, err := os.Open(path) if err != nil { - fmt.Println("Error: ", err) - fmt.Println("Coudln't open ", path) + logging.Error(err, "Error opening config file "+path) return cfg } defer f.Close() dec := json.NewDecoder(f) err = dec.Decode(cfg) - helpers.MaybePanic(err, "Error decoding config.json") + helpers.Assert(err, "Error decoding config file") return cfg } diff --git a/providers/xmlprovider.go b/providers/xmlprovider.go index 97a070c..6cb0425 100644 --- a/providers/xmlprovider.go +++ b/providers/xmlprovider.go @@ -6,6 +6,8 @@ import ( "io" "os" "sync" + + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" ) type KGPZXML[T any] interface { @@ -48,7 +50,7 @@ func (l *Library) Serialize() { err := l.Agents.Serialize() if err != nil { l.Agents = nil - fmt.Println(err) + } }() @@ -57,7 +59,7 @@ func (l *Library) Serialize() { err := l.Places.Serialize() if err != nil { l.Places = nil - fmt.Println(err) + } }() @@ -66,7 +68,7 @@ func (l *Library) Serialize() { err := l.Works.Serialize() if err != nil { l.Works = nil - fmt.Println(err) + } }() @@ -75,7 +77,7 @@ func (l *Library) Serialize() { err := l.Categories.Serialize() if err != nil { l.Categories = nil - fmt.Println(err) + } }() @@ -84,7 +86,7 @@ func (l *Library) Serialize() { err := l.Issues.Serialize() if err != nil { l.Issues = nil - fmt.Println(err) + } }() @@ -93,7 +95,7 @@ func (l *Library) Serialize() { err := l.Pieces.Serialize() if err != nil { l.Pieces = nil - fmt.Println(err) + } }() @@ -109,7 +111,7 @@ func (p *XMLProvider[T]) Serialize() error { defer wg.Done() var data T if err := UnmarshalFile(path, &data); err != nil { - fmt.Println(err) + return } p.mu.Lock() @@ -131,11 +133,10 @@ func (a *XMLProvider[T]) String() string { func UnmarshalFile[T any](filename string, data *T) error { xmlFile, err := os.Open(filename) if err != nil { - fmt.Println(err) return err } - fmt.Println("Successfully opened " + filename) defer xmlFile.Close() + logging.Info("Opened " + filename) byteValue, _ := io.ReadAll(xmlFile) xml.Unmarshal(byteValue, data) diff --git a/server/server.go b/server/server.go index a440d41..7af034d 100644 --- a/server/server.go +++ b/server/server.go @@ -1,14 +1,13 @@ package server import ( - "fmt" - "log" "sync" "time" "github.com/Theodor-Springmann-Stiftung/kgpz_web/app" "github.com/Theodor-Springmann-Stiftung/kgpz_web/controllers" "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers/logging" "github.com/Theodor-Springmann-Stiftung/kgpz_web/providers" "github.com/Theodor-Springmann-Stiftung/kgpz_web/templating" "github.com/Theodor-Springmann-Stiftung/kgpz_web/views" @@ -55,7 +54,7 @@ type Server struct { func Create(k *app.KGPZ, c *providers.ConfigProvider) *Server { if c == nil || k == nil { - log.Println("Error creating server") + logging.Error(nil, "Config or KGPZ is posssibly nil while tying to create server") return nil } @@ -78,7 +77,7 @@ func (s *Server) Watcher() error { s.watcher = watcher s.watcher.Append(func(path string) { - log.Println("Restarting server") + logging.Info("File changed: ", path) time.Sleep(200 * time.Millisecond) s.Restart() }) @@ -159,10 +158,7 @@ func (s *Server) Start() { if s.Config.Debug { err := s.Watcher() - if err != nil { - log.Println("Error watching files") - log.Println(err) - } + logging.Error(err, "Error setting up file watcher") } } @@ -200,9 +196,10 @@ func (s *Server) runner(srv *fiber.App) { go func() { defer s.shutdown.Done() + + logging.Info("Starting server on ", s.Config.Address+":"+s.Config.Port) if err := srv.Listen(s.Config.Address + ":" + s.Config.Port); err != nil { - fmt.Println(err) - fmt.Println("Error starting server") + logging.Error(err, "Error starting server") return } @@ -213,16 +210,19 @@ func (s *Server) runner(srv *fiber.App) { defer cleanup.Done() clean := <-s.running + logging.Info("Server shutdown requested") + if clean { if err := srv.ShutdownWithTimeout(SERVER_TIMEOUT); err != nil { - fmt.Println(err) - fmt.Println("Error shutting down server") + logging.Error(err, "Error closing server cleanly. Shutting server down by force.") + clean = false } s.cache.Close() - } else { + } + + if !clean { if err := srv.ShutdownWithTimeout(0); err != nil { - fmt.Println(err) - fmt.Println("Error closing server") + logging.Error(err, "Error closing server by force.") } } }() diff --git a/templating/layout_registry.go b/templating/layout_registry.go index 7a6bf78..98add3e 100644 --- a/templating/layout_registry.go +++ b/templating/layout_registry.go @@ -1,11 +1,11 @@ package templating import ( - "fmt" "html/template" "io/fs" "sync" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" "github.com/yalue/merged_fs" ) @@ -36,10 +36,7 @@ func (r *LayoutRegistry) Register(fs fs.FS) *LayoutRegistry { func (r *LayoutRegistry) Load() error { r.once.Do(func() { err := r.load() - if err != nil { - fmt.Println(err) - panic(-1) - } + helpers.Assert(err, "Error loading layouts. Exiting.") }) return nil diff --git a/templating/template_registry.go b/templating/template_registry.go index 3b2e1fe..6d28287 100644 --- a/templating/template_registry.go +++ b/templating/template_registry.go @@ -1,13 +1,13 @@ package templating import ( - "fmt" "html/template" "io/fs" "os" "strings" "sync" + "github.com/Theodor-Springmann-Stiftung/kgpz_web/helpers" "github.com/yalue/merged_fs" ) @@ -36,10 +36,7 @@ func (r *TemplateRegistry) Register(path string, fs fs.FS) *TemplateRegistry { func (r *TemplateRegistry) Load() error { r.once.Do(func() { err := r.load() - if err != nil { - fmt.Println(err) - panic(-1) - } + helpers.Assert(err, "Error loading templates. Exiting.") }) return nil } diff --git a/tmp/build-errors.log b/tmp/build-errors.log index 67fc100..bfd43cc 100644 --- a/tmp/build-errors.log +++ b/tmp/build-errors.log @@ -1 +1 @@ -exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file +exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1exit status 1 \ No newline at end of file diff --git a/tmp/main b/tmp/main index df291b8..712aac5 100755 Binary files a/tmp/main and b/tmp/main differ