Skip to content

Commit

Permalink
fix: don't race poking logger variable, just make events from it
Browse files Browse the repository at this point in the history
fixes: #68
  • Loading branch information
mgabeler-lee-6rs committed Dec 7, 2023
1 parent 7cff53e commit 86361e8
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 18 deletions.
30 changes: 12 additions & 18 deletions logger.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,34 +104,28 @@ func SetLogger(opts ...Option) gin.HandlerFunc {
}
latency := end.Sub(start)

l = l.With().
Int("status", c.Writer.Status()).
Str("method", c.Request.Method).
Str("path", path).
Str("ip", c.ClientIP()).
Dur("latency", latency).
Str("user_agent", c.Request.UserAgent()).Logger()

msg := "Request"
if len(c.Errors) > 0 {
msg = c.Errors.String()
}

var evt *zerolog.Event
switch {
case c.Writer.Status() >= http.StatusBadRequest && c.Writer.Status() < http.StatusInternalServerError:
{
l.WithLevel(cfg.clientErrorLevel).
Msg(msg)
}
evt = l.WithLevel(cfg.clientErrorLevel)
case c.Writer.Status() >= http.StatusInternalServerError:
{
l.WithLevel(cfg.serverErrorLevel).
Msg(msg)
}
evt = l.WithLevel(cfg.serverErrorLevel)
default:
l.WithLevel(cfg.defaultLevel).
Msg(msg)
evt = l.WithLevel(cfg.defaultLevel)
}
evt.
Int("status", c.Writer.Status()).
Str("method", c.Request.Method).
Str("path", path).
Str("ip", c.ClientIP()).
Dur("latency", latency).
Str("user_agent", c.Request.UserAgent()).
Msg(msg)
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions logger_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package logger
import (
"bytes"
"context"
"fmt"
"net/http"
"net/http/httptest"
"regexp"
"strings"
"sync"
"testing"

"github.com/gin-gonic/gin"
Expand Down Expand Up @@ -151,6 +154,41 @@ func TestLoggerWithLevels(t *testing.T) {
assert.Contains(t, buffer.String(), "FTL")
}

func TestCustomLoggerIssue68(t *testing.T) {
buffer := new(bytes.Buffer)
gin.SetMode(gin.ReleaseMode)
r := gin.New()
l := zerolog.New(buffer)
r.Use(SetLogger(
WithLogger(func(*gin.Context, zerolog.Logger) zerolog.Logger { return l }),
WithDefaultLevel(zerolog.DebugLevel),
WithClientErrorLevel(zerolog.ErrorLevel),
WithServerErrorLevel(zerolog.FatalLevel),
))
r.GET("/example", func(c *gin.Context) {})

// concurrent requests should only have their info logged once
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
req := fmt.Sprintf("/example?a=%d", i)
go func() {
defer wg.Done()
performRequest(r, "GET", req)
}()
}
wg.Wait()

bs := buffer.String()
for i := 0; i < 10; i++ {
// should contain each request log exactly once
msg := fmt.Sprintf("/example?a=%d", i)
if assert.Contains(t, bs, msg) {
assert.Equal(t, strings.Index(bs, msg), strings.LastIndex(bs, msg))
}
}
}

func TestLoggerParseLevel(t *testing.T) {
type args struct {
levelStr string
Expand Down

0 comments on commit 86361e8

Please sign in to comment.