Golog
Super fast, unstructured logging in Go.
Install / Use
/learn @keakon/GologREADME
golog
Features
- Unstructured
- Leveled
- With caller (file path / name and line number)
- Customizable output format
- Rotating by size, date or hour
- Cross platform, tested on Linux, macOS and Windows
- No 3rd party dependance
- Fast
- Thread safe
Installation
go get -u github.com/keakon/golog
Examples
Logging to console
package main
import (
"github.com/keakon/golog"
"github.com/keakon/golog/log"
)
func main() {
l := golog.NewStdoutLogger()
defer l.Close()
l.Infof("hello %d", 1)
log.SetDefaultLogger(l)
test()
}
func test() {
log.Infof("hello %d", 2)
}
Logging to file
func main() {
w, _ := golog.NewBufferedFileWriter("test.log")
l := golog.NewLoggerWithWriter(w)
defer l.Close()
l.Infof("hello world")
}
Rotating
func main() {
w, _ := golog.NewTimedRotatingFileWriter("test", golog.RotateByDate, 30)
l := golog.NewLoggerWithWriter(w)
defer l.Close()
l.Infof("hello world")
}
Formatting
func main() {
w := golog.NewStdoutWriter()
f := golog.ParseFormat("[%l %D %T %S] %m")
h := golog.NewHandler(golog.InfoLevel, f)
h.AddWriter(w)
l := golog.NewLogger(golog.InfoLevel)
l.AddHandler(h)
defer l.Close()
l.Infof("hello world")
}
Check document for more format directives.
Fast timer
func main() {
golog.StartFastTimer()
defer golog.StopFastTimer()
l := golog.NewStdoutLogger()
defer l.Close()
l.Infof("hello world")
}
The fast timer is about 30% faster than calling time.Time() for each logging record. But it's not thread-safe which may cause some problems (I think those are negligible in most cases):
- The timer updates every 1 second, so the logging time can be at most 1 second behind the real time.
- Each thread will notice the changes of timer in a few milliseconds, so the concurrent logging messages may get different logging time (less than 2% probability). eg:
[I 2021-09-13 14:31:25 log_test:206] test
[I 2021-09-13 14:31:24 log_test:206] test
[I 2021-09-13 14:31:25 log_test:206] test
- When the day changing, the logging date and time might belong to different day. eg:
[I 2021-09-12 23:59:59 log_test:206] test
[I 2021-09-13 23:59:59 log_test:206] test
[I 2021-09-12 00:00:00 log_test:206] test
ConcurrentFileWriter (experimental)
func main() {
w, _ := golog.NewConcurrentFileWriter("test.log")
l := golog.NewLoggerWithWriter(w)
defer l.Close()
l.Infof("hello world")
}
The ConcurrentFileWriter is designed for high concurrency applications.
It is about 140% faster than BufferedFileWriter at 6C12H by reducing the lock overhead, but a little slower at single thread.
Note: The order of logging records from different cpu cores within each 0.1 second is random.
Benchmarks
Platform
go1.19.2 darwin/amd64 cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Result
| Name | Time/op | Time (x) | Alloc/op | allocs/op | | :--- | :---: | :---: | :---: | :---: | | DiscardLogger | 483ns ± 1% | 1.00 | 0B | 0 | | DiscardLoggerParallel | 89.0ns ± 6% | 1.00 | 0B | 0 | | DiscardLoggerWithoutTimer | 691ns ± 7% | 1.43 | 0B | 0 | | DiscardLoggerWithoutTimerParallel | 129ns ± 5% | 1.45 | 0B | 0 | | NopLog | 1.5ns ± 1% | 0.003 | 0B | 0 | | NopLogParallel | 0.22ns ± 3% | 0.002 | 0B | 0 | | MultiLevels | 2.77µs ± 7% | 5.73 | 0B | 0 | | MultiLevelsParallel | 532ns ± 15% | 5.98 | 0B | 0 | | BufferedFileLogger | 588ns ± 2% | 1.22 | 0B | 0 | | BufferedFileLoggerParallel | 241ns ± 1% | 2.71 | 0B | 0 | | ConcurrentFileLogger | 593ns ± 1% | 1.23 | 0B | 0 | | ConcurrentFileLoggerParallel | 101ns ± 2% | 1.13 | 0B | 0 | | | | | | | | DiscardZerolog | 2.24µs ± 1% | 4.64 | 280B | 3 | | DiscardZerologParallel | 408ns ± 10% | 4.58 | 280B | 3 | | DiscardZap | 2.13µs ± 0% | 4.41 | 272B | 5 | | DiscardZapParallel | 465ns ± 5% | 5.22 | 274B | 5 |
- DiscardLogger: writes logs to
ioutil.Discard - DiscardLoggerWithoutTimer: the same as above but without fast timer
- NopLog: skips logs with lower level than the logger or handler
- MultiLevels: writes 5 levels of logs to 5 levels handlers of a warning level logger
- BufferedFileLogger: writes logs to a disk file
- ConcurrentFileLogger: writes logs to a disk file with
ConcurrentFileWriter - DiscardZerolog: writes logs to
ioutil.Discardwith zerolog - DiscardZap: writes logs to
ioutil.Discardwith zap usingzap.NewProductionEncoderConfig()
All the logs include 4 parts: level, time, caller and message. This is an example output of the benchmarks:
[I 2018-11-20 17:05:37 log_test:118] test
Related Skills
node-connect
347.0kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
xurl
347.0kA CLI tool for making authenticated requests to the X (Twitter) API. Use this skill when you need to post tweets, reply, quote, search, read posts, manage followers, send DMs, upload media, or interact with any X API v2 endpoint.
frontend-design
107.8kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.0kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
