better logging

This commit is contained in:
Simon Martens
2024-11-16 17:30:14 +01:00
parent 527fbfa000
commit 84fa6f7fa4
17 changed files with 221 additions and 106 deletions

1
.gitignore vendored
View File

@@ -1,4 +1,5 @@
KGPZ/
tmp/
data_git/
cache_geo/
cache_gnd/

View File

@@ -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() {

View File

@@ -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})
}
}

View File

@@ -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)
}

View File

@@ -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.

View File

@@ -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)
}
}

View File

@@ -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)
}

57
helpers/parselog.go Normal file
View File

@@ -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)
}

View File

@@ -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)
}
}
}()

View File

@@ -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.")
}

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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.")
}
}
}()

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
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

BIN
tmp/main

Binary file not shown.