SkillAgentSearch skills...

Golog

Super fast, unstructured logging in Go.

Install / Use

/learn @keakon/Golog
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

golog

GoDoc Build Status Go Report Card codecov

Features

  1. Unstructured
  2. Leveled
  3. With caller (file path / name and line number)
  4. Customizable output format
  5. Rotating by size, date or hour
  6. Cross platform, tested on Linux, macOS and Windows
  7. No 3rd party dependance
  8. Fast
  9. 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):

  1. The timer updates every 1 second, so the logging time can be at most 1 second behind the real time.
  2. 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
  1. 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.Discard with zerolog
  • DiscardZap: writes logs to ioutil.Discard with zap using zap.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

View on GitHub
GitHub Stars39
CategoryDevelopment
Updated7mo ago
Forks3

Languages

Go

Security Score

87/100

Audited on Aug 29, 2025

No findings