Skip to content

Commit

Permalink
Merge remote-tracking branch 'rs/master' into daver/merge-remote
Browse files Browse the repository at this point in the history
  • Loading branch information
autarch committed Jan 25, 2024
2 parents 22af876 + 417580d commit 6b21701
Show file tree
Hide file tree
Showing 26 changed files with 765 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
with:
go-version: ${{ matrix.go-version }}
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: actions/cache@v3
with:
path: ~/go/pkg/mod
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Zero Allocation JSON Logger

[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://travis-ci.org/rs/zerolog.svg?branch=master)](https://travis-ci.org/rs/zerolog) [![Go Coverage](https://github.com/rs/zerolog/wiki/coverage.svg)](https://raw.githack.com/wiki/rs/zerolog/coverage.html)
[![godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/rs/zerolog) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/rs/zerolog/master/LICENSE) [![Build Status](https://github.com/rs/zerolog/actions/workflows/test.yml/badge.svg)](https://github.com/rs/zerolog/actions/workflows/test.yml) [![Go Coverage](https://github.com/rs/zerolog/wiki/coverage.svg)](https://raw.githack.com/wiki/rs/zerolog/coverage.html)

The zerolog package provides a fast and simple logger dedicated to JSON output.

Expand Down Expand Up @@ -547,7 +547,7 @@ and facilitates the unification of logging and tracing in some systems:
type TracingHook struct{}

func (h TracingHook) Run(e *zerolog.Event, level zerolog.Level, msg string) {
ctx := e.Ctx()
ctx := e.GetCtx()
spanId := getSpanIdFromContext(ctx) // as per your tracing framework
e.Str("span-id", spanId)
}
Expand Down
20 changes: 10 additions & 10 deletions benchmark_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package zerolog
import (
"context"
"errors"
"io/ioutil"
"io"
"net"
"testing"
"time"
Expand All @@ -15,7 +15,7 @@ var (
)

func BenchmarkLogEmpty(b *testing.B) {
logger := New(ioutil.Discard)
logger := New(io.Discard)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Expand All @@ -25,7 +25,7 @@ func BenchmarkLogEmpty(b *testing.B) {
}

func BenchmarkDisabled(b *testing.B) {
logger := New(ioutil.Discard).Level(Disabled)
logger := New(io.Discard).Level(Disabled)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Expand All @@ -35,7 +35,7 @@ func BenchmarkDisabled(b *testing.B) {
}

func BenchmarkInfo(b *testing.B) {
logger := New(ioutil.Discard)
logger := New(io.Discard)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Expand All @@ -45,7 +45,7 @@ func BenchmarkInfo(b *testing.B) {
}

func BenchmarkContextFields(b *testing.B) {
logger := New(ioutil.Discard).With().
logger := New(io.Discard).With().
Str("string", "four!").
Time("time", time.Time{}).
Int("int", 123).
Expand All @@ -60,7 +60,7 @@ func BenchmarkContextFields(b *testing.B) {
}

func BenchmarkContextAppend(b *testing.B) {
logger := New(ioutil.Discard).With().
logger := New(io.Discard).With().
Str("foo", "bar").
Logger()
b.ResetTimer()
Expand All @@ -72,7 +72,7 @@ func BenchmarkContextAppend(b *testing.B) {
}

func BenchmarkLogFields(b *testing.B) {
logger := New(ioutil.Discard)
logger := New(io.Discard)
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Expand Down Expand Up @@ -102,7 +102,7 @@ func BenchmarkLogArrayObject(b *testing.B) {
obj1 := obj{"a", "b", 2}
obj2 := obj{"c", "d", 3}
obj3 := obj{"e", "f", 4}
logger := New(ioutil.Discard)
logger := New(io.Discard)
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
Expand Down Expand Up @@ -224,7 +224,7 @@ func BenchmarkLogFieldType(b *testing.B) {
return e.Object("k", objects[0])
},
}
logger := New(ioutil.Discard)
logger := New(io.Discard)
b.ResetTimer()
for name := range types {
f := types[name]
Expand Down Expand Up @@ -358,7 +358,7 @@ func BenchmarkContextFieldType(b *testing.B) {
return c.Timestamp()
},
}
logger := New(ioutil.Discard)
logger := New(io.Discard)
b.ResetTimer()
for name := range types {
f := types[name]
Expand Down
1 change: 0 additions & 1 deletion binary_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"

// "io/ioutil"
stdlog "log"
"time"
)
Expand Down
40 changes: 34 additions & 6 deletions cmd/prettylog/prettylog.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package main

import (
"bufio"
"errors"
"fmt"
"io"
"os"
Expand All @@ -14,13 +16,39 @@ func isInputFromPipe() bool {
}

func main() {
if !isInputFromPipe() {
fmt.Println("The command is intended to work with pipes.")
fmt.Println("Usage: app_with_zerolog | 2> >(prettylog)")
writer := zerolog.NewConsoleWriter()

if isInputFromPipe() {
_, _ = io.Copy(writer, os.Stdin)
} else if len(os.Args) > 1 {
for _, filename := range os.Args[1:] {
// Scan each line from filename and write it into writer
r, err := os.Open(filename)
if err != nil {
fmt.Printf("%s open: %v", filename, err)
os.Exit(1)
}
scanner := bufio.NewScanner(r)
for scanner.Scan() {
_, err = writer.Write(scanner.Bytes())
if err != nil {
if errors.Is(err, io.EOF) {
break
}
fmt.Printf("%s write: %v", filename, err)
os.Exit(1)
}
}
if err := scanner.Err(); err != nil {
fmt.Printf("%s scan: %v", filename, err)
os.Exit(1)
}
}
} else {
fmt.Println("Usage:")
fmt.Println(" app_with_zerolog | 2> >(prettylog)")
fmt.Println(" prettylog zerolog_output.jsonl")
os.Exit(1)
return
}

writer := zerolog.NewConsoleWriter()
_, _ = io.Copy(writer, os.Stdin)
}
60 changes: 35 additions & 25 deletions console.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ type ConsoleWriter struct {
FormatErrFieldValue Formatter

FormatExtra func(map[string]interface{}, *bytes.Buffer) error

FormatPrepare func(map[string]interface{}) error
}

// NewConsoleWriter creates and initializes a new ConsoleWriter.
Expand Down Expand Up @@ -124,6 +126,13 @@ func (w ConsoleWriter) Write(p []byte) (n int, err error) {
return n, fmt.Errorf("cannot decode event: %s", err)
}

if w.FormatPrepare != nil {
err = w.FormatPrepare(evt)
if err != nil {
return n, err
}
}

for _, p := range w.PartsOrder {
w.writePart(buf, evt, p)
}
Expand Down Expand Up @@ -272,7 +281,7 @@ func (w ConsoleWriter) writePart(buf *bytes.Buffer, evt map[string]interface{},
}
case MessageFieldName:
if w.FormatMessage == nil {
f = consoleDefaultFormatMessage
f = consoleDefaultFormatMessage(w.NoColor, evt[LevelFieldName])
} else {
f = w.FormatMessage
}
Expand Down Expand Up @@ -310,8 +319,13 @@ func needsQuote(s string) bool {
return false
}

// colorize returns the string s wrapped in ANSI code c, unless disabled is true.
// colorize returns the string s wrapped in ANSI code c, unless disabled is true or c is 0.
func colorize(s interface{}, c int, disabled bool) string {
e := os.Getenv("NO_COLOR")
if e != "" || c == 0 {
disabled = true
}

if disabled {
return fmt.Sprintf("%s", s)
}
Expand Down Expand Up @@ -373,27 +387,16 @@ func consoleDefaultFormatLevel(noColor bool) Formatter {
return func(i interface{}) string {
var l string
if ll, ok := i.(string); ok {
switch ll {
case LevelTraceValue:
l = colorize("TRC", colorMagenta, noColor)
case LevelDebugValue:
l = colorize("DBG", colorYellow, noColor)
case LevelInfoValue:
l = colorize("INF", colorGreen, noColor)
case LevelWarnValue:
l = colorize("WRN", colorRed, noColor)
case LevelErrorValue:
l = colorize(colorize("ERR", colorRed, noColor), colorBold, noColor)
case LevelFatalValue:
l = colorize(colorize("FTL", colorRed, noColor), colorBold, noColor)
case LevelPanicValue:
l = colorize(colorize("PNC", colorRed, noColor), colorBold, noColor)
default:
l = colorize(ll, colorBold, noColor)
level, _ := ParseLevel(ll)
fl, ok := FormattedLevels[level]
if ok {
l = colorize(fl, LevelColors[level], noColor)
} else {
l = strings.ToUpper(ll)[0:3]
}
} else {
if i == nil {
l = colorize("???", colorBold, noColor)
l = "???"
} else {
l = strings.ToUpper(fmt.Sprintf("%s", i))[0:3]
}
Expand All @@ -420,11 +423,18 @@ func consoleDefaultFormatCaller(noColor bool) Formatter {
}
}

func consoleDefaultFormatMessage(i interface{}) string {
if i == nil {
return ""
func consoleDefaultFormatMessage(noColor bool, level interface{}) Formatter {
return func(i interface{}) string {
if i == nil || i == "" {
return ""
}
switch level {
case LevelInfoValue, LevelWarnValue, LevelErrorValue, LevelFatalValue, LevelPanicValue:
return colorize(fmt.Sprintf("%s", i), colorBold, noColor)
default:
return fmt.Sprintf("%s", i)
}
}
return fmt.Sprintf("%s", i)
}

func consoleDefaultFormatFieldName(noColor bool) Formatter {
Expand All @@ -445,6 +455,6 @@ func consoleDefaultFormatErrFieldName(noColor bool) Formatter {

func consoleDefaultFormatErrFieldValue(noColor bool) Formatter {
return func(i interface{}) string {
return colorize(fmt.Sprintf("%s", i), colorRed, noColor)
return colorize(colorize(fmt.Sprintf("%s", i), colorBold, noColor), colorRed, noColor)
}
}
50 changes: 46 additions & 4 deletions console_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package zerolog_test
import (
"bytes"
"fmt"
"io/ioutil"
"io"
"os"
"strings"
"testing"
Expand Down Expand Up @@ -97,13 +97,32 @@ func TestConsoleWriter(t *testing.T) {
t.Errorf("Unexpected error when writing output: %s", err)
}

expectedOutput := "\x1b[90m<nil>\x1b[0m \x1b[31mWRN\x1b[0m Foobar\n"
expectedOutput := "\x1b[90m<nil>\x1b[0m \x1b[33mWRN\x1b[0m \x1b[1mFoobar\x1b[0m\n"
actualOutput := buf.String()
if actualOutput != expectedOutput {
t.Errorf("Unexpected output %q, want: %q", actualOutput, expectedOutput)
}
})

t.Run("NO_COLOR = true", func(t *testing.T) {
os.Setenv("NO_COLOR", "anything")

buf := &bytes.Buffer{}
w := zerolog.ConsoleWriter{Out: buf}

_, err := w.Write([]byte(`{"level": "warn", "message": "Foobar"}`))
if err != nil {
t.Errorf("Unexpected error when writing output: %s", err)
}

expectedOutput := "<nil> WRN Foobar\n"
actualOutput := buf.String()
if actualOutput != expectedOutput {
t.Errorf("Unexpected output %q, want: %q", actualOutput, expectedOutput)
}
os.Unsetenv("NO_COLOR")
})

t.Run("Write fields", func(t *testing.T) {
buf := &bytes.Buffer{}
w := zerolog.ConsoleWriter{Out: buf, NoColor: true}
Expand Down Expand Up @@ -229,7 +248,7 @@ func TestConsoleWriter(t *testing.T) {
t.Errorf("Unexpected error when writing output: %s", err)
}

expectedOutput := "\x1b[90m<nil>\x1b[0m \x1b[31mWRN\x1b[0m Foobar \x1b[36mfoo=\x1b[0mbar\n"
expectedOutput := "\x1b[90m<nil>\x1b[0m \x1b[33mWRN\x1b[0m \x1b[1mFoobar\x1b[0m \x1b[36mfoo=\x1b[0mbar\n"
actualOutput := buf.String()
if actualOutput != expectedOutput {
t.Errorf("Unexpected output %q, want: %q", actualOutput, expectedOutput)
Expand Down Expand Up @@ -399,6 +418,29 @@ func TestConsoleWriterConfiguration(t *testing.T) {
}
})

t.Run("Sets FormatPrepare", func(t *testing.T) {
buf := &bytes.Buffer{}
w := zerolog.ConsoleWriter{
Out: buf, NoColor: true, PartsOrder: []string{"level", "message"},
FormatPrepare: func(evt map[string]interface{}) error {
evt["message"] = fmt.Sprintf("msg=%s", evt["message"])
return nil
},
}

evt := `{"level": "info", "message": "Foobar"}`
_, err := w.Write([]byte(evt))
if err != nil {
t.Errorf("Unexpected error when writing output: %s", err)
}

expectedOutput := "INF msg=Foobar\n"
actualOutput := buf.String()
if actualOutput != expectedOutput {
t.Errorf("Unexpected output %q, want: %q", actualOutput, expectedOutput)
}
})

t.Run("Uses local time for console writer without time zone", func(t *testing.T) {
// Regression test for issue #483 (check there for more details)

Expand Down Expand Up @@ -432,7 +474,7 @@ func BenchmarkConsoleWriter(b *testing.B) {

var msg = []byte(`{"level": "info", "foo": "bar", "message": "HELLO", "time": "1990-01-01"}`)

w := zerolog.ConsoleWriter{Out: ioutil.Discard, NoColor: false}
w := zerolog.ConsoleWriter{Out: io.Discard, NoColor: false}

for i := 0; i < b.N; i++ {
w.Write(msg)
Expand Down
Loading

0 comments on commit 6b21701

Please sign in to comment.