Logging Starter

Introduction

The Logging Starter provides structured logging capabilities for Hiboot applications. It supports multiple log levels, formatters, and is easily configurable through YAML configuration.

Installation

Import the logging starter in your application:

import "github.com/hidevopsio/hiboot/pkg/starter/logging"

Configuration

Enable logging in your application.yml:

app:
  profiles:
    include:
    - logging

logging:
  level: info

Or enable it programmatically:

package main

import (
	"github.com/hidevopsio/hiboot/pkg/app"
	"github.com/hidevopsio/hiboot/pkg/app/web"
	"github.com/hidevopsio/hiboot/pkg/starter/logging"
)

func main() {
	web.NewApplication().
		SetProperty(app.ProfilesInclude, logging.Profile).
		Run()
}

Basic Usage

Use the log package for logging:

package service

import (
	"github.com/hidevopsio/hiboot/pkg/log"
)

type UserService struct{}

func (s *UserService) GetUser(id uint64) (*User, error) {
	log.Infof("Getting user with ID: %d", id)

	user, err := s.repository.FindById(id)
	if err != nil {
		log.Errorf("Failed to get user %d: %v", id, err)
		return nil, err
	}

	log.Debugf("User found: %+v", user)
	return user, nil
}

Log Levels

Level Description Method
debug Detailed debugging information log.Debug(), log.Debugf()
info General operational information log.Info(), log.Infof()
warn Warning messages log.Warn(), log.Warnf()
error Error conditions log.Error(), log.Errorf()
fatal Critical errors (exits application) log.Fatal(), log.Fatalf()

Setting Log Level

In application.yml:

logging:
  level: debug  # debug, info, warn, error, fatal

Logging Methods

Basic Logging

log.Debug("Debug message")
log.Info("Info message")
log.Warn("Warning message")
log.Error("Error message")

Formatted Logging

log.Debugf("User %s logged in from %s", username, ip)
log.Infof("Processing request %d", requestId)
log.Warnf("High memory usage: %d%%", memoryPercent)
log.Errorf("Database error: %v", err)

Logging with Fields

log.WithFields(log.Fields{
	"user_id":    123,
	"request_id": "abc-123",
	"action":     "login",
}).Info("User action logged")

Environment-Specific Configuration

Development

# application-dev.yml
logging:
  level: debug

Production

# application-prod.yml
logging:
  level: info

Controller Logging Example

package controller

import (
	"github.com/hidevopsio/hiboot/pkg/app"
	"github.com/hidevopsio/hiboot/pkg/at"
	"github.com/hidevopsio/hiboot/pkg/log"
	"github.com/hidevopsio/hiboot/pkg/model"
)

type userController struct {
	at.RestController
	at.RequestMapping `value:"/user"`
}

func init() {
	app.Register(newUserController)
}

func newUserController() *userController {
	return &userController{}
}

func (c *userController) Post(request *CreateUserRequest) (model.Response, error) {
	log.Infof("Creating user: %s", request.Username)

	// Business logic
	user, err := createUser(request)
	if err != nil {
		log.Errorf("Failed to create user: %v", err)
		response := new(model.BaseResponse)
		response.SetCode(500)
		response.SetMessage("Failed to create user")
		return response, nil
	}

	log.Infof("User created successfully: ID=%d", user.Id)

	response := new(model.BaseResponse)
	response.SetData(user)
	return response, nil
}

Service Logging Example

package service

import (
	"github.com/hidevopsio/hiboot/pkg/app"
	"github.com/hidevopsio/hiboot/pkg/log"
)

type OrderService interface {
	ProcessOrder(orderId uint64) error
}

type orderServiceImpl struct {
	repository OrderRepository
}

func init() {
	app.Register(newOrderService)
}

func newOrderService(repository OrderRepository) OrderService {
	return &orderServiceImpl{
		repository: repository,
	}
}

func (s *orderServiceImpl) ProcessOrder(orderId uint64) error {
	log.WithFields(log.Fields{
		"order_id": orderId,
		"action":   "process_start",
	}).Info("Starting order processing")

	order, err := s.repository.FindById(orderId)
	if err != nil {
		log.WithFields(log.Fields{
			"order_id": orderId,
			"error":    err.Error(),
		}).Error("Failed to fetch order")
		return err
	}

	// Process order...
	log.WithFields(log.Fields{
		"order_id": orderId,
		"status":   order.Status,
	}).Debug("Order status updated")

	log.WithFields(log.Fields{
		"order_id": orderId,
		"action":   "process_complete",
	}).Info("Order processing completed")

	return nil
}

Best Practices

  1. Use appropriate log levels: Use debug for development details, info for operational events, warn for potential issues, error for failures
  2. Include context: Always include relevant IDs (user_id, request_id, order_id) in log messages
  3. Avoid logging sensitive data: Never log passwords, tokens, or personal data
  4. Use structured logging: Use log.WithFields() for machine-parseable logs
  5. Be consistent: Use consistent message formats across your application

Configuration Reference

Property Description Default
logging.level Log level (debug, info, warn, error, fatal) info

What’s Next?