aboutsummaryrefslogtreecommitdiffstats
path: root/backend/internal/logger/logger.go
blob: 7de276d1957379c19ec41a80d5b43e4b1e133db4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package logger

import (
	"fmt"
	"io"
	"log"
	"os"
	"time"
)

// LogLevel represents the severity of a log message
type LogLevel int

const (
	// DEBUG level for detailed information
	DEBUG LogLevel = iota
	// INFO level for general operational information
	INFO
	// WARN level for warnings
	WARN
	// ERROR level for errors
	ERROR
	// FATAL level for fatal errors that cause the application to exit
	FATAL
)

var (
	// defaultLogger is the default logger used by the package
	defaultLogger *Logger
	// level names for pretty printing
	levelNames = []string{
		"DEBUG",
		"INFO",
		"WARN",
		"ERROR",
		"FATAL",
	}
)

// Logger is a custom logger that wraps the standard log package
type Logger struct {
	debugLog *log.Logger
	infoLog  *log.Logger
	warnLog  *log.Logger
	errorLog *log.Logger
	fatalLog *log.Logger
}

// Init initializes the default logger with the specified output and minimum log level
func Init(out io.Writer, level LogLevel) {
	defaultLogger = NewLogger(out, level)
}

// NewLogger creates a new logger with the specified output and minimum log level
func NewLogger(out io.Writer, level LogLevel) *Logger {
	if out == nil {
		out = os.Stdout
	}

	flags := log.Ldate | log.Ltime

	l := &Logger{
		debugLog: log.New(out, "[DEBUG] ", flags),
		infoLog:  log.New(out, "[INFO] ", flags),
		warnLog:  log.New(out, "[WARN] ", flags),
		errorLog: log.New(out, "[ERROR] ", flags),
		fatalLog: log.New(out, "[FATAL] ", flags),
	}

	return l
}

// Debug logs a debug message
func (l *Logger) Debug(v ...interface{}) {
	l.debugLog.Println(v...)
}

// Info logs an info message
func (l *Logger) Info(v ...interface{}) {
	l.infoLog.Println(v...)
}

// Warn logs a warning message
func (l *Logger) Warn(v ...interface{}) {
	l.warnLog.Println(v...)
}

// Error logs an error message
func (l *Logger) Error(v ...interface{}) {
	l.errorLog.Println(v...)
}

// Fatal logs a fatal message and exits the program
func (l *Logger) Fatal(v ...interface{}) {
	l.fatalLog.Println(v...)
	os.Exit(1)
}

// Debugf logs a formatted debug message
func (l *Logger) Debugf(format string, v ...interface{}) {
	l.debugLog.Printf(format, v...)
}

// Infof logs a formatted info message
func (l *Logger) Infof(format string, v ...interface{}) {
	l.infoLog.Printf(format, v...)
}

// Warnf logs a formatted warning message
func (l *Logger) Warnf(format string, v ...interface{}) {
	l.warnLog.Printf(format, v...)
}

// Errorf logs a formatted error message
func (l *Logger) Errorf(format string, v ...interface{}) {
	l.errorLog.Printf(format, v...)
}

// Fatalf logs a formatted fatal message and exits the program
func (l *Logger) Fatalf(format string, v ...interface{}) {
	l.fatalLog.Printf(format, v...)
	os.Exit(1)
}

// LogRequest logs an HTTP request
func (l *Logger) LogRequest(method, path, ip, userAgent string, status int, latency time.Duration) {
	l.Infof(
		"Request: %s %s | Status: %d | IP: %s | User-Agent: %s | Latency: %v",
		method, path, status, ip, userAgent, latency,
	)
}

// GetTimestamp returns the current timestamp as a formatted string
func GetTimestamp() string {
	return time.Now().Format("2006-01-02 15:04:05")
}

// FormatRequestLog formats a request log entry with useful information
func FormatRequestLog(method, path, ip, userAgent string, statusCode int, latency time.Duration) string {
	return fmt.Sprintf(
		"Request: %s %s | Status: %d | IP: %s | Latency: %s | User-Agent: %s",
		method, path, statusCode, ip, latency, userAgent,
	)
}