[中文版本]

RainbowLog v1 is released! From v0.0.12 all the way to v1.0.1, this major release brings a cleaner package structure, a more concise API, and numerous performance optimizations and bug fixes. This article covers the key improvements from v0.0.12 to v1.0.1 and explains the API differences between the old and new versions.

Version Evolution

Version Highlights
v0.0.12 Baseline
v0.0.13 Windows console ANSI support
v0.0.14 Major refactoring + Bug fixes + Performance optimizations + Test coverage
v1.0.0 Package restructure: core moved to log/, global logger moved to global/
v1.0.1 Global logger package renamed from global/ to logger/

Detailed Changelog

v0.0.13 — Windows Console Color Support

Added record_packer_console_windows.go, enabling colored log output on Windows terminals. Windows users no longer have to suffer through monochrome logs.

v0.0.14 — Comprehensive Polish

The most change-intensive version before v1, with 22 commits:

Bug Fixes:

  • Fixed short write error handling
  • Added nil check for []byte input in ObjectData method
  • Fixed duplicate first element issue when encoding duration slices
  • Fixed SubLogger shallow copywriterEncoders now uses deep copy, child Logger modifications no longer affect the parent
  • Attach detailed error info when loading config files fails

Performance Optimizations:

  • Pre-built text encoder to avoid per-createRecord allocation
  • Global logger changed to lazy init + sync.Mutex double-check, init() removed
  • Caller path truncation logic optimized

New Features:

  • Added TimeFormatUnixNano (UNIXNANO) nanosecond time format
  • Added TimestampFunc variable for customizable time source (useful for testing)

Refactoring:

  • Refactored BufferedLevelWriter to properly implement LevelWriter interface
  • Fixed text encoder incorrectly using JSONMarshalFunc, replaced with TextMarshalFunc
  • Simplified multiLevelWriter.WriteLevel implementation
  • NewTextEncoder changed from var to func
  • Removed unused mutex from LogRecord

Testing: Added tests for encoder interface, hex, float/int slices, strings, etc.

Build: Go version upgraded from 1.23 to 1.26, added golang.org/x/sync dependency.

v1.0.0 — Package Restructure (Breaking Change)

The largest structural adjustment: all core files moved from the root into the log/ sub-package, and the global logger moved from log/global_logger.go to the new global/ package.

Old Path (v0.x) New Path (v1.0.0)
encoder.go log/encoder.go
logger.go log/logger.go
option.go log/option.go
record.go log/record.go
writer.go log/writer.go
log/global_logger.go global/global_logger.go

v1.0.1 — Global Logger Package Renamed (Breaking Change)

Global logger package renamed from global/ to logger/ for better clarity.


Old vs. New API Comparison

1. Global Logger — Import Path & Calling Convention

v0.x (old way):

1
2
3
4
5
6
7
import "github.com/rambollwong/rainbowlog/log"

func main() {
log.UseDefault()
log.Logger.Info().Msg("Hello world!").Done()
// ^^^^^^ must go through the Logger field
}

v1.x (new way):

1
2
3
4
5
6
7
import "github.com/rambollwong/rainbowlog/logger"

func main() {
logger.UseDefault()
logger.Info().Msg("Hello world!").Done()
// ^^ package-level function, no .Logger needed
}

⚠️ Changes:

  • Import path: rainbowlog/lograinbowlog/logger
  • Calling convention: log.Logger.Info()logger.Info() (package-level convenience function)
  • Initialization: from init() auto-call to lazy init on first use

2. Custom Logger — Type Prefix Changes

v0.x (old way):

1
2
3
4
5
6
import "github.com/rambollwong/rainbowlog"

logger := rainbowlog.New(
rainbowlog.WithDefault(),
rainbowlog.AppendsEncoderWriters(rainbowlog.JsonEnc, os.Stderr),
)

v1.x (new way):

1
2
3
4
5
6
import "github.com/rambollwong/rainbowlog/log"

logger := log.New(
log.WithDefault(),
log.AppendsEncoderWriters(log.JsonEnc, os.Stderr),
)

⚠️ All type and function prefixes change from rainbowlog.XXX to log.XXX.

3. Complete Type Reference Mapping

Concept v0.x Prefix v1.x Prefix
Logger type *rainbowlog.Logger *log.Logger
Constructor rainbowlog.New(...) log.New(...)
Option type rainbowlog.Option log.Option
Record type rainbowlog.Record log.Record
Hook types rainbowlog.Hook / rainbowlog.HookFunc log.Hook / log.HookFunc
LevelWriter rainbowlog.LevelWriter log.LevelWriter
Encoders rainbowlog.JsonEnc / rainbowlog.TextEnc log.JsonEnc / log.TextEnc
Time format constants rainbowlog.TimeFormatUnix log.TimeFormatUnix
ConsolePacker rainbowlog.ConsolePacker log.ConsolePacker
Global functions rainbowlog.GlobalCallerMarshalFunc log.GlobalCallerMarshalFunc

4. Default Config File Name Change

Version Default Config File
v0.x rainbowlog.yaml
v1.x log.yaml

5. New Features at a Glance

Nanosecond time format (added in v0.0.14):

1
log.WithTimeFormat(log.TimeFormatUnixNano) // outputs nanosecond Unix timestamp

Customizable time source (added in v0.0.14):

1
2
3
log.TimestampFunc = func() time.Time {
return time.Date(2025, 1, 1, 0, 0, 0, 0, time.UTC)
}

SubLogger deep copy (fixed in v0.0.14): child Logger’s writerEncoders is now an independent copy — modifying a child Logger no longer affects the parent.


Upgrade Guide

To upgrade from v0.x to v1.x:

  1. Global Logger import: "rainbowlog/log""rainbowlog/logger"
  2. Global Logger calls: log.Logger.XXX()logger.XXX() (package-level functions)
  3. Custom Logger import: switch to "rainbowlog/log", type prefix rainbowlog.log.
  4. Config file: default filename rainbowlog.yamllog.yaml
  5. Go version: requires Go 1.26+

Github Repository

https://github.com/rambollwong/rainbowlog

If you find this project useful, please give it a ⭐. Your support is my greatest motivation!


💰 Support with a Donation

If you like this project, feel free to buy the author a cup of lemonade ☕️. Your support is my motivation for continuous updates!

  • WeChat Pay:
  • Alipay: