Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix log stdlibadapter when prefixed #1036

Merged
merged 4 commits into from Nov 25, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 33 additions & 3 deletions log/stdlib.go
@@ -1,6 +1,7 @@
package log

import (
"bytes"
"io"
"log"
"regexp"
Expand All @@ -26,9 +27,11 @@ func (w StdlibWriter) Write(p []byte) (int, error) {
// messages, and place them under relevant keys.
type StdlibAdapter struct {
Logger
timestampKey string
fileKey string
messageKey string
peterbourgon marked this conversation as resolved.
Show resolved Hide resolved
timestampKey string
fileKey string
messageKey string
prefix string
joinPrefixToMsg bool
}

// StdlibAdapterOption sets a parameter for the StdlibAdapter.
Expand All @@ -49,6 +52,11 @@ func MessageKey(key string) StdlibAdapterOption {
return func(a *StdlibAdapter) { a.messageKey = key }
}

// Prefix sets value of the prefix for the actual log message. By default, there's no prefix.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does setting the prefix do?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It allows client code to use the adapter for stdlib logger which is set by the prefix. There is an example in the issue.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add some more detail to the doc comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure. done

func Prefix(prefix string, joinPrefixToMsg bool) StdlibAdapterOption {
return func(a *StdlibAdapter) { a.prefix = prefix; a.joinPrefixToMsg = joinPrefixToMsg }
}

// NewStdlibAdapter returns a new StdlibAdapter wrapper around the passed
// logger. It's designed to be passed to log.SetOutput.
func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer {
Expand All @@ -65,6 +73,8 @@ func NewStdlibAdapter(logger Logger, options ...StdlibAdapterOption) io.Writer {
}

func (a StdlibAdapter) Write(p []byte) (int, error) {
p = a.handlePrefix(p)

result := subexps(p)
keyvals := []interface{}{}
var timestamp string
Expand All @@ -84,6 +94,7 @@ func (a StdlibAdapter) Write(p []byte) (int, error) {
keyvals = append(keyvals, a.fileKey, file)
}
if msg, ok := result["msg"]; ok {
msg = a.handleMessagePrefix(msg)
keyvals = append(keyvals, a.messageKey, msg)
}
if err := a.Logger.Log(keyvals...); err != nil {
Expand All @@ -92,6 +103,25 @@ func (a StdlibAdapter) Write(p []byte) (int, error) {
return len(p), nil
}

func (a StdlibAdapter) handlePrefix(p []byte) []byte {
if a.prefix != "" {
p = bytes.TrimPrefix(p, []byte(a.prefix))
}
return p
}

func (a StdlibAdapter) handleMessagePrefix(msg string) string {
if a.prefix == "" {
return msg
}

msg = strings.TrimPrefix(msg, a.prefix)
if a.joinPrefixToMsg {
msg = a.prefix + msg
}
return msg
}

const (
logRegexpDate = `(?P<date>[0-9]{4}/[0-9]{2}/[0-9]{2})?[ ]?`
logRegexpTime = `(?P<time>[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?)?[ ]?`
Expand Down
50 changes: 50 additions & 0 deletions log/stdlib_test.go
Expand Up @@ -72,6 +72,56 @@ func TestStdLibAdapterExtraction(t *testing.T) {
}
peterbourgon marked this conversation as resolved.
Show resolved Hide resolved
}

func TestStdLibAdapterPrefixedExtraction(t *testing.T) {
buf := &bytes.Buffer{}
logger := NewLogfmtLogger(buf)
writer := NewStdlibAdapter(logger, Prefix("some prefix ", false))
for input, want := range map[string]string{
"some prefix hello": "msg=hello\n",
"some prefix 2009/01/23: hello": "ts=2009/01/23 msg=hello\n",
"some prefix 2009/01/23 01:23:23: hello": "ts=\"2009/01/23 01:23:23\" msg=hello\n",
"some prefix 01:23:23: hello": "ts=01:23:23 msg=hello\n",
"some prefix 2009/01/23 01:23:23.123123: hello": "ts=\"2009/01/23 01:23:23.123123\" msg=hello\n",
"some prefix 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: hello": "ts=\"2009/01/23 01:23:23.123123\" caller=/a/b/c/d.go:23 msg=hello\n",
"some prefix 01:23:23.123123 /a/b/c/d.go:23: hello": "ts=01:23:23.123123 caller=/a/b/c/d.go:23 msg=hello\n",
"some prefix 2009/01/23 01:23:23 /a/b/c/d.go:23: hello": "ts=\"2009/01/23 01:23:23\" caller=/a/b/c/d.go:23 msg=hello\n",
"some prefix 2009/01/23 /a/b/c/d.go:23: hello": "ts=2009/01/23 caller=/a/b/c/d.go:23 msg=hello\n",
"some prefix /a/b/c/d.go:23: hello": "caller=/a/b/c/d.go:23 msg=hello\n",
"/a/b/c/d.go:23: some prefix hello": "caller=/a/b/c/d.go:23 msg=hello\n",
} {
buf.Reset()
fmt.Fprint(writer, input)
if have := buf.String(); want != have {
t.Errorf("%q: want %#v, have %#v", input, want, have)
}
}
}

func TestStdLibAdapterPrefixedExtractionWithJoinToMessage(t *testing.T) {
buf := &bytes.Buffer{}
logger := NewLogfmtLogger(buf)
writer := NewStdlibAdapter(logger, Prefix("some prefix ", true))
for input, want := range map[string]string{
"some prefix hello": "msg=\"some prefix hello\"\n",
"some prefix 2009/01/23: hello": "ts=2009/01/23 msg=\"some prefix hello\"\n",
"some prefix 2009/01/23 01:23:23: hello": "ts=\"2009/01/23 01:23:23\" msg=\"some prefix hello\"\n",
"some prefix 01:23:23: hello": "ts=01:23:23 msg=\"some prefix hello\"\n",
"some prefix 2009/01/23 01:23:23.123123: hello": "ts=\"2009/01/23 01:23:23.123123\" msg=\"some prefix hello\"\n",
"some prefix 2009/01/23 01:23:23.123123 /a/b/c/d.go:23: hello": "ts=\"2009/01/23 01:23:23.123123\" caller=/a/b/c/d.go:23 msg=\"some prefix hello\"\n",
"some prefix 01:23:23.123123 /a/b/c/d.go:23: hello": "ts=01:23:23.123123 caller=/a/b/c/d.go:23 msg=\"some prefix hello\"\n",
"some prefix 2009/01/23 01:23:23 /a/b/c/d.go:23: hello": "ts=\"2009/01/23 01:23:23\" caller=/a/b/c/d.go:23 msg=\"some prefix hello\"\n",
"some prefix 2009/01/23 /a/b/c/d.go:23: hello": "ts=2009/01/23 caller=/a/b/c/d.go:23 msg=\"some prefix hello\"\n",
"some prefix /a/b/c/d.go:23: hello": "caller=/a/b/c/d.go:23 msg=\"some prefix hello\"\n",
"/a/b/c/d.go:23: some prefix hello": "caller=/a/b/c/d.go:23 msg=\"some prefix hello\"\n",
} {
buf.Reset()
fmt.Fprint(writer, input)
if have := buf.String(); want != have {
t.Errorf("%q: want %#v, have %#v", input, want, have)
}
}
}

func TestStdlibAdapterSubexps(t *testing.T) {
for input, wantMap := range map[string]map[string]string{
"hello world": {
Expand Down