Skip to main content
Learn the basics of go_logs with a working example. This guide covers creating a logger, logging with structured fields, and using child loggers.

Basic usage

1

Import the package

Import go_logs in your Go file:
package main

import (
    "os"
    "github.com/drossan/go_logs"
)
2

Create a logger

Create a logger with configuration options:
func main() {
    logger, err := go_logs.New(
        go_logs.WithLevel(go_logs.InfoLevel),
        go_logs.WithFormatter(go_logs.NewTextFormatter()),
        go_logs.WithOutput(os.Stdout),
    )
    if err != nil {
        panic(err)
    }
    defer logger.Sync()
Always call defer logger.Sync() to flush buffered logs before your application exits.
3

Log with structured fields

Use typed field helpers for structured logging:
    // Log with structured fields
    logger.Info("connection established",
        go_logs.String("host", "db.example.com"),
        go_logs.Int("port", 5432),
    )

    logger.Error("database query failed",
        go_logs.Err(err),
        go_logs.String("query", "SELECT * FROM users"),
        go_logs.Int("duration_ms", 150),
    )
}

Complete example

Here’s a complete working example:
package main

import (
    "os"
    "github.com/drossan/go_logs"
)

func main() {
    // Create logger with configuration
    logger, err := go_logs.New(
        go_logs.WithLevel(go_logs.InfoLevel),
        go_logs.WithFormatter(go_logs.NewTextFormatter()),
        go_logs.WithOutput(os.Stdout),
    )
    if err != nil {
        panic(err)
    }
    defer logger.Sync()

    // Log with structured fields
    logger.Info("connection established",
        go_logs.String("host", "db.example.com"),
        go_logs.Int("port", 5432),
    )

    // Log different levels
    logger.Debug("processing request", go_logs.String("endpoint", "/api/users"))
    logger.Warn("high memory usage", go_logs.Float64("usage_percent", 85.5))
    
    // Log errors with error field
    if err := performOperation(); err != nil {
        logger.Error("operation failed",
            go_logs.Err(err),
            go_logs.String("operation", "database_query"),
        )
    }
}

func performOperation() error {
    // Simulated operation
    return nil
}

Available field types

go_logs provides typed helpers for common field types:
// String values
go_logs.String("username", "john")

// Integer values
go_logs.Int("status_code", 200)
go_logs.Int64("user_id", 123456789)

// Floating point values
go_logs.Float64("cpu_percent", 45.7)

// Boolean values
go_logs.Bool("debug_mode", true)

// Error values (key is automatically "error")
go_logs.Err(err)

// Any type (uses fmt.Sprintf)
go_logs.Any("metadata", map[string]string{"ip": "192.168.1.1"})

Child loggers

Create child loggers with pre-populated fields that automatically propagate:
// Create base logger
logger, _ := go_logs.New(go_logs.WithLevel(go_logs.InfoLevel))

// Create child logger with request context
reqLogger := logger.With(
    go_logs.String("request_id", "abc-123"),
    go_logs.String("user_id", "user-456"),
)

// All logs include request_id and user_id
reqLogger.Info("request started")
reqLogger.Info("processing data")
reqLogger.Error("validation failed")
Output:
[2026/03/03 10:30:00] INFO request started request_id=abc-123 user_id=user-456
[2026/03/03 10:30:00] INFO processing data request_id=abc-123 user_id=user-456
[2026/03/03 10:30:00] ERROR validation failed request_id=abc-123 user_id=user-456

Context propagation

Use LogCtx to automatically extract trace information from context:
import (
    "context"
    "github.com/drossan/go_logs"
)

func handler(ctx context.Context) {
    // Add trace ID to context
    ctx = go_logs.WithTraceID(ctx, "trace-789")
    ctx = go_logs.WithSpanID(ctx, "span-101")

    // Logger extracts trace_id and span_id automatically
    logger, _ := go_logs.New()
    logger.LogCtx(ctx, go_logs.InfoLevel, "processing request")
    // Output includes: trace_id=trace-789 span_id=span-101
}

JSON formatter

Switch to JSON format for production log aggregators:
logger, _ := go_logs.New(
    go_logs.WithLevel(go_logs.InfoLevel),
    go_logs.WithFormatter(go_logs.NewJSONFormatter()),
    go_logs.WithOutput(os.Stdout),
)

logger.Info("user action",
    go_logs.String("action", "login"),
    go_logs.String("username", "john"),
)
Output:
{"timestamp":"2026-03-03T10:30:00Z","level":"INFO","message":"user action","fields":{"action":"login","username":"john"}}

Legacy API (v2)

The v2 API is still fully supported for backward compatibility:
import "github.com/drossan/go_logs"

func main() {
    go_logs.Init() // Optional, auto-initializes
    defer go_logs.Close()

    go_logs.InfoLog("Server started")
    go_logs.ErrorLog("Connection error")
    go_logs.Infof("Port: %d", 8080)
}
While the v2 API works, we recommend using the v3 API for new code to take advantage of structured logging and modern features.

Next steps

Configuration

Configure loggers with environment variables and options

Structured fields

Learn about all available field types and usage

Formatters

Explore text and JSON formatters in detail

Child loggers

Master child loggers and field propagation

Build docs developers (and LLMs) love