Logger
Dokumentasi logging system menggunakan Logrus.
Overview
Package infra/logger menyediakan structured logging dengan berbagai level menggunakan Logrus.
Log Levels
| Level | Function | Deskripsi |
|---|---|---|
| Debug | Debugf() | Detailed information for debugging |
| Info | Infof() | General operational information |
| Warn | Warnf() | Warning messages |
| Error | Errorf() | Error conditions |
| Fatal | Fatalf() | 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
-
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 -
Include Context
// ✅ Good
logger.Errorf("Failed to create user %s: %v", userID, err)
// ❌ Bad
logger.Errorf("Error occurred") -
Don't Log Sensitive Data
// ✅ Good
logger.Infof("User %s authenticated", userID)
// ❌ Bad
logger.Infof("User %s authenticated with password %s", userID, password) -
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)