Database is more usable now. All pages have been updated to use the database, and share an application configuration. Page Stack has been removed, no more pages hanging around in memory. Replaced with a 'Router' which uses an Enum to determine which page should be displayed, destroys the old page and initializes the new page all in one go. No more push, pop, rollback, etc. No more holding instances of pages. Logger has been updated with proper timestamps and sorting now works as expected."
102 lines
2.1 KiB
Go
102 lines
2.1 KiB
Go
package logger
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"rhemawavetech.com/rhemawave/internal/db"
|
|
)
|
|
|
|
type Level int
|
|
|
|
const (
|
|
LevelDebug Level = iota
|
|
LevelInfo
|
|
LevelWarning
|
|
LevelError
|
|
LevelFatal
|
|
)
|
|
|
|
func (l Level) String() string {
|
|
return [...]string{"DEBUG", "INFO", "WARNING", "ERROR", "FATAL"}[l]
|
|
}
|
|
|
|
var (
|
|
DB *gorm.DB
|
|
file *os.File
|
|
console = log.New(os.Stderr, "", 0)
|
|
)
|
|
|
|
// AddFile attaches or replaces the file backend
|
|
func AddFile(path string) error {
|
|
if file != nil {
|
|
file.Close()
|
|
}
|
|
|
|
_, err := os.OpenFile(path, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// AddDatabase attaches or replaces the database backend
|
|
func AddDatabase(d *gorm.DB) {
|
|
console.Println("Adding database to logger")
|
|
DB = d
|
|
}
|
|
|
|
// Close shuts down the file backend.
|
|
func Close() error {
|
|
if file != nil {
|
|
err := file.Close()
|
|
file = nil
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func logMsg(level Level, format string, args ...any) {
|
|
message := fmt.Sprintf(format, args...)
|
|
now := time.Now()
|
|
timestamp := now.Format("2006-01-02 15:04:05.000")
|
|
line := fmt.Sprintf("%s [%s] %s", timestamp, level, message)
|
|
|
|
// 1. The standard log package is internally thread-safe
|
|
console.Println(line)
|
|
|
|
// 2. Write to file
|
|
if file != nil {
|
|
fmt.Fprintln(file, line)
|
|
}
|
|
|
|
// 3. Write to DB using GORM. It handles its own connection pooling and locking.
|
|
if DB != nil {
|
|
var entry db.Log
|
|
entry.Timestamp = now.UnixMilli()
|
|
entry.Level = level.String()
|
|
entry.Message = message
|
|
|
|
// Use Save() to insert the new record.
|
|
result := DB.Save(&entry)
|
|
if result.Error != nil {
|
|
console.Printf("Failed to write log to database: %v\n", result.Error)
|
|
}
|
|
}
|
|
}
|
|
|
|
func Debug(format string, args ...any) { logMsg(LevelDebug, format, args...) }
|
|
func Info(format string, args ...any) { logMsg(LevelInfo, format, args...) }
|
|
func Warning(format string, args ...any) { logMsg(LevelWarning, format, args...) }
|
|
func Error(format string, args ...any) { logMsg(LevelError, format, args...) }
|
|
|
|
func Fatal(format string, args ...any) {
|
|
logMsg(LevelFatal, format, args...)
|
|
time.Sleep(100 * time.Millisecond)
|
|
os.Exit(1)
|
|
}
|