261 lines
5.8 KiB
Go
261 lines
5.8 KiB
Go
package logger
|
|
|
|
import (
|
|
"os"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
var Logger *logrus.Logger
|
|
|
|
// InitLogger initializes the logger
|
|
func InitLogger() {
|
|
Logger = logrus.New()
|
|
|
|
// Set log level based on environment
|
|
logLevel := os.Getenv("LOG_LEVEL")
|
|
if logLevel == "" {
|
|
logLevel = "info"
|
|
}
|
|
|
|
level, err := logrus.ParseLevel(logLevel)
|
|
if err != nil {
|
|
level = logrus.InfoLevel
|
|
}
|
|
|
|
Logger.SetLevel(level)
|
|
|
|
// Set formatter
|
|
Logger.SetFormatter(&logrus.JSONFormatter{
|
|
TimestampFormat: time.RFC3339,
|
|
})
|
|
|
|
// Set output to stdout by default
|
|
Logger.SetOutput(os.Stdout)
|
|
}
|
|
|
|
// GetLogger returns the logger instance
|
|
func GetLogger() *logrus.Logger {
|
|
if Logger == nil {
|
|
InitLogger()
|
|
}
|
|
return Logger
|
|
}
|
|
|
|
// GinLogger returns a gin middleware for logging
|
|
func GinLogger() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
// Start timer
|
|
start := time.Now()
|
|
path := c.Request.URL.Path
|
|
raw := c.Request.URL.RawQuery
|
|
|
|
// Process request
|
|
c.Next()
|
|
|
|
// Stop timer
|
|
end := time.Now()
|
|
latency := end.Sub(start)
|
|
|
|
// Get client IP
|
|
clientIP := c.ClientIP()
|
|
|
|
// Get method
|
|
method := c.Request.Method
|
|
|
|
// Get status code
|
|
statusCode := c.Writer.Status()
|
|
|
|
// Get error message if any
|
|
var errorMessage string
|
|
if len(c.Errors) > 0 {
|
|
errorMessage = c.Errors.String()
|
|
}
|
|
|
|
// Get body size
|
|
bodySize := c.Writer.Size()
|
|
|
|
// Get request ID if available
|
|
requestID := c.GetHeader("X-Request-ID")
|
|
if requestID == "" {
|
|
requestID = c.GetString("requestID")
|
|
}
|
|
|
|
// Get user ID if available
|
|
userID := c.GetString("userID")
|
|
|
|
// Log the request
|
|
entry := GetLogger().WithFields(logrus.Fields{
|
|
"request_id": requestID,
|
|
"user_id": userID,
|
|
"client_ip": clientIP,
|
|
"method": method,
|
|
"path": path,
|
|
"query": raw,
|
|
"status_code": statusCode,
|
|
"body_size": bodySize,
|
|
"latency": latency,
|
|
"latency_human": latency.String(),
|
|
"error_message": errorMessage,
|
|
})
|
|
|
|
if statusCode >= 500 {
|
|
entry.Error()
|
|
} else if statusCode >= 400 {
|
|
entry.Warn()
|
|
} else {
|
|
entry.Info()
|
|
}
|
|
}
|
|
}
|
|
|
|
// WithRequestID adds a request ID to the logger
|
|
func WithRequestID(requestID string) *logrus.Entry {
|
|
return GetLogger().WithField("request_id", requestID)
|
|
}
|
|
|
|
// WithUserID adds a user ID to the logger
|
|
func WithUserID(userID string) *logrus.Entry {
|
|
return GetLogger().WithField("user_id", userID)
|
|
}
|
|
|
|
// WithError adds an error to the logger
|
|
func WithError(err error) *logrus.Entry {
|
|
return GetLogger().WithError(err)
|
|
}
|
|
|
|
// WithField adds a custom field to the logger
|
|
func WithField(key string, value interface{}) *logrus.Entry {
|
|
return GetLogger().WithField(key, value)
|
|
}
|
|
|
|
// WithFields adds multiple custom fields to the logger
|
|
func WithFields(fields logrus.Fields) *logrus.Entry {
|
|
return GetLogger().WithFields(fields)
|
|
}
|
|
|
|
// Info logs an info message
|
|
func Info(args ...interface{}) {
|
|
GetLogger().Info(args...)
|
|
}
|
|
|
|
// Infof logs a formatted info message
|
|
func Infof(format string, args ...interface{}) {
|
|
GetLogger().Infof(format, args...)
|
|
}
|
|
|
|
// Warn logs a warning message
|
|
func Warn(args ...interface{}) {
|
|
GetLogger().Warn(args...)
|
|
}
|
|
|
|
// Warnf logs a formatted warning message
|
|
func Warnf(format string, args ...interface{}) {
|
|
GetLogger().Warnf(format, args...)
|
|
}
|
|
|
|
// Error logs an error message
|
|
func Error(args ...interface{}) {
|
|
GetLogger().Error(args...)
|
|
}
|
|
|
|
// Errorf logs a formatted error message
|
|
func Errorf(format string, args ...interface{}) {
|
|
GetLogger().Errorf(format, args...)
|
|
}
|
|
|
|
// Fatal logs a fatal message and exits
|
|
func Fatal(args ...interface{}) {
|
|
GetLogger().Fatal(args...)
|
|
}
|
|
|
|
// Fatalf logs a formatted fatal message and exits
|
|
func Fatalf(format string, args ...interface{}) {
|
|
GetLogger().Fatalf(format, args...)
|
|
}
|
|
|
|
// Debug logs a debug message
|
|
func Debug(args ...interface{}) {
|
|
GetLogger().Debug(args...)
|
|
}
|
|
|
|
// Debugf logs a formatted debug message
|
|
func Debugf(format string, args ...interface{}) {
|
|
GetLogger().Debugf(format, args...)
|
|
}
|
|
|
|
// Panic logs a panic message and panics
|
|
func Panic(args ...interface{}) {
|
|
GetLogger().Panic(args...)
|
|
}
|
|
|
|
// Panicf logs a formatted panic message and panics
|
|
func Panicf(format string, args ...interface{}) {
|
|
GetLogger().Panicf(format, args...)
|
|
}
|
|
|
|
// LogDatabaseOperation logs a database operation
|
|
func LogDatabaseOperation(operation string, table string, duration time.Duration, err error) {
|
|
entry := GetLogger().WithFields(logrus.Fields{
|
|
"operation": operation,
|
|
"table": table,
|
|
"duration": duration,
|
|
})
|
|
|
|
if err != nil {
|
|
entry.WithError(err).Error("Database operation failed")
|
|
} else {
|
|
entry.Info("Database operation completed")
|
|
}
|
|
}
|
|
|
|
// LogAIInteraction logs an AI interaction
|
|
func LogAIInteraction(model string, promptLength int, responseLength int, duration time.Duration, success bool, err error) {
|
|
entry := GetLogger().WithFields(logrus.Fields{
|
|
"ai_model": model,
|
|
"prompt_length": promptLength,
|
|
"response_length": responseLength,
|
|
"duration": duration,
|
|
"success": success,
|
|
})
|
|
|
|
if err != nil {
|
|
entry.WithError(err).Error("AI interaction failed")
|
|
} else {
|
|
entry.Info("AI interaction completed")
|
|
}
|
|
}
|
|
|
|
// LogWebSocketEvent logs a WebSocket event
|
|
func LogWebSocketEvent(event string, clientID string, roomID string, err error) {
|
|
entry := GetLogger().WithFields(logrus.Fields{
|
|
"event": event,
|
|
"client_id": clientID,
|
|
"room_id": roomID,
|
|
})
|
|
|
|
if err != nil {
|
|
entry.WithError(err).Error("WebSocket event failed")
|
|
} else {
|
|
entry.Info("WebSocket event completed")
|
|
}
|
|
}
|
|
|
|
// LogAuthEvent logs an authentication event
|
|
func LogAuthEvent(event string, userID string, clientIP string, success bool, err error) {
|
|
entry := GetLogger().WithFields(logrus.Fields{
|
|
"event": event,
|
|
"user_id": userID,
|
|
"client_ip": clientIP,
|
|
"success": success,
|
|
})
|
|
|
|
if err != nil {
|
|
entry.WithError(err).Error("Authentication event failed")
|
|
} else {
|
|
entry.Info("Authentication event completed")
|
|
}
|
|
}
|