logging: stdout formatter: use logfmt package to format non-special stdout fields + handle errors

refs #40
This commit is contained in:
Christian Schwarz 2017-11-12 21:43:19 +01:00
parent 9e48c70f58
commit cef63ac176

View File

@ -7,7 +7,6 @@ import (
"github.com/go-logfmt/logfmt" "github.com/go-logfmt/logfmt"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/zrepl/zrepl/logger" "github.com/zrepl/zrepl/logger"
"strings"
"time" "time"
) )
@ -85,16 +84,17 @@ func (f *HumanFormatter) Format(e *logger.Entry) (out []byte, err error) {
} }
fmt.Fprint(&line, e.Message) fmt.Fprint(&line, e.Message)
if len(e.Fields)-len(prefixed) > 0 {
fmt.Fprint(&line, " ")
enc := logfmt.NewEncoder(&line)
for field, value := range e.Fields { for field, value := range e.Fields {
if prefixed[field] { if prefixed[field] {
continue continue
} }
if err := logfmtTryEncodeKeyval(enc, field, value); err != nil {
if strings.ContainsAny(field, " \t") { return nil, err
return nil, errors.Errorf("field must not contain whitespace: '%s'", field) }
} }
fmt.Fprintf(&line, " %s=\"%s\"", field, value)
} }
return line.Bytes(), nil return line.Bytes(), nil
@ -154,7 +154,9 @@ func (f *LogfmtFormatter) Format(e *logger.Entry) ([]byte, error) {
if !ok { if !ok {
break break
} }
enc.EncodeKeyval(pf, v) if err := logfmtTryEncodeKeyval(enc, pf, v); err != nil {
return nil, err // unlikely
}
prefixed[pf] = true prefixed[pf] = true
} }
@ -162,13 +164,25 @@ func (f *LogfmtFormatter) Format(e *logger.Entry) ([]byte, error) {
for k, v := range e.Fields { for k, v := range e.Fields {
if !prefixed[k] { if !prefixed[k] {
enc.EncodeKeyval(k, v) if err := logfmtTryEncodeKeyval(enc, k, v); err != nil {
}
}
if err := enc.EndRecord(); err != nil {
return nil, err return nil, err
} }
}
}
return buf.Bytes(), nil return buf.Bytes(), nil
} }
func logfmtTryEncodeKeyval(enc *logfmt.Encoder, field, value interface{}) error {
err := enc.EncodeKeyval(field, value)
switch err {
case nil: // ok
return nil
case logfmt.ErrUnsupportedValueType:
enc.EncodeKeyval(field, fmt.Sprintf("<%T>", value))
return nil
}
return errors.Wrapf(err, "cannot encode field '%s'", field)
}