feat: Add pcap import, file browser, logging, local capture, and stable call ordering
This commit is contained in:
113
internal/logger/logger.go
Normal file
113
internal/logger/logger.go
Normal file
@@ -0,0 +1,113 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
instance *Logger
|
||||
once sync.Once
|
||||
)
|
||||
|
||||
// Logger handles application logging
|
||||
type Logger struct {
|
||||
file *os.File
|
||||
mu sync.Mutex
|
||||
path string
|
||||
}
|
||||
|
||||
// Init initializes the logger with timestamp-based filename
|
||||
func Init() error {
|
||||
var err error
|
||||
once.Do(func() {
|
||||
// Create logs directory
|
||||
logsDir := "logs"
|
||||
if mkErr := os.MkdirAll(logsDir, 0755); mkErr != nil {
|
||||
err = mkErr
|
||||
return
|
||||
}
|
||||
|
||||
// Create log file with timestamp
|
||||
timestamp := time.Now().Format("2006-01-02_15-04-05")
|
||||
filename := filepath.Join(logsDir, fmt.Sprintf("%s.log", timestamp))
|
||||
|
||||
f, openErr := os.Create(filename)
|
||||
if openErr != nil {
|
||||
err = openErr
|
||||
return
|
||||
}
|
||||
|
||||
instance = &Logger{
|
||||
file: f,
|
||||
path: filename,
|
||||
}
|
||||
|
||||
Info("Logger initialized: %s", filename)
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// Close closes the logger
|
||||
func Close() {
|
||||
if instance != nil && instance.file != nil {
|
||||
instance.file.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// GetPath returns the log file path
|
||||
func GetPath() string {
|
||||
if instance != nil {
|
||||
return instance.path
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// log writes a log entry
|
||||
func log(level, format string, args ...interface{}) {
|
||||
if instance == nil {
|
||||
return
|
||||
}
|
||||
|
||||
instance.mu.Lock()
|
||||
defer instance.mu.Unlock()
|
||||
|
||||
timestamp := time.Now().Format("15:04:05.000")
|
||||
msg := fmt.Sprintf(format, args...)
|
||||
line := fmt.Sprintf("[%s] [%s] %s\n", timestamp, level, msg)
|
||||
|
||||
instance.file.WriteString(line)
|
||||
instance.file.Sync()
|
||||
}
|
||||
|
||||
// Debug logs a debug message
|
||||
func Debug(format string, args ...interface{}) {
|
||||
log("DEBUG", format, args...)
|
||||
}
|
||||
|
||||
// Info logs an info message
|
||||
func Info(format string, args ...interface{}) {
|
||||
log("INFO", format, args...)
|
||||
}
|
||||
|
||||
// Warn logs a warning message
|
||||
func Warn(format string, args ...interface{}) {
|
||||
log("WARN", format, args...)
|
||||
}
|
||||
|
||||
// Error logs an error message
|
||||
func Error(format string, args ...interface{}) {
|
||||
log("ERROR", format, args...)
|
||||
}
|
||||
|
||||
// Writer returns an io.Writer that logs to the file
|
||||
func Writer() io.Writer {
|
||||
if instance != nil {
|
||||
return instance.file
|
||||
}
|
||||
return os.Stdout
|
||||
}
|
||||
Reference in New Issue
Block a user