Skip to content

Commit

Permalink
Merge pull request #13 from iamd3vil/default-fields
Browse files Browse the repository at this point in the history
feat: Add default options to opts which gets logged with every log.
  • Loading branch information
mr-karan authored Jul 7, 2022
2 parents 77491f1 + d91f472 commit 6a1a75c
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 21 deletions.
25 changes: 10 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,23 @@
package main

import (
"os"
"time"

"github.com/zerodha/logf"
)

func main() {
logger := logf.New(os.Stderr)

// Basic log.
logger := logf.New(logf.Opts{
EnableColor: true,
Level: logf.DebugLevel,
CallerSkipFrameCount: 3,
EnableCaller: true,
TimestampFormat: time.RFC3339Nano,
DefaultFields: []any{"scope", "example"},
})

// Basic logs.
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")

// Add extra keys to the log.
Expand All @@ -41,11 +41,6 @@ func main() {
// Log with error key.
logger.Error("error fetching details", "error", "this is a dummy error")

// Enable `caller` field in the log and specify the number of frames to skip to get the caller.
logger.SetCallerFrame(true, 3)
// Change the default timestamp format.
logger.SetTimestampFormat(time.RFC3339Nano)

// Log the error and set exit code as 1.
logger.Fatal("goodbye world")
}
Expand Down
11 changes: 11 additions & 0 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,17 @@ func BenchmarkOneField(b *testing.B) {
})
}

func BenchmarkOneFieldWithDefaultFields(b *testing.B) {
logger := logf.New(logf.Opts{Writer: io.Discard, DefaultFields: []any{"component", "logf"}})
b.ReportAllocs()
b.ResetTimer()
b.RunParallel(func(p *testing.PB) {
for p.Next() {
logger.Info("hello world", "stack", "testing")
}
})
}

func BenchmarkThreeFields(b *testing.B) {
logger := logf.New(logf.Opts{Writer: io.Discard})
b.ReportAllocs()
Expand Down
1 change: 1 addition & 0 deletions examples/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ func main() {
CallerSkipFrameCount: 3,
EnableCaller: true,
TimestampFormat: time.RFC3339Nano,
DefaultFields: []any{"scope", "example"},
})

// Basic logs.
Expand Down
33 changes: 27 additions & 6 deletions log.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ type Opts struct {
EnableColor bool
EnableCaller bool
CallerSkipFrameCount int

// These fields will be printed with every log.
DefaultFields []any
}

// Logger is the interface for all log operations
Expand Down Expand Up @@ -180,19 +183,37 @@ func (l Logger) handleLog(msg string, lvl Level, fields ...any) {
// Format the line as logfmt.
var (
// count is find out if this is the last key in while itering fields.
count int
key string
val any
count int
fieldCount = len(l.DefaultFields) + len(fields)
key string
val any
)

// If there are odd number of fields, ignore the last.
if len(fields)%2 != 0 {
fields = fields[0 : len(fields)-1]
if fieldCount%2 != 0 {
fields = fields[0 : fieldCount-1]
}

for i := range l.DefaultFields {
space := false
if count != fieldCount-1 {
space = true
}

if i%2 == 0 {
key = l.DefaultFields[i].(string)
continue
} else {
val = l.DefaultFields[i]
}

writeToBuf(buf, key, val, lvl, l.Opts.EnableColor, space)
count++
}

for i := range fields {
space := false
if count != len(fields)-1 {
if count != fieldCount-1 {
space = true
}

Expand Down
13 changes: 13 additions & 0 deletions log_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,19 @@ func TestLogFormat(t *testing.T) {
buf.Reset()
}

func TestLogFormatWithDefaultFields(t *testing.T) {
buf := &bytes.Buffer{}
l := New(Opts{Writer: buf, DefaultFields: []any{"defaultkey", "defaultvalue"}})

l.Info("hello world")
assert.Contains(t, buf.String(), `level=info message="hello world" defaultkey=defaultvalue`)
buf.Reset()

l.Info("hello world", "component", "logf")
assert.Contains(t, buf.String(), `level=info message="hello world" defaultkey=defaultvalue component=logf`)
buf.Reset()
}

func TestOddNumberedFields(t *testing.T) {
buf := &bytes.Buffer{}
l := New(Opts{Writer: buf})
Expand Down

0 comments on commit 6a1a75c

Please sign in to comment.