-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
NOTE: breaking change as now relying on go-playground/pkg/runtime for stack information previously within go-playground/errors Added default logger. If you register your own logger, of any kind, the default logger is removed and so is backward compatible. It is only registered when attached to a terminal. Added Close methods to handlers to allow resource cleanup & automatic removal of the logger now that RemoveHandler and AddHandler can be made on the fly. Updated to use go-playground/pkg/runtime.StackLevel(...) previously found int go-playground/errors
- Loading branch information
Dean Karn
authored
May 12, 2019
1 parent
fdcdf50
commit d70d76e
Showing
24 changed files
with
983 additions
and
173 deletions.
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,26 @@ | ||
language: go | ||
go: | ||
- 1.12.5 | ||
- tip | ||
matrix: | ||
allow_failures: | ||
- go: tip | ||
|
||
notifications: | ||
email: | ||
recipients: [email protected] | ||
on_success: change | ||
on_failure: always | ||
|
||
before_install: | ||
- go get -u github.com/go-playground/overalls | ||
- go get -u github.com/mattn/goveralls | ||
|
||
script: | ||
- make test | ||
- go vet ./... | ||
|
||
after_success: | | ||
[ $TRAVIS_GO_VERSION = 1.12.5 ] && | ||
overalls -project="github.com/go-playground/log" -covermode=count -ignore=.git,examples -debug && | ||
goveralls -coverprofile=overalls.coverprofile -service travis-ci -repotoken $COVERALLS_TOKEN |
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
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
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,45 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/go-playground/errors" | ||
|
||
"github.com/go-playground/log" | ||
"github.com/go-playground/log/handlers/console" | ||
) | ||
|
||
func main() { | ||
cLog := console.New(true) | ||
log.AddHandler(cLog, log.AllLevels...) | ||
|
||
// Trace | ||
defer log.WithTrace().Info("time to run") | ||
|
||
log.Debug("debug") | ||
log.Info("info") | ||
log.Notice("notice") | ||
log.Warn("warn") | ||
log.Error("error") | ||
// log.Panic("panic") // this will panic | ||
log.Alert("alert") | ||
// log.Fatal("fatal") // this will call os.Exit(1) | ||
|
||
err := errors.New("the is an error") | ||
// logging with fields can be used with any of the above | ||
log.WithError(err).WithFields(log.F("key", "value")).Info("test info") | ||
|
||
// predefined global fields | ||
log.WithDefaultFields(log.Fields{ | ||
{"program", "test"}, | ||
{"version", "0.1.3"}, | ||
}...) | ||
|
||
log.WithField("key", "value").Info("testing default fields") | ||
|
||
// or request scoped default fields | ||
logger := log.WithFields( | ||
log.F("request", "req"), | ||
log.F("scoped", "sco"), | ||
) | ||
|
||
logger.WithField("key", "value").Info("test") | ||
} |
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,17 @@ | ||
package log | ||
|
||
import "sync" | ||
|
||
// BytePool represents a reusable byte pool. It is a centralized global instance for this package and can be accessed by | ||
// calling log.BytePool(). It is intended to be used by Handlers. | ||
type ByteArrayPool struct { | ||
pool *sync.Pool | ||
} | ||
|
||
func (p *ByteArrayPool) Get() []byte { | ||
return p.pool.Get().([]byte) | ||
} | ||
|
||
func (p *ByteArrayPool) Put(b []byte) { | ||
p.pool.Put(b[:0]) | ||
} |
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,147 @@ | ||
package log | ||
|
||
import ( | ||
"bufio" | ||
"fmt" | ||
"io" | ||
stdlog "log" | ||
"os" | ||
"strconv" | ||
|
||
"github.com/go-playground/ansi" | ||
) | ||
|
||
const ( | ||
space = byte(' ') | ||
equals = byte('=') | ||
newLine = byte('\n') | ||
base10 = 10 | ||
v = "%v" | ||
) | ||
|
||
var ( | ||
defaultLoggerWriter io.Writer = os.Stderr // here for tests only | ||
defaultLoggerTimeFormat = "2006-01-02 15:04:05.000000000Z07:00" // here for tests only | ||
) | ||
|
||
// console is an instance of the console logger | ||
type console struct { | ||
colors [8]ansi.EscSeq | ||
writer io.Writer | ||
timestampFormat string | ||
r *io.PipeReader | ||
} | ||
|
||
func newDefaultLogger() *console { | ||
c := &console{ | ||
colors: [...]ansi.EscSeq{ | ||
DebugLevel: ansi.Green, | ||
InfoLevel: ansi.Blue, | ||
NoticeLevel: ansi.LightCyan, | ||
WarnLevel: ansi.LightYellow, | ||
ErrorLevel: ansi.LightRed, | ||
PanicLevel: ansi.Red, | ||
AlertLevel: ansi.Red + ansi.Underline, | ||
FatalLevel: ansi.Red + ansi.Underline + ansi.Blink, | ||
}, | ||
writer: defaultLoggerWriter, | ||
timestampFormat: defaultLoggerTimeFormat, | ||
} | ||
done := make(chan struct{}) | ||
go c.handleStdLogger(done) | ||
<-done // have to wait, it was running too quickly and some messages can be lost | ||
return c | ||
} | ||
|
||
// this will redirect the output of | ||
func (c *console) handleStdLogger(done chan<- struct{}) { | ||
var w *io.PipeWriter | ||
c.r, w = io.Pipe() | ||
stdlog.SetOutput(w) | ||
|
||
scanner := bufio.NewScanner(c.r) | ||
go func() { | ||
done <- struct{}{} | ||
}() | ||
|
||
for scanner.Scan() { | ||
WithField("stdlog", true).Info(scanner.Text()) | ||
} | ||
_ = c.r.Close() | ||
_ = w.Close() | ||
} | ||
|
||
// Log handles the log entry | ||
func (c *console) Log(e Entry) { | ||
var i int | ||
|
||
b := BytePool().Get() | ||
lvl := e.Level.String() | ||
color := c.colors[e.Level] | ||
b = append(b, e.Timestamp.Format(c.timestampFormat)...) | ||
b = append(b, space) | ||
b = append(b, color...) | ||
|
||
for i = 0; i < 6-len(lvl); i++ { | ||
b = append(b, space) | ||
} | ||
b = append(b, lvl...) | ||
b = append(b, ansi.Reset...) | ||
b = append(b, space) | ||
b = append(b, e.Message...) | ||
|
||
for _, f := range e.Fields { | ||
b = append(b, space) | ||
b = append(b, color...) | ||
b = append(b, f.Key...) | ||
b = append(b, ansi.Reset...) | ||
b = append(b, equals) | ||
|
||
switch t := f.Value.(type) { | ||
case string: | ||
b = append(b, t...) | ||
case int: | ||
b = strconv.AppendInt(b, int64(t), base10) | ||
case int8: | ||
b = strconv.AppendInt(b, int64(t), base10) | ||
case int16: | ||
b = strconv.AppendInt(b, int64(t), base10) | ||
case int32: | ||
b = strconv.AppendInt(b, int64(t), base10) | ||
case int64: | ||
b = strconv.AppendInt(b, t, base10) | ||
case uint: | ||
b = strconv.AppendUint(b, uint64(t), base10) | ||
case uint8: | ||
b = strconv.AppendUint(b, uint64(t), base10) | ||
case uint16: | ||
b = strconv.AppendUint(b, uint64(t), base10) | ||
case uint32: | ||
b = strconv.AppendUint(b, uint64(t), base10) | ||
case uint64: | ||
b = strconv.AppendUint(b, t, base10) | ||
case float32: | ||
b = strconv.AppendFloat(b, float64(t), 'f', -1, 32) | ||
case float64: | ||
b = strconv.AppendFloat(b, t, 'f', -1, 64) | ||
case bool: | ||
b = strconv.AppendBool(b, t) | ||
default: | ||
b = append(b, fmt.Sprintf(v, f.Value)...) | ||
} | ||
} | ||
b = append(b, newLine) | ||
_, _ = c.writer.Write(b) | ||
BytePool().Put(b) | ||
} | ||
|
||
// Close cleans up any resources | ||
func (c *console) Close() error { | ||
// reset the output back to original | ||
stdlog.SetOutput(os.Stderr) | ||
// since we reset the output piror to closing we don't have to wait | ||
if c.r != nil { | ||
_ = c.r.Close() | ||
} | ||
return nil | ||
} |
Oops, something went wrong.