-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
New API for package log (post-GopherCon) #76
Merged
Merged
Changes from 1 commit
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
3afb956
log: first cut of new API, incomplete
peterbourgon d3c703c
Rename withLogger to Context and export With method.
ChrisHines f2a9e2f
Add Context example.
ChrisHines 651b069
Rename log.With to log.NewContext and remove keyvals vargs.
ChrisHines 9043375
Fix spelling in comment.
ChrisHines 8a32db2
Move leveled logging into its own package and update API to improve c…
ChrisHines 9044c97
log/levels: clean up some comments and var names
peterbourgon 38ea61a
log2: rm
peterbourgon 8899b82
log: fix some comments
peterbourgon 803da74
Combine config and Levels structs.
ChrisHines a50819e
Document implementation tradeoff and reason for choosing to favor a c…
ChrisHines File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package log_test | ||
|
||
import ( | ||
"io/ioutil" | ||
"testing" | ||
|
||
"github.com/go-kit/kit/log2" | ||
) | ||
|
||
func BenchmarkContextNoMessage(b *testing.B) { | ||
logger := log.NewLogfmtLogger(ioutil.Discard) | ||
ctx := log.NewContext(logger, "module", "benchmark") | ||
for i := 0; i < b.N; i++ { | ||
ctx.Log() | ||
} | ||
} | ||
|
||
func BenchmarkContextOneMessage(b *testing.B) { | ||
logger := log.NewLogfmtLogger(ioutil.Discard) | ||
ctx := log.NewContext(logger, "module", "benchmark") | ||
for i := 0; i < b.N; i++ { | ||
ctx.Log("msg", "hello") | ||
} | ||
} | ||
|
||
func BenchmarkContextWith(b *testing.B) { | ||
logger := log.NewLogfmtLogger(ioutil.Discard) | ||
ctx := log.NewContext(logger, "module", "benchmark") | ||
for i := 0; i < b.N; i++ { | ||
ctx.With("subcontext", 123).Log("msg", "goodbye") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
package log_test | ||
|
||
import ( | ||
"os" | ||
|
||
"github.com/go-kit/kit/log2" | ||
) | ||
|
||
func ExampleContext() { | ||
logger := log.NewLogfmtLogger(os.Stdout) | ||
logger.Log("foo", 123) | ||
ctx := log.NewContext(logger, "level", "info") | ||
ctx.Log() | ||
ctx = ctx.With("msg", "hello") | ||
ctx.Log() | ||
ctx.With("a", 1).Log("b", 2) | ||
|
||
// Output: | ||
// foo=123 | ||
// level=info | ||
// level=info msg=hello | ||
// level=info msg=hello a=1 b=2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
package log | ||
|
||
type Levels interface { | ||
With(...interface{}) Levels | ||
Debug(...interface{}) error | ||
Info(...interface{}) error | ||
Warn(...interface{}) error | ||
Error(...interface{}) error | ||
Crit(...interface{}) error | ||
} | ||
|
||
func NewLevels(logger Logger, keyvals ...interface{}) Levels { | ||
return levels(NewContext(logger, keyvals...)) | ||
} | ||
|
||
type levels Context | ||
|
||
func (l levels) With(keyvals ...interface{}) Levels { | ||
return levels(Context(l).With(keyvals...)) | ||
} | ||
|
||
func (l levels) Debug(keyvals ...interface{}) error { | ||
return NewContext(l.logger).With("level", "debug").With(l.keyvals...).Log(keyvals...) | ||
} | ||
|
||
func (l levels) Info(keyvals ...interface{}) error { | ||
return NewContext(l.logger).With("level", "info").With(l.keyvals...).Log(keyvals...) | ||
} | ||
|
||
func (l levels) Warn(keyvals ...interface{}) error { | ||
return NewContext(l.logger).With("level", "warn").With(l.keyvals...).Log(keyvals...) | ||
} | ||
|
||
func (l levels) Error(keyvals ...interface{}) error { | ||
return NewContext(l.logger).With("level", "error").With(l.keyvals...).Log(keyvals...) | ||
} | ||
|
||
func (l levels) Crit(keyvals ...interface{}) error { | ||
return NewContext(l.logger).With("level", "crit").With(l.keyvals...).Log(keyvals...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package log_test | ||
|
||
import ( | ||
"io/ioutil" | ||
"os" | ||
"testing" | ||
|
||
"github.com/go-kit/kit/log2" | ||
) | ||
|
||
func ExampleLevels() { | ||
logger := log.NewLevels(log.NewLogfmtLogger(os.Stdout)) | ||
logger.Debug("msg", "hello") | ||
logger.With("context", "foo").Warn("err", "error") | ||
// Output: | ||
// level=debug msg=hello | ||
// level=warn context=foo err=error | ||
} | ||
|
||
func BenchmarkLevels(b *testing.B) { | ||
logger := log.NewLevels(log.NewLogfmtLogger(ioutil.Discard)).With("foo", "bar") | ||
for i := 0; i < b.N; i++ { | ||
logger.Debug("key", "val") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package log | ||
|
||
import ( | ||
"io" | ||
|
||
"gopkg.in/logfmt.v0" | ||
) | ||
|
||
type logfmtLogger struct { | ||
w io.Writer | ||
} | ||
|
||
// NewLogfmtLogger returns a logger that encodes keyvals to the Writer in | ||
// logfmt format. The passed Writer must be safe for concurrent use by | ||
// multiple goroutines if the returned Logger will be used concurrently. | ||
func NewLogfmtLogger(w io.Writer) Logger { | ||
return &logfmtLogger{w} | ||
} | ||
|
||
func (l logfmtLogger) Log(keyvals ...interface{}) error { | ||
// The Logger interface requires implementations to be safe for concurrent | ||
// use by multiple goroutines. For this implementation that means making | ||
// only one call to l.w.Write() for each call to Log. We first collect all | ||
// of the bytes into b, and then call l.w.Write(b). | ||
for i := 1; i < len(keyvals); i += 2 { | ||
if valuer, ok := keyvals[i].(Valuer); ok { | ||
keyvals[i] = valuer.Value() | ||
} | ||
} | ||
b, err := logfmt.MarshalKeyvals(keyvals...) | ||
if err != nil { | ||
return err | ||
} | ||
b = append(b, '\n') | ||
if _, err := l.w.Write(b); err != nil { | ||
return err | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package log | ||
|
||
type Logger interface { | ||
Log(keyvals ...interface{}) error | ||
} | ||
|
||
type Context struct { | ||
logger Logger | ||
keyvals []interface{} | ||
} | ||
|
||
func NewContext(logger Logger, keyvals ...interface{}) Context { | ||
if len(keyvals)%2 != 0 { | ||
panic("bad keyvals") | ||
} | ||
return Context{ | ||
logger: logger, | ||
keyvals: keyvals, | ||
} | ||
} | ||
|
||
func (c Context) With(keyvals ...interface{}) Context { | ||
if len(keyvals)%2 != 0 { | ||
panic("bad keyvals") | ||
} | ||
return Context{ | ||
logger: c.logger, | ||
keyvals: append(c.keyvals, keyvals...), | ||
} | ||
} | ||
|
||
func (c Context) Log(keyvals ...interface{}) error { | ||
return c.logger.Log(append(c.keyvals, keyvals...)...) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package log | ||
|
||
import ( | ||
"fmt" | ||
"path/filepath" | ||
"runtime" | ||
) | ||
|
||
type Valuer interface { | ||
Value() interface{} | ||
} | ||
|
||
var Caller = ValuerFunc(func() interface{} { | ||
_, file, line, _ := runtime.Caller(5) | ||
return fmt.Sprintf("%s:%d", filepath.Base(file), line) | ||
}) | ||
|
||
type ValuerFunc func() interface{} | ||
|
||
func (f ValuerFunc) Value() interface{} { return f() } |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is 1 here ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because keyvals contains alternating keys (in even indices) and values (in odd indices). This loop only needs to operate on the values, so it can start at index 1.