Perbaikan Middelware dan tool generete logger
This commit is contained in:
191
pkg/logger/middleware.go
Normal file
191
pkg/logger/middleware.go
Normal file
@@ -0,0 +1,191 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// RequestLoggerMiddleware creates a Gin middleware for request logging
|
||||
func RequestLoggerMiddleware(logger *Logger) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
// Generate request ID if not present
|
||||
requestID := c.GetHeader("X-Request-ID")
|
||||
if requestID == "" {
|
||||
requestID = uuid.New().String()
|
||||
c.Header("X-Request-ID", requestID)
|
||||
}
|
||||
|
||||
// Get correlation ID
|
||||
correlationID := c.GetHeader("X-Correlation-ID")
|
||||
if correlationID == "" {
|
||||
correlationID = uuid.New().String()
|
||||
c.Header("X-Correlation-ID", correlationID)
|
||||
}
|
||||
|
||||
// Create request-scoped logger
|
||||
reqLogger := logger.
|
||||
WithRequestID(requestID).
|
||||
WithCorrelationID(correlationID)
|
||||
|
||||
// Store logger in context
|
||||
c.Set("logger", reqLogger)
|
||||
c.Set("request_id", requestID)
|
||||
c.Set("correlation_id", correlationID)
|
||||
|
||||
// Capture request body for logging if needed
|
||||
var requestBody []byte
|
||||
if c.Request.Body != nil && strings.HasPrefix(c.ContentType(), "application/json") {
|
||||
requestBody, _ = io.ReadAll(c.Request.Body)
|
||||
c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
|
||||
}
|
||||
|
||||
// Start timer
|
||||
start := time.Now()
|
||||
|
||||
// Log request start
|
||||
reqLogger.Info("Request started", map[string]interface{}{
|
||||
"method": c.Request.Method,
|
||||
"path": c.Request.URL.Path,
|
||||
"query": c.Request.URL.RawQuery,
|
||||
"remote_addr": c.Request.RemoteAddr,
|
||||
"user_agent": c.Request.UserAgent(),
|
||||
"content_type": c.ContentType(),
|
||||
"body_size": len(requestBody),
|
||||
})
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
|
||||
// Calculate duration
|
||||
duration := time.Since(start)
|
||||
|
||||
// Get response status
|
||||
status := c.Writer.Status()
|
||||
responseSize := c.Writer.Size()
|
||||
|
||||
// Log level based on status code
|
||||
var logLevel LogLevel
|
||||
switch {
|
||||
case status >= 500:
|
||||
logLevel = ERROR
|
||||
case status >= 400:
|
||||
logLevel = WARN
|
||||
default:
|
||||
logLevel = INFO
|
||||
}
|
||||
|
||||
// Log request completion
|
||||
fields := map[string]interface{}{
|
||||
"method": c.Request.Method,
|
||||
"path": c.Request.URL.Path,
|
||||
"status": status,
|
||||
"duration": duration.String(),
|
||||
"duration_ms": duration.Milliseconds(),
|
||||
"response_size": responseSize,
|
||||
"client_ip": c.ClientIP(),
|
||||
"user_agent": c.Request.UserAgent(),
|
||||
"content_type": c.ContentType(),
|
||||
"content_length": c.Request.ContentLength,
|
||||
}
|
||||
|
||||
// Add query parameters if present
|
||||
if c.Request.URL.RawQuery != "" {
|
||||
fields["query"] = c.Request.URL.RawQuery
|
||||
}
|
||||
|
||||
// Add error information if present
|
||||
if len(c.Errors) > 0 {
|
||||
errors := make([]string, len(c.Errors))
|
||||
for i, err := range c.Errors {
|
||||
errors[i] = err.Error()
|
||||
}
|
||||
fields["errors"] = errors
|
||||
}
|
||||
|
||||
reqLogger.log(logLevel, "Request completed", &duration, fields)
|
||||
}
|
||||
}
|
||||
|
||||
// GetLoggerFromContext retrieves the logger from Gin context
|
||||
func GetLoggerFromContext(c *gin.Context) *Logger {
|
||||
if logger, exists := c.Get("logger"); exists {
|
||||
if l, ok := logger.(*Logger); ok {
|
||||
return l
|
||||
}
|
||||
}
|
||||
return globalLogger
|
||||
}
|
||||
|
||||
// GetRequestIDFromContext retrieves the request ID from Gin context
|
||||
func GetRequestIDFromContext(c *gin.Context) string {
|
||||
if requestID, exists := c.Get("request_id"); exists {
|
||||
if id, ok := requestID.(string); ok {
|
||||
return id
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetCorrelationIDFromContext retrieves the correlation ID from Gin context
|
||||
func GetCorrelationIDFromContext(c *gin.Context) string {
|
||||
if correlationID, exists := c.Get("correlation_id"); exists {
|
||||
if id, ok := correlationID.(string); ok {
|
||||
return id
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// DatabaseLoggerMiddleware creates middleware for database operation logging
|
||||
func DatabaseLoggerMiddleware(logger *Logger, serviceName string) gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
reqLogger := GetLoggerFromContext(c).WithService(serviceName)
|
||||
c.Set("db_logger", reqLogger)
|
||||
c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// GetDBLoggerFromContext retrieves the database logger from Gin context
|
||||
func GetDBLoggerFromContext(c *gin.Context) *Logger {
|
||||
if logger, exists := c.Get("db_logger"); exists {
|
||||
if l, ok := logger.(*Logger); ok {
|
||||
return l
|
||||
}
|
||||
}
|
||||
return GetLoggerFromContext(c)
|
||||
}
|
||||
|
||||
// ServiceLogger creates a service-specific logger
|
||||
func ServiceLogger(serviceName string) *Logger {
|
||||
return globalLogger.WithService(serviceName)
|
||||
}
|
||||
|
||||
// AuthServiceLogger returns a logger for auth service
|
||||
func AuthServiceLogger() *Logger {
|
||||
return ServiceLogger("auth-service")
|
||||
}
|
||||
|
||||
// BPJSServiceLogger returns a logger for BPJS service
|
||||
func BPJSServiceLogger() *Logger {
|
||||
return ServiceLogger("bpjs-service")
|
||||
}
|
||||
|
||||
// RetribusiServiceLogger returns a logger for retribusi service
|
||||
func RetribusiServiceLogger() *Logger {
|
||||
return ServiceLogger("retribusi-service")
|
||||
}
|
||||
|
||||
// DatabaseServiceLogger returns a logger for database operations
|
||||
func DatabaseServiceLogger() *Logger {
|
||||
return ServiceLogger("database-service")
|
||||
}
|
||||
|
||||
// MiddlewareServiceLogger returns a logger for middleware operations
|
||||
func MiddlewareServiceLogger() *Logger {
|
||||
return ServiceLogger("middleware-service")
|
||||
}
|
||||
Reference in New Issue
Block a user