mirror of
https://github.com/chenasraf/sofmani.git
synced 2026-05-17 17:28:04 +00:00
169 lines
4.7 KiB
Go
169 lines
4.7 KiB
Go
package logger
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/chenasraf/sofmani/platform"
|
|
"github.com/davecgh/go-spew/spew"
|
|
"github.com/fatih/color"
|
|
)
|
|
|
|
// Logger provides logging functionality with support for file and console output.
|
|
type Logger struct {
|
|
fileLogger *log.Logger // fileLogger is the logger for writing to the log file.
|
|
consoleOut *log.Logger // consoleOut is the logger for writing to the console.
|
|
logFile *os.File // logFile is the opened log file.
|
|
logFilePath string // logFilePath is the path to the log file.
|
|
debug bool // debug indicates whether debug logging is enabled.
|
|
}
|
|
|
|
var logger *Logger // logger is the global logger instance.
|
|
var customLogFile *string // customLogFile holds the custom log file path if set.
|
|
|
|
// GetLogDir returns the appropriate log directory based on the operating system.
|
|
func GetLogDir() string {
|
|
var logDir string
|
|
switch platform.GetPlatform() {
|
|
case platform.PlatformLinux:
|
|
stateDir := os.Getenv("XDG_STATE_HOME")
|
|
if stateDir == "" {
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
fmt.Printf("Could not get user home directory: %v\n", err)
|
|
panic(err)
|
|
}
|
|
stateDir = filepath.Join(home, ".local", "state")
|
|
}
|
|
logDir = filepath.Join(stateDir, "sofmani")
|
|
case platform.PlatformMacos:
|
|
home, err := os.UserHomeDir()
|
|
if err != nil {
|
|
fmt.Printf("Could not get user home directory: %v\n", err)
|
|
panic(err)
|
|
}
|
|
logDir = filepath.Join(home, "Library", "Logs", "sofmani")
|
|
case platform.PlatformWindows:
|
|
appData := os.Getenv("APPDATA")
|
|
logDir = filepath.Join(appData, "sofmani", "Logs")
|
|
}
|
|
return logDir
|
|
}
|
|
|
|
// GetDefaultLogFile returns the default log file path.
|
|
func GetDefaultLogFile() string {
|
|
return filepath.Join(GetLogDir(), "sofmani.log")
|
|
}
|
|
|
|
// GetLogFile returns the current log file path (custom or default).
|
|
func GetLogFile() string {
|
|
if customLogFile != nil {
|
|
return *customLogFile
|
|
}
|
|
return GetDefaultLogFile()
|
|
}
|
|
|
|
// SetLogFile sets a custom log file path.
|
|
func SetLogFile(path string) {
|
|
customLogFile = &path
|
|
}
|
|
|
|
// InitLogger initializes the global logger with the specified debug mode.
|
|
// It creates the log directory and file if they don't exist.
|
|
func InitLogger(debug bool) *Logger {
|
|
filePath := GetLogFile()
|
|
logDir := filepath.Dir(filePath)
|
|
if _, err := os.Stat(logDir); os.IsNotExist(err) {
|
|
err := os.MkdirAll(logDir, 0755)
|
|
if err != nil {
|
|
fmt.Printf("Could not create log directory: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
logFile, err := os.OpenFile(filePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
|
if err != nil {
|
|
fmt.Printf("Could not create log file: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Create file and console loggers
|
|
fileLogger := log.New(logFile, "", log.LstdFlags)
|
|
consoleOut := log.New(os.Stdout, "", log.LstdFlags)
|
|
|
|
// Initialize the logger
|
|
logger = &Logger{
|
|
fileLogger: fileLogger,
|
|
consoleOut: consoleOut,
|
|
logFile: logFile,
|
|
logFilePath: filePath,
|
|
debug: debug,
|
|
}
|
|
|
|
return logger
|
|
}
|
|
|
|
// log is an internal helper function for logging messages with a specific level and color.
|
|
func (l *Logger) log(level string, colorizer *color.Color, format string, args ...any) {
|
|
// Create timestamped message
|
|
// timestamp := time.Now().Format("2006-01-02 15:04:05")
|
|
message := fmt.Sprintf("[%s] %s", level, fmt.Sprintf(format, args...))
|
|
|
|
// Write to file
|
|
l.fileLogger.Println(message)
|
|
|
|
if level == "DEBUG" && !l.debug {
|
|
return
|
|
}
|
|
|
|
// Write to console with color
|
|
if colorizer != nil {
|
|
l.consoleOut.Println(colorizer.Sprint(message))
|
|
} else {
|
|
l.consoleOut.Println(message)
|
|
}
|
|
}
|
|
|
|
// Info logs an informational message.
|
|
func Info(format string, args ...any) {
|
|
colorBlue := color.New(color.FgBlue).Add(color.Bold)
|
|
logger.log(" INFO", colorBlue, format, args...)
|
|
}
|
|
|
|
// Warn logs a warning message.
|
|
func Warn(format string, args ...any) {
|
|
colorYellow := color.New(color.FgYellow).Add(color.Bold)
|
|
logger.log(" WARN", colorYellow, format, args...)
|
|
}
|
|
|
|
// Error logs an error message.
|
|
func Error(format string, args ...any) {
|
|
colorRed := color.New(color.FgRed).Add(color.Bold)
|
|
logger.log("ERROR", colorRed, format, args...)
|
|
}
|
|
|
|
// Debug logs a debug message. Only printed if debug mode is enabled.
|
|
func Debug(format string, args ...any) {
|
|
colorGreen := color.New(color.FgGreen).Add(color.Bold)
|
|
logger.log("DEBUG", colorGreen, format, args...)
|
|
}
|
|
|
|
// Spew logs a detailed representation of a value using spew.Dump.
|
|
// This is typically used for debugging complex data structures.
|
|
func Spew(v any) {
|
|
// Print/debug the passed value (works like spew.Dump)
|
|
spewDump := spew.Sdump(v)
|
|
Debug("%s", spewDump)
|
|
}
|
|
|
|
// CloseLogger closes the log file.
|
|
func CloseLogger() {
|
|
if logger != nil && logger.logFile != nil {
|
|
err := logger.logFile.Close()
|
|
if err != nil {
|
|
fmt.Printf("Could not close log file: %v\n", err)
|
|
}
|
|
}
|
|
}
|