Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/golang/go/llms.txt

Use this file to discover all available pages before exploring further.

The log package implements simple logging. It provides basic logging functions and customizable loggers.

Basic Logging

import "log"

func main() {
    log.Print("This is a message")
    log.Printf("User %s logged in", "alice")
    log.Println("Server started")
    
    // Fatal logs and calls os.Exit(1)
    // log.Fatal("Critical error")
    
    // Panic logs and calls panic()
    // log.Panic("Panic message")
}

Custom Logger

import (
    "log"
    "os"
)

func createLogger() *log.Logger {
    return log.New(os.Stdout, "[APP] ", log.LstdFlags)
}

func main() {
    logger := createLogger()
    logger.Println("Custom logger message")
}

Log Flags

const (
    Ldate         = 1 << iota // 2009/01/23
    Ltime                     // 01:23:23
    Lmicroseconds             // 01:23:23.123123
    Llongfile                 // /a/b/c/d.go:23
    Lshortfile                // d.go:23
    LUTC                      // Use UTC times
    Lmsgprefix                // Move prefix to message line
    LstdFlags     = Ldate | Ltime
)

func configureLogger() {
    log.SetFlags(log.Ldate | log.Ltime | log.Lshortfile)
    log.SetPrefix("[MyApp] ")
}

File Logging

func logToFile(filename string) error {
    f, err := os.OpenFile(filename,
        os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
    if err != nil {
        return err
    }
    defer f.Close()
    
    log.SetOutput(f)
    log.Println("This goes to file")
    return nil
}

Multiple Loggers

var (
    Info    *log.Logger
    Warning *log.Logger
    Error   *log.Logger
)

func initLoggers() {
    Info = log.New(os.Stdout, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile)
    Warning = log.New(os.Stdout, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)
    Error = log.New(os.Stderr, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile)
}

func main() {
    initLoggers()
    
    Info.Println("Application started")
    Warning.Println("Disk space low")
    Error.Println("Failed to connect")
}

Practical Examples

HTTP Request Logger

type LoggingHandler struct {
    handler http.Handler
    logger  *log.Logger
}

func NewLoggingHandler(h http.Handler) *LoggingHandler {
    return &LoggingHandler{
        handler: h,
        logger:  log.New(os.Stdout, "[HTTP] ", log.LstdFlags),
    }
}

func (h *LoggingHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    h.logger.Printf("%s %s %s", r.Method, r.URL.Path, r.RemoteAddr)
    h.handler.ServeHTTP(w, r)
}

Structured Logging

type StructuredLogger struct {
    logger *log.Logger
}

func NewStructuredLogger() *StructuredLogger {
    return &StructuredLogger{
        logger: log.New(os.Stdout, "", 0),
    }
}

func (sl *StructuredLogger) Log(level, msg string, fields map[string]interface{}) {
    entry := map[string]interface{}{
        "level": level,
        "msg":   msg,
        "time":  time.Now().Format(time.RFC3339),
    }
    
    for k, v := range fields {
        entry[k] = v
    }
    
    data, _ := json.Marshal(entry)
    sl.logger.Println(string(data))
}

log/slog (Go 1.21+)

New structured logging package.
import "log/slog"

func useSlog() {
    slog.Info("User logged in", "user", "alice", "ip", "192.168.1.1")
    slog.Warn("High memory usage", "percent", 85)
    slog.Error("Database error", "error", err)
}

// JSON output
func jsonLogger() {
    logger := slog.New(slog.NewJSONHandler(os.Stdout, nil))
    logger.Info("Application started", "version", "1.0.0")
}

Best Practices

  1. Use appropriate levels - Info for general messages, Error for errors
  2. Include context - Add relevant information to log messages
  3. Don’t log sensitive data - Avoid passwords, tokens, etc.
  4. Configure output - Set appropriate flags and prefix
  5. Use structured logging - For production applications
  6. Rotate log files - Prevent unbounded growth
  7. Handle errors - Check errors when opening log files

Build docs developers (and LLMs) love