106 lines
2.2 KiB
Go
106 lines
2.2 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)
|
|
SetLevel Level = LevelInfo
|
|
)
|
|
|
|
// 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, 0o644)
|
|
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) {
|
|
if level == LevelDebug && SetLevel != LevelDebug {
|
|
return
|
|
}
|
|
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)
|
|
}
|