Make logging more efficient
This commit is contained in:
parent
d44a11325d
commit
2f0fdf1252
5 changed files with 168 additions and 60 deletions
116
log/log_test.go
116
log/log_test.go
|
@ -1,9 +1,8 @@
|
|||
package log_test
|
||||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"github.com/stretchr/testify/require"
|
||||
"heckel.io/ntfy/log"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -12,7 +11,7 @@ import (
|
|||
func TestMain(m *testing.M) {
|
||||
exitCode := m.Run()
|
||||
resetState()
|
||||
log.SetLevel(log.ErrorLevel) // For other modules!
|
||||
SetLevel(ErrorLevel) // For other modules!
|
||||
os.Exit(exitCode)
|
||||
}
|
||||
|
||||
|
@ -27,22 +26,21 @@ func TestLog_TagContextFieldFields(t *testing.T) {
|
|||
Message: "some error",
|
||||
}
|
||||
var out bytes.Buffer
|
||||
log.SetOutput(&out)
|
||||
log.SetFormat(log.JSONFormat)
|
||||
log.SetLevelOverride("tag", "stripe", log.DebugLevel)
|
||||
SetOutput(&out)
|
||||
SetFormat(JSONFormat)
|
||||
SetLevelOverride("tag", "stripe", DebugLevel)
|
||||
|
||||
log.
|
||||
Tag("mytag").
|
||||
Tag("mytag").
|
||||
Field("field2", 123).
|
||||
Field("field1", "value1").
|
||||
Time(time.Unix(123, 999000000).UTC()).
|
||||
Info("hi there %s", "phil")
|
||||
log.
|
||||
Tag("not-stripe").
|
||||
|
||||
Tag("not-stripe").
|
||||
Debug("this message will not appear")
|
||||
log.
|
||||
With(v).
|
||||
Fields(log.Context{
|
||||
|
||||
With(v).
|
||||
Fields(Context{
|
||||
"stripe_customer_id": "acct_123",
|
||||
"stripe_subscription_id": "sub_123",
|
||||
}).
|
||||
|
@ -57,6 +55,76 @@ func TestLog_TagContextFieldFields(t *testing.T) {
|
|||
require.Equal(t, expected, out.String())
|
||||
}
|
||||
|
||||
func TestLog_NoAllocIfNotPrinted(t *testing.T) {
|
||||
t.Cleanup(resetState)
|
||||
v := &fakeVisitor{
|
||||
UserID: "u_abc",
|
||||
IP: "1.2.3.4",
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
SetOutput(&out)
|
||||
SetFormat(JSONFormat)
|
||||
|
||||
// Do not log, do not call contexters (because global level is INFO)
|
||||
v.contextCalled = false
|
||||
ev := With(v)
|
||||
ev.Debug("some message")
|
||||
require.False(t, v.contextCalled)
|
||||
require.Equal(t, "", ev.Timestamp)
|
||||
require.Equal(t, Level(0), ev.Level)
|
||||
require.Equal(t, "", ev.Message)
|
||||
require.Nil(t, ev.fields)
|
||||
|
||||
// Logged because info level, contexters called
|
||||
v.contextCalled = false
|
||||
ev = With(v).Time(time.Unix(1111, 0).UTC())
|
||||
ev.Info("some message")
|
||||
require.True(t, v.contextCalled)
|
||||
require.NotNil(t, ev.fields)
|
||||
require.Equal(t, "1.2.3.4", ev.fields["visitor_ip"])
|
||||
|
||||
// Not logged, but contexters called, because overrides exist
|
||||
SetLevel(DebugLevel)
|
||||
SetLevelOverride("tag", "overridetag", TraceLevel)
|
||||
v.contextCalled = false
|
||||
ev = Tag("sometag").Field("field", "value").With(v).Time(time.Unix(123, 0).UTC())
|
||||
ev.Trace("some debug message")
|
||||
require.True(t, v.contextCalled) // If there are overrides, we must call the context to determine the filter fields
|
||||
require.Equal(t, "", ev.Timestamp)
|
||||
require.Equal(t, Level(0), ev.Level)
|
||||
require.Equal(t, "", ev.Message)
|
||||
require.Equal(t, 4, len(ev.fields))
|
||||
require.Equal(t, "value", ev.fields["field"])
|
||||
require.Equal(t, "sometag", ev.fields["tag"])
|
||||
|
||||
// Logged because of override tag, and contexters called
|
||||
v.contextCalled = false
|
||||
ev = Tag("overridetag").Field("field", "value").With(v).Time(time.Unix(123, 0).UTC())
|
||||
ev.Trace("some trace message")
|
||||
require.True(t, v.contextCalled)
|
||||
require.Equal(t, "1970-01-01T00:02:03Z", ev.Timestamp)
|
||||
require.Equal(t, TraceLevel, ev.Level)
|
||||
require.Equal(t, "some trace message", ev.Message)
|
||||
|
||||
// Logged because of field override, and contexters called
|
||||
ResetLevelOverrides()
|
||||
SetLevelOverride("visitor_ip", "1.2.3.4", TraceLevel)
|
||||
v.contextCalled = false
|
||||
ev = With(v).Time(time.Unix(124, 0).UTC())
|
||||
ev.Trace("some trace message with override")
|
||||
require.True(t, v.contextCalled)
|
||||
require.Equal(t, "1970-01-01T00:02:04Z", ev.Timestamp)
|
||||
require.Equal(t, TraceLevel, ev.Level)
|
||||
require.Equal(t, "some trace message with override", ev.Message)
|
||||
|
||||
expected := `{"time":"1970-01-01T00:18:31Z","level":"INFO","message":"some message","user_id":"u_abc","visitor_ip":"1.2.3.4"}
|
||||
{"time":"1970-01-01T00:02:03Z","level":"TRACE","message":"some trace message","field":"value","tag":"overridetag","user_id":"u_abc","visitor_ip":"1.2.3.4"}
|
||||
{"time":"1970-01-01T00:02:04Z","level":"TRACE","message":"some trace message with override","user_id":"u_abc","visitor_ip":"1.2.3.4"}
|
||||
`
|
||||
require.Equal(t, expected, out.String())
|
||||
}
|
||||
|
||||
type fakeError struct {
|
||||
Code int
|
||||
Message string
|
||||
|
@ -66,28 +134,30 @@ func (e fakeError) Error() string {
|
|||
return e.Message
|
||||
}
|
||||
|
||||
func (e fakeError) Context() log.Context {
|
||||
return log.Context{
|
||||
func (e fakeError) Context() Context {
|
||||
return Context{
|
||||
"error": e.Message,
|
||||
"error_code": e.Code,
|
||||
}
|
||||
}
|
||||
|
||||
type fakeVisitor struct {
|
||||
UserID string
|
||||
IP string
|
||||
UserID string
|
||||
IP string
|
||||
contextCalled bool
|
||||
}
|
||||
|
||||
func (v *fakeVisitor) Context() log.Context {
|
||||
return log.Context{
|
||||
func (v *fakeVisitor) Context() Context {
|
||||
v.contextCalled = true
|
||||
return Context{
|
||||
"user_id": v.UserID,
|
||||
"visitor_ip": v.IP,
|
||||
}
|
||||
}
|
||||
|
||||
func resetState() {
|
||||
log.SetLevel(log.DefaultLevel)
|
||||
log.SetFormat(log.DefaultFormat)
|
||||
log.SetOutput(log.DefaultOutput)
|
||||
log.ResetLevelOverrides()
|
||||
SetLevel(DefaultLevel)
|
||||
SetFormat(DefaultFormat)
|
||||
SetOutput(DefaultOutput)
|
||||
ResetLevelOverrides()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue