open-vault/helper/pluginutil/logger.go
Calvin Leung Huang b023d46cb8 Direct plugin logs through vault's logger (#3142)
* Direct plugin logs through vault's logger

* Pass in a logger in testConfig
2017-08-15 10:16:48 -04:00

159 lines
3.6 KiB
Go

package pluginutil
import (
"bytes"
"fmt"
stdlog "log"
"strings"
hclog "github.com/hashicorp/go-hclog"
log "github.com/mgutz/logxi/v1"
)
// pluginLogFaker is a wrapper on logxi.Logger that
// implements hclog.Logger
type hclogFaker struct {
logger log.Logger
name string
implied []interface{}
}
func (f *hclogFaker) buildLog(msg string, args ...interface{}) (string, []interface{}) {
if f.name != "" {
msg = fmt.Sprintf("%s: %s", f.name, msg)
}
args = append(f.implied, args...)
return msg, args
}
func (f *hclogFaker) Trace(msg string, args ...interface{}) {
msg, args = f.buildLog(msg, args...)
f.logger.Trace(msg, args...)
}
func (f *hclogFaker) Debug(msg string, args ...interface{}) {
msg, args = f.buildLog(msg, args...)
f.logger.Debug(msg, args...)
}
func (f *hclogFaker) Info(msg string, args ...interface{}) {
msg, args = f.buildLog(msg, args...)
f.logger.Info(msg, args...)
}
func (f *hclogFaker) Warn(msg string, args ...interface{}) {
msg, args = f.buildLog(msg, args...)
f.logger.Warn(msg, args...)
}
func (f *hclogFaker) Error(msg string, args ...interface{}) {
msg, args = f.buildLog(msg, args...)
f.logger.Error(msg, args...)
}
func (f *hclogFaker) IsTrace() bool {
return f.logger.IsTrace()
}
func (f *hclogFaker) IsDebug() bool {
return f.logger.IsDebug()
}
func (f *hclogFaker) IsInfo() bool {
return f.logger.IsInfo()
}
func (f *hclogFaker) IsWarn() bool {
return f.logger.IsWarn()
}
func (f *hclogFaker) IsError() bool {
return !f.logger.IsTrace() && !f.logger.IsDebug() && !f.logger.IsInfo() && !f.IsWarn()
}
func (f *hclogFaker) With(args ...interface{}) hclog.Logger {
var nf = *f
nf.implied = append(nf.implied, args...)
return f
}
func (f *hclogFaker) Named(name string) hclog.Logger {
var nf = *f
if nf.name != "" {
nf.name = nf.name + "." + name
}
return &nf
}
func (f *hclogFaker) ResetNamed(name string) hclog.Logger {
var nf = *f
nf.name = name
return &nf
}
func (f *hclogFaker) StandardLogger(opts *hclog.StandardLoggerOptions) *stdlog.Logger {
if opts == nil {
opts = &hclog.StandardLoggerOptions{}
}
return stdlog.New(&stdlogAdapter{f, opts.InferLevels}, "", 0)
}
// Provides a io.Writer to shim the data out of *log.Logger
// and back into our Logger. This is basically the only way to
// build upon *log.Logger.
type stdlogAdapter struct {
hl hclog.Logger
inferLevels bool
}
// Take the data, infer the levels if configured, and send it through
// a regular Logger
func (s *stdlogAdapter) Write(data []byte) (int, error) {
str := string(bytes.TrimRight(data, " \t\n"))
if s.inferLevels {
level, str := s.pickLevel(str)
switch level {
case hclog.Trace:
s.hl.Trace(str)
case hclog.Debug:
s.hl.Debug(str)
case hclog.Info:
s.hl.Info(str)
case hclog.Warn:
s.hl.Warn(str)
case hclog.Error:
s.hl.Error(str)
default:
s.hl.Info(str)
}
} else {
s.hl.Info(str)
}
return len(data), nil
}
// Detect, based on conventions, what log level this is
func (s *stdlogAdapter) pickLevel(str string) (hclog.Level, string) {
switch {
case strings.HasPrefix(str, "[DEBUG]"):
return hclog.Debug, strings.TrimSpace(str[7:])
case strings.HasPrefix(str, "[TRACE]"):
return hclog.Trace, strings.TrimSpace(str[7:])
case strings.HasPrefix(str, "[INFO]"):
return hclog.Info, strings.TrimSpace(str[6:])
case strings.HasPrefix(str, "[WARN]"):
return hclog.Warn, strings.TrimSpace(str[7:])
case strings.HasPrefix(str, "[ERROR]"):
return hclog.Error, strings.TrimSpace(str[7:])
case strings.HasPrefix(str, "[ERR]"):
return hclog.Error, strings.TrimSpace(str[5:])
default:
return hclog.Info, str
}
}