This commit is contained in:
105
logger.go
Normal file
105
logger.go
Normal file
@@ -0,0 +1,105 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// Logger is the global logger instance
|
||||
var Logger *logrus.Logger
|
||||
|
||||
// InitLogger initializes the structured logger with file output
|
||||
func InitLogger(config *Config) error {
|
||||
Logger = logrus.New()
|
||||
|
||||
// Set log level based on configuration
|
||||
level, err := logrus.ParseLevel(config.LogLevel)
|
||||
if err != nil {
|
||||
level = logrus.InfoLevel
|
||||
}
|
||||
Logger.SetLevel(level)
|
||||
|
||||
// Set JSON formatter for structured logging
|
||||
Logger.SetFormatter(&logrus.JSONFormatter{
|
||||
TimestampFormat: time.RFC3339,
|
||||
FieldMap: logrus.FieldMap{
|
||||
logrus.FieldKeyTime: "timestamp",
|
||||
logrus.FieldKeyLevel: "level",
|
||||
logrus.FieldKeyMsg: "message",
|
||||
},
|
||||
})
|
||||
|
||||
// Create log directory if it doesn't exist
|
||||
if err := os.MkdirAll(config.LogDir, 0755); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Create log file with timestamp
|
||||
logFile := filepath.Join(config.LogDir, "app.log")
|
||||
file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Set output to both file and stdout
|
||||
multiWriter := io.MultiWriter(os.Stdout, file)
|
||||
Logger.SetOutput(multiWriter)
|
||||
|
||||
// Add default fields
|
||||
Logger = Logger.WithFields(logrus.Fields{
|
||||
"service": "counter-app",
|
||||
"environment": string(config.Environment),
|
||||
"version": "1.0.0",
|
||||
}).Logger
|
||||
|
||||
// Log initialization
|
||||
Logger.Info("Logger initialized successfully")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetLogger returns the global logger instance
|
||||
func GetLogger() *logrus.Logger {
|
||||
if Logger == nil {
|
||||
// Fallback to standard logger if not initialized
|
||||
logrus.SetFormatter(&logrus.JSONFormatter{
|
||||
TimestampFormat: time.RFC3339,
|
||||
})
|
||||
return logrus.StandardLogger()
|
||||
}
|
||||
return Logger
|
||||
}
|
||||
|
||||
// LoggingMiddleware creates a Gin middleware for HTTP request logging
|
||||
func LoggingMiddleware() gin.HandlerFunc {
|
||||
return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
|
||||
// Create structured log entry
|
||||
entry := Logger.WithFields(logrus.Fields{
|
||||
"method": param.Method,
|
||||
"path": param.Path,
|
||||
"status": param.StatusCode,
|
||||
"latency": param.Latency.String(),
|
||||
"client_ip": param.ClientIP,
|
||||
"user_agent": param.Request.UserAgent(),
|
||||
"timestamp": param.TimeStamp.Format(time.RFC3339),
|
||||
})
|
||||
|
||||
// Set log level based on status code
|
||||
switch {
|
||||
case param.StatusCode >= 500:
|
||||
entry.Error("HTTP Request")
|
||||
case param.StatusCode >= 400:
|
||||
entry.Warn("HTTP Request")
|
||||
default:
|
||||
entry.Info("HTTP Request")
|
||||
}
|
||||
|
||||
// Return empty string since we're handling logging ourselves
|
||||
return ""
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user