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)