logger

package module
v0.0.0-...-ca7c364 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 10, 2025 License: MIT Imports: 14 Imported by: 2

README

Go Logger

Lightweight, flexible logging library built on Go's log/slog with multi-output support, structured fields, custom templates, colors, and automatic rotation.

Features

  • Multi-output: Console & file with independent configuration
  • Flexible formats: Text, JSON, and custom template support
  • Smart coloring: ANSI colors for console (auto-disabled for files)
  • Auto-rotation: Size-based rotation with configurable retention
  • Structured logging: Full slog API with groups and attributes
  • Attribute transformation: Custom processing via WithReplaceAttr
  • Drop-in replacement: Embeds *slog.Logger + easy SetDefault()
  • High performance: Lock-free formatting + efficient I/O

Installation

go get github.com/simp-lee/logger

Quick Start

package main

import "github.com/simp-lee/logger"

func main() {
    log, err := logger.New()
    if err != nil {
        panic(err)
    }
    defer log.Close()

    log.Info("Hello, world!")
    log.Info("User login", "userId", 123, "username", "johndoe")
}

Quick Configuration Reference

All options are functional options passed to logger.New(...). Only configure what you need; unspecified fields fall back to sane defaults.

Configuration Options

Global Options
Option Description Default
WithLevel Set the minimum logging level slog.LevelInfo
WithAddSource Include source file information false
WithTimeFormat Format for timestamp "2006/01/02 15:04:05"
WithTimeZone Time zone for timestamps time.Local
WithReplaceAttr Custom attribute transformation function nil
Console Options
Option Description Default
WithConsole Enable console logging true
WithConsoleColor Enable colored output in console true
WithConsoleFormat Console log format (FormatText, FormatJSON, FormatCustom) FormatCustom
WithConsoleFormatter Custom format template for console "{time} {level} {message} {file} {attrs}"
File Options
Option Description Default
WithFile Enable file logging false
WithFilePath Path to the log file (enables file logging automatically) ""
WithFileFormat File log format (FormatText, FormatJSON, FormatCustom) FormatCustom
WithFileFormatter Custom format template for file "{time} {level} {message} {file} {attrs}"
WithMaxSizeMB Maximum size of log file before rotation (0 to disable rotation) 10
WithRetentionDays Days to retain rotated log files (<=0 resets to default) 7
Compatibility Options

These options set both console and file configurations at once:

Option Description Affects
WithFormat Set log format for both console and file Console & File
WithFormatter Set formatter for both console and file Console & File

Custom Formatting

Templates (FormatCustom) accept these placeholders:

Placeholder Meaning
{time} Timestamp (formatted via WithTimeFormat + WithTimeZone)
{level} Log level string (DEBUG, INFO, WARN, ERROR)
{message} Log message text
{file} filename:function:line (only if WithAddSource(true))
{attrs} User attributes (key=value ...)

Example:

log, err := logger.New(
    logger.WithConsoleFormatter("{time} | {level} | {message} | {attrs}"),
)
if err != nil {
    panic(err)
}
defer log.Close()

If a placeholder produces empty content (e.g. {file} without source), surrounding extra spaces are minimized automatically.

Color Output

Console coloring (ANSI) can be toggled with WithConsoleColor(true/false). File output never includes color. Levels map to Bright Cyan / Green / Yellow / Red; error messages & error attribute keys are emphasized.

Mixed Formats (Console vs File)

Formats are independent. Common pattern: human-readable console + structured file:

log, err := logger.New(
    logger.WithConsoleFormat(logger.FormatCustom),
    logger.WithConsoleFormatter("{time} {level} {message}"),
    logger.WithConsoleColor(true),
    logger.WithFilePath("./logs/app.log"),
    logger.WithFileFormat(logger.FormatJSON),
)
if err != nil {
    panic(err)
}
defer log.Close()

File Rotation & Retention

  • Trigger: size > WithMaxSizeMB(N) MB. Set 0 to disable rotation. Negative values reset to default (10MB).
  • Naming pattern: basename.YYYYMMDD.HHMMSS.mmm.ext (adds .counter if collision).
  • Retention: Files older than WithRetentionDays(D) days are purged daily; <=0 resets to default (7 days).

Example:

log, err := logger.New(
    logger.WithFilePath("./logs/app.log"),
    logger.WithMaxSizeMB(50),
    logger.WithRetentionDays(30),
)
if err != nil {
    panic(err)
}
defer log.Close()

Multiple Outputs

Enable console + file together. WithFilePath implies WithFile(true). At least one destination must remain enabled; disabling both returns an error.

Attribute Transformation (WithReplaceAttr)

Intercept & edit/remove attributes (including built-ins: time, level, message, source, and user attrs). Return an empty slog.Attr{} to drop an attribute.

log, err := logger.New(
    logger.WithReplaceAttr(func(groups []string, a slog.Attr) slog.Attr {
        if a.Key == "user_id" {
            return slog.String("userId", a.Value.String())
        }
        return a
    }),
)
if err != nil {
    panic(err)
}
defer log.Close()

Standard Library Integration

Because Logger embeds *slog.Logger, you get the full slog API. Call SetDefault() to route global slog.* calls:

log, err := logger.New(logger.WithAddSource(true))
if err != nil {
    panic(err)
}
defer log.Close()

log.SetDefault()
slog.Info("uses custom logger", "module", "auth")

Complete Example

package main

import (
    "log/slog"
    "github.com/simp-lee/logger"
)

func main() {
    log, err := logger.New(
        logger.WithLevel(slog.LevelDebug),
        logger.WithAddSource(true),
        logger.WithConsoleFormatter("{time} [{level}] {message} {attrs}"),
        logger.WithFilePath("./logs/app.log"),
        logger.WithFileFormat(logger.FormatJSON),
    )
    if err != nil {
        panic(err)
    }
    defer log.Close()
    
    log.Info("startup", "version", "1.0.0")
    userLogger := log.WithGroup("user")
    userLogger.Info("login", "id", 42)
}

Performance

Thread-safe with optimized performance (Windows amd64, i5-13500H).

Performance Benchmarks
Test Scenario Performance (ns/op) Memory (B/op) Allocations Notes
Memory Output ~367 1,055 17 Baseline performance
File Output ~8,730 24 2 Optimized I/O with buffering
Text Format ~367 738 17 Human readable
JSON Format ~359 738 17 Structured data
Custom Format ~390 737 17 Flexible formatting
With Color ~871 1,234 22 Enhanced readability
Without Color ~791 889 18 ~9% faster than colored
No Rotation ~8,996 32 2 File rotation disabled
With Rotation ~8,908 32 2 Minimal rotation overhead (~1%)
Concurrent Logging ~373 698 14 Multi-threaded safe
Multi-Handler ~687 1,454 31 Multiple output targets
Concurrent Tests
Scenario Goroutines Messages Throughput (msg/sec)
Basic Concurrent 100 100,000 ~1,799,474
Multi-Handler 50 5,000 ~242,502
File Rotation 20 10,000 ~108,780
High-Load Stress 200 20,000 ~701,498

Key insights: Concurrent logging achieves ~2.7M msg/sec theoretical peak. Production workloads typically see 500K-1.8M msg/sec depending on I/O patterns and template complexity.

License

MIT License

Documentation

Index

Constants

View Source
const (
	FormatText   OutputFormat = "text"
	FormatJSON   OutputFormat = "json"
	FormatCustom OutputFormat = "custom"

	DefaultTimeFormat    = "2006/01/02 15:04:05"
	DefaultMaxSizeMB     = 10
	DefaultRetentionDays = 7
	DefaultFormatter     = "{time} {level} {message} {file} {attrs}"
	DefaultFormat        = FormatText
)
View Source
const (
	// Placeholders
	PlaceholderTime    = "{time}"
	PlaceholderLevel   = "{level}"
	PlaceholderMessage = "{message}"
	PlaceholderFile    = "{file}"
	PlaceholderAttrs   = "{attrs}"
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Config

type Config struct {
	// Base configuration
	Level      slog.Level
	AddSource  bool
	TimeFormat string
	TimeZone   *time.Location

	// Configurations for different log destinations
	Console ConsoleConfig
	File    FileConfig

	// ReplaceAttr is a function that can be used to replace attributes in log messages
	ReplaceAttr func(groups []string, a slog.Attr) slog.Attr
}

func DefaultConfig

func DefaultConfig() *Config

type ConsoleConfig

type ConsoleConfig struct {
	Enabled   bool         // Enable console logging
	Color     bool         // Enable colorized output
	Format    OutputFormat // text, json, custom
	Formatter string       // Custom formatter string, only used if Format is FormatCustom
}

func (*ConsoleConfig) GetColor

func (c *ConsoleConfig) GetColor() bool

func (*ConsoleConfig) GetFormat

func (c *ConsoleConfig) GetFormat() OutputFormat

ConsoleConfig implements outputConfig interface

func (*ConsoleConfig) GetFormatter

func (c *ConsoleConfig) GetFormatter() string

type FileConfig

type FileConfig struct {
	Enabled       bool
	Format        OutputFormat
	Formatter     string // Custom formatter string, only used if Format is FormatCustom
	Path          string // Path to the log file
	MaxSizeMB     int    // Maximum size of the log file in megabytes
	RetentionDays int    // Number of days to retain log files
}

func (*FileConfig) GetColor

func (c *FileConfig) GetColor() bool

func (*FileConfig) GetFormat

func (c *FileConfig) GetFormat() OutputFormat

FileConfig implements outputConfig interface

func (*FileConfig) GetFormatter

func (c *FileConfig) GetFormatter() string

type Logger

type Logger struct {
	*slog.Logger
	// contains filtered or unexported fields
}

Logger wraps slog.Logger with automatic resource management By embedding *slog.Logger, it inherits all methods like Info, Error, Debug, Warn, With, WithGroup, etc.

func Default

func Default() *Logger

Default returns a new Logger using the default slog configuration

func New

func New(opts ...Option) (*Logger, error)

New creates a new Logger with automatic resource cleanup This is the recommended way to create a logger

func (*Logger) Close

func (l *Logger) Close() error

Close cleans up any resources held by the logger Always call this when you're done with the logger to prevent resource leaks

func (*Logger) SetDefault

func (l *Logger) SetDefault()

SetDefault sets the current logger as the default logger After setting, standard library calls like slog.Info(), slog.Error() will use this logger Note: Since Logger embeds *slog.Logger, the following methods can be used directly without additional implementation: - With(args ...any): Adds attributes and returns a new Logger - WithGroup(name string): Adds a group and returns a new Logger - Info, Warn, Error, Debug and other log level methods

type Option

type Option func(*Config)

Option is a function that modifies a Config

func WithAddSource

func WithAddSource(addSource bool) Option

func WithConsole

func WithConsole(enabled bool) Option

func WithConsoleColor

func WithConsoleColor(enabled bool) Option

func WithConsoleFormat

func WithConsoleFormat(format OutputFormat) Option

func WithConsoleFormatter

func WithConsoleFormatter(formatter string) Option

WithConsoleFormatter sets the console formatter for logging, and automatically sets the format to FormatCustom The formatter string can contain the following placeholders: - {time}: The timestamp of the log message - {level}: The log level of the message - {message}: The log message - {file}: The source file where the log message was generated - {attrs}: Any additional attributes associated with the log message For example: "{time} [{level}] {file} {message} {attrs}"

func WithFile

func WithFile(enabled bool) Option

func WithFileFormat

func WithFileFormat(format OutputFormat) Option

func WithFileFormatter

func WithFileFormatter(formatter string) Option

func WithFilePath

func WithFilePath(path string) Option

func WithFormat

func WithFormat(format OutputFormat) Option

WithFormat sets the format of the log message for both console and file logging

func WithFormatter

func WithFormatter(formatter string) Option

WithFormatter sets the formatter for both console and file logging, and automatically sets the format to FormatCustom

func WithLevel

func WithLevel(level slog.Level) Option

func WithMaxSizeMB

func WithMaxSizeMB(maxSizeMB int) Option

WithMaxSizeMB sets the maximum size of the log file in megabytes. Set to 0 to disable file rotation. Negative values will be reset to the default.

func WithReplaceAttr

func WithReplaceAttr(replaceAttr func(groups []string, a slog.Attr) slog.Attr) Option

WithReplaceAttr sets a function that can be used to replace attributes in log messages

func WithRetentionDays

func WithRetentionDays(retentionDays int) Option

WithRetentionDays sets the number of days to retain log files

func WithTimeFormat

func WithTimeFormat(timeFormat string) Option

func WithTimeZone

func WithTimeZone(timeZone *time.Location) Option

type OutputFormat

type OutputFormat string

type ParsedTemplate

type ParsedTemplate struct {
	// contains filtered or unexported fields
}

ParsedTemplate holds the pre-parsed template tokens

type Token

type Token struct {
	Type TokenType
	Text string // For static text tokens
}

Token represents a parsed template component

type TokenType

type TokenType int

TokenType represents the type of a template token

const (
	TokenTypeText TokenType = iota
	TokenTypeTime
	TokenTypeLevel
	TokenTypeMessage
	TokenTypeFile
	TokenTypeAttrs
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL