91 lines
2.0 KiB
Go
91 lines
2.0 KiB
Go
package log
|
|
|
|
import (
|
|
"io"
|
|
|
|
"go.uber.org/multierr"
|
|
"go.uber.org/zap/zapcore"
|
|
)
|
|
|
|
// A PipeReader is a reader that reads from the logger. It is synchronous
|
|
// so blocking on read will affect logging performance.
|
|
type PipeReader struct {
|
|
r *io.PipeReader
|
|
closer io.Closer
|
|
core zapcore.Core
|
|
}
|
|
|
|
// Read implements the standard Read interface
|
|
func (p *PipeReader) Read(data []byte) (int, error) {
|
|
return p.r.Read(data)
|
|
}
|
|
|
|
// Close unregisters the reader from the logger.
|
|
func (p *PipeReader) Close() error {
|
|
if p.core != nil {
|
|
loggerCore.DeleteCore(p.core)
|
|
}
|
|
return multierr.Append(p.core.Sync(), p.closer.Close())
|
|
}
|
|
|
|
// NewPipeReader creates a new in-memory reader that reads from all loggers
|
|
// The caller must call Close on the returned reader when done.
|
|
//
|
|
// By default, it:
|
|
//
|
|
// 1. Logs JSON. This can be changed by passing the PipeFormat option.
|
|
// 2. Logs everything that would otherwise be logged to the "primary" log
|
|
// output. That is, everything enabled by SetLogLevel. The minimum log level
|
|
// can be increased by passing the PipeLevel option.
|
|
func NewPipeReader(opts ...PipeReaderOption) *PipeReader {
|
|
opt := pipeReaderOptions{
|
|
format: JSONOutput,
|
|
level: LevelDebug,
|
|
}
|
|
|
|
for _, o := range opts {
|
|
o.setOption(&opt)
|
|
}
|
|
|
|
r, w := io.Pipe()
|
|
|
|
p := &PipeReader{
|
|
r: r,
|
|
closer: w,
|
|
core: newCore(opt.format, zapcore.AddSync(w), opt.level),
|
|
}
|
|
|
|
loggerCore.AddCore(p.core)
|
|
|
|
return p
|
|
}
|
|
|
|
type pipeReaderOptions struct {
|
|
format LogFormat
|
|
level LogLevel
|
|
}
|
|
|
|
type PipeReaderOption interface {
|
|
setOption(*pipeReaderOptions)
|
|
}
|
|
|
|
type pipeReaderOptionFunc func(*pipeReaderOptions)
|
|
|
|
func (p pipeReaderOptionFunc) setOption(o *pipeReaderOptions) {
|
|
p(o)
|
|
}
|
|
|
|
// PipeFormat sets the output format of the pipe reader
|
|
func PipeFormat(format LogFormat) PipeReaderOption {
|
|
return pipeReaderOptionFunc(func(o *pipeReaderOptions) {
|
|
o.format = format
|
|
})
|
|
}
|
|
|
|
// PipeLevel sets the log level of logs sent to the pipe reader.
|
|
func PipeLevel(level LogLevel) PipeReaderOption {
|
|
return pipeReaderOptionFunc(func(o *pipeReaderOptions) {
|
|
o.level = level
|
|
})
|
|
}
|