Skip to main content

Logger

Dokumentasi logging system menggunakan Logrus.

Overview

Package infra/logger menyediakan structured logging dengan berbagai level menggunakan Logrus.

Log Levels

LevelFunctionDeskripsi
DebugDebugf()Detailed information for debugging
InfoInfof()General operational information
WarnWarnf()Warning messages
ErrorErrorf()Error conditions
FatalFatalf()Fatal errors (exits application)

Functions

Debugf

Log message dengan level Debug.

func Debugf(format string, args ...interface{})

Usage:

logger.Debugf("Processing request with ID: %s", requestID)

Infof

Log message dengan level Info.

func Infof(format string, args ...interface{})

Usage:

logger.Infof("Server started on port %s", port)
logger.Infof("User %s logged in successfully", userID)

Warnf

Log message dengan level Warning.

func Warnf(format string, args ...interface{})

Usage:

logger.Warnf("High memory usage detected: %d%%", memUsage)
logger.Warnf("Deprecated API endpoint called: %s", endpoint)

Errorf

Log message dengan level Error.

func Errorf(format string, args ...interface{})

Usage:

logger.Errorf("Failed to connect to database: %v", err)
logger.Errorf("Invalid request body from user %s", userID)

Fatalf

Log message dan exit aplikasi.

func Fatalf(format string, args ...interface{})

Usage:

logger.Fatalf("Critical configuration missing: %s", configKey)
// Application will exit after this
danger

Fatalf akan menghentikan aplikasi. Gunakan hanya untuk error yang tidak dapat di-recover.

SetLogLevel

Mengubah log level.

func SetLogLevel(level logrus.Level)

Usage:

// Set to Debug for development
logger.SetLogLevel(logrus.DebugLevel)

// Set to Info for production
logger.SetLogLevel(logrus.InfoLevel)

Log Format

Default Format

LEVEL TIMESTAMP MESSAGE

Example Output

INFO 2026-01-22T10:00:00+07:00 Server started on port 8000
ERROR 2026-01-22T10:01:00+07:00 Failed to process request: connection refused
DEBUG 2026-01-22T10:02:00+07:00 Query executed: SELECT * FROM users
WARN 2026-01-22T10:03:00+07:00 Slow query detected: 2.5s

Custom Formatter

type formatter struct {
prefix string
}

func (f *formatter) Format(entry *logrus.Entry) ([]byte, error) {
var sb bytes.Buffer

sb.WriteString(strings.ToUpper(entry.Level.String()))
sb.WriteString(" ")
sb.WriteString(entry.Time.Format(time.RFC3339))
sb.WriteString(" ")
sb.WriteString(f.prefix)
sb.WriteString(entry.Message)

return sb.Bytes(), nil
}

Configuration

Default Configuration

func init() {
logger.Level = logrus.InfoLevel
logger.Formatter = &formatter{}
logger.SetReportCaller(true)
}

Environment-based Configuration

func SetupLogger() {
env := viper.GetString("APP_ENV")

if env == "development" {
logger.SetLogLevel(logrus.DebugLevel)
} else {
logger.SetLogLevel(logrus.InfoLevel)
}
}

Usage Examples

In Controller

func CreateUser(c *gin.Context) {
logger.Infof("Creating new user")

var req dto.CreateUserRequest
if err := c.ShouldBindJSON(&req); err != nil {
logger.Errorf("Invalid request body: %v", err)
helpers.SendError(c, helpers.NewBadRequest("Invalid request"))
return
}

logger.Debugf("Request body: %+v", req)

// ... create user

logger.Infof("User created successfully: %s", user.ID)
}

In Repository

func GetUserById(id string) (*models.User, error) {
logger.Debugf("Fetching user with ID: %s", id)

var user models.User
if err := database.DB.First(&user, "id = ?", id).Error; err != nil {
logger.Errorf("Failed to fetch user %s: %v", id, err)
return nil, err
}

logger.Debugf("User found: %s", user.Email)
return &user, nil
}

In Middleware

func LoggerMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
start := time.Now()

c.Next()

duration := time.Since(start)
status := c.Writer.Status()

logger.Infof("%s %s %d %v",
c.Request.Method,
c.Request.URL.Path,
status,
duration,
)
}
}

Best Practices

  1. Use Appropriate Level

    // ✅ Good
    logger.Debugf("Query result: %+v", result) // Debug for detailed info
    logger.Infof("User logged in: %s", userID) // Info for business events
    logger.Errorf("Database error: %v", err) // Error for failures

    // ❌ Bad
    logger.Infof("Query result: %+v", result) // Too verbose for Info
    logger.Errorf("User logged in") // Not an error
  2. Include Context

    // ✅ Good
    logger.Errorf("Failed to create user %s: %v", userID, err)

    // ❌ Bad
    logger.Errorf("Error occurred")
  3. Don't Log Sensitive Data

    // ✅ Good
    logger.Infof("User %s authenticated", userID)

    // ❌ Bad
    logger.Infof("User %s authenticated with password %s", userID, password)
  4. Structured Logging for Production

    logger.WithFields(logrus.Fields{
    "user_id": userID,
    "action": "login",
    "ip": clientIP,
    }).Info("User action")

Log Rotation

Untuk production, gunakan external tools untuk log rotation:

  • logrotate (Linux)
  • Docker logging drivers
  • Cloud logging services (CloudWatch, Stackdriver)