Skip to content

Commit

Permalink
chore: cosmetic changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mr-karan committed Jun 27, 2022
1 parent 28e15f5 commit e0cb9b1
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 53 deletions.
38 changes: 26 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
[![GitHub Actions](https://github.com/mr-karan/logf/actions/workflows/build.yml/badge.svg)](https://github.com/mr-karan/logf/actions/workflows/build.yml)


logf provides a minimal logging interface for Go applications. It emits **structured logs** ([`logfmt`](https://brandur.org/logfmt) style) in human readable and machine friendly way.
logf is a **high performance** logging library Go applications with a **minimal** API overhead. It emits **structured logs** ([`logfmt`](https://brandur.org/logfmt) style) in human readable and machine friendly way. `logf` tries to be customisable without providing an overwhelming amount of things to configure before you start logging in your Go apps.

## Example

Expand Down Expand Up @@ -62,7 +62,6 @@ timestamp=2022-06-26T11:56:46+05:30 level=error message=error fetching details e
timestamp=2022-06-26T11:56:46.412189111+05:30 level=info message=request success ip=1.1.1.1 method=GET request_id=3MG91VKP
timestamp=2022-06-26T11:56:46.412204619+05:30 level=warn message=this isn't supposed to happen ip=1.1.1.1 level=warn message=this isn't supposed to happen method=GET request_id=3MG91VKP timestamp=2022-06-26T11:56:46.412204619+05:30
timestamp=2022-06-26T11:56:46.412218628+05:30 level=fatal message=goodbye world ip=1.1.1.1 level=fatal message=goodbye world method=GET request_id=3MG91VKP timestamp=2022-06-26T11:56:46.412218628+05:30
exit status 1
```

### Console Output
Expand All @@ -84,21 +83,36 @@ Agreed there are many logging libraries out there but I was dissatisfied with th

You can run benchmarks with `make bench`.

**Note**
> Enabling color significantly affects performance. You should enable them only in scenarios where this isn't a concern (for eg single run CLI apps etc.)
### No Colors (Default)

```
BenchmarkNoField-8 6720405 172.8 ns/op 40 B/op 3 allocs/op
BenchmarkOneField-8 2377168 597.5 ns/op 376 B/op 5 allocs/op
BenchmarkThreeFields-8 1951350 540.5 ns/op 384 B/op 6 allocs/op
BenchmarkThreeFields_WithCaller-8 742970 1551 ns/op 680 B/op 10 allocs/op
BenchmarkErrorField-8 2714325 442.5 ns/op 392 B/op 6 allocs/op
BenchmarkHugePayload-8 531368 2151 ns/op 1427 B/op 17 allocs/op
```

### With Colors

```
BenchmarkNoField-8 290559 3797 ns/op 1576 B/op 74 allocs/op
BenchmarkNoField_NoColor-8 1313766 924.8 ns/op 328 B/op 11 allocs/op
BenchmarkOneField-8 219285 5445 ns/op 2609 B/op 103 allocs/op
BenchmarkOneField_NoColor-8 668251 1550 ns/op 928 B/op 19 allocs/op
BenchmarkThreeFields-8 152988 7992 ns/op 3953 B/op 153 allocs/op
BenchmarkThreeFields_NoColor-8 516135 2220 ns/op 1320 B/op 27 allocs/op
BenchmarkHugePayload-8 57367 22658 ns/op 15121 B/op 356 allocs/op
BenchmarkHugePayload_NoColor-8 140937 7404 ns/op 8342 B/op 62 allocs/op
BenchmarkErrorField-8 212184 5639 ns/op 2657 B/op 104 allocs/op
BenchmarkErrorField_NoColor-8 703165 1593 ns/op 952 B/op 20 allocs/op
BenchmarkNoField_WithColor-8 398384 2992 ns/op 1200 B/op 66 allocs/op
BenchmarkOneField_WithColor-8 227470 5106 ns/op 2320 B/op 110 allocs/op
BenchmarkThreeFields_WithColor-8 120404 9819 ns/op 3921 B/op 195 allocs/op
BenchmarkHugePayload_WithColor-8 45508 25975 ns/op 11344 B/op 542 allocs/op
BenchmarkErrorField_WithColor-8 237148 5357 ns/op 2336 B/op 111 allocs/op
```

For a comparison with existing popular libs, visit [uber-go/zap#performance](https://github.com/uber-go/zap#performance).

## Contributors

- [Sarat](https://github.com/iamd3vil/)

## LICENSE

[LICENSE](./LICENSE)
94 changes: 55 additions & 39 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,6 @@ func BenchmarkNoField(b *testing.B) {
}
}

func BenchmarkNoField_NoColor(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(false)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
logger.Info("hello world")
}
}

func BenchmarkOneField(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
Expand All @@ -39,20 +28,25 @@ func BenchmarkOneField(b *testing.B) {
}
}

func BenchmarkOneField_NoColor(b *testing.B) {
func BenchmarkThreeFields(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(false)
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
logger.WithFields(logf.Fields{"stack": "testing"}).Info("hello world")
logger.WithFields(logf.Fields{
"component": "api",
"method": "GET",
"bytes": 1 << 18,
}).Info("request completed")
}
}

func BenchmarkThreeFields(b *testing.B) {
func BenchmarkThreeFields_WithCaller(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetCallerFrame(true, 3)
b.ReportAllocs()
b.ResetTimer()

Expand All @@ -65,19 +59,16 @@ func BenchmarkThreeFields(b *testing.B) {
}
}

func BenchmarkThreeFields_NoColor(b *testing.B) {
func BenchmarkErrorField(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(false)
b.ReportAllocs()
b.ResetTimer()

fakeErr := errors.New("fake error")

for i := 0; i < b.N; i++ {
logger.WithFields(logf.Fields{
"component": "api",
"method": "GET",
"bytes": 1 << 18,
}).Info("request completed")
logger.WithError(fakeErr).Error("request failed")
}
}

Expand Down Expand Up @@ -109,10 +100,48 @@ func BenchmarkHugePayload(b *testing.B) {
}
}

func BenchmarkHugePayload_NoColor(b *testing.B) {
func BenchmarkNoField_WithColor(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(true)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
logger.Info("hello world")
}
}

func BenchmarkOneField_WithColor(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(false)
logger.SetColorOutput(true)
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
logger.WithFields(logf.Fields{"stack": "testing"}).Info("hello world")
}
}

func BenchmarkThreeFields_WithColor(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(true)
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
logger.WithFields(logf.Fields{
"component": "api",
"method": "GET",
"bytes": 1 << 18,
}).Info("request completed")
}
}

func BenchmarkHugePayload_WithColor(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(true)
b.ReportAllocs()
b.ResetTimer()

Expand All @@ -138,23 +167,10 @@ func BenchmarkHugePayload_NoColor(b *testing.B) {
}
}

func BenchmarkErrorField(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
b.ReportAllocs()
b.ResetTimer()

fakeErr := errors.New("fake error")

for i := 0; i < b.N; i++ {
logger.WithError(fakeErr).Error("request failed")
}
}

func BenchmarkErrorField_NoColor(b *testing.B) {
func BenchmarkErrorField_WithColor(b *testing.B) {
logger := logf.New()
logger.SetWriter(io.Discard)
logger.SetColorOutput(false)
logger.SetColorOutput(true)
b.ReportAllocs()
b.ResetTimer()

Expand Down
3 changes: 3 additions & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ func main() {
// Basic log.
logger.Info("starting app")

// Enable colored output.
logger.SetColorOutput(true)

// Change verbosity on the fly.
logger.SetLevel(logf.DebugLevel)
logger.Debug("meant for debugging app")
Expand Down
Binary file modified examples/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 5 additions & 1 deletion log.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ func New() *Logger {
bufW: bytes.NewBuffer([]byte{}),
level: InfoLevel,
tsFormat: time.RFC3339,
enableColor: true,
enableColor: false,
enableCaller: false,
callerSkipFrameCount: 0,
fields: make(Fields, 0),
Expand Down Expand Up @@ -203,6 +203,10 @@ func (l *Logger) handleLog(msg string, lvl Level) {
l.writeToBuf("level", lvl, lvl, l.enableColor, true)
l.writeToBuf("message", msg, lvl, l.enableColor, true)

if l.enableCaller {
l.writeToBuf("caller", caller(l.callerSkipFrameCount), lvl, l.enableColor, true)
}

// Format the line as logfmt.
var count int // count is find out if this is the last key in while itering l.fields.
for k, v := range l.fields {
Expand Down
2 changes: 1 addition & 1 deletion log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func TestLevelParsing(t *testing.T) {
func TestNewLoggerDefault(t *testing.T) {
l := New()
assert.Equal(t, l.level, InfoLevel, "level is info")
assert.Equal(t, l.enableColor, true, "color output is enabled")
assert.Equal(t, l.enableColor, false, "color output is disabled")
assert.Equal(t, l.enableCaller, false, "caller is disabled")
assert.Equal(t, l.callerSkipFrameCount, 0, "skip frame count is 0")
assert.Equal(t, l.tsFormat, time.RFC3339, "timestamp format is RFC3399")
Expand Down

0 comments on commit e0cb9b1

Please sign in to comment.