github.com/sykesm/fabric@v1.1.0-preview.0.20200129034918-2aa12b1a0181/common/flogging/fabenc/encoder.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package fabenc
     8  
     9  import (
    10  	"io"
    11  	"time"
    12  
    13  	zaplogfmt "github.com/sykesm/zap-logfmt"
    14  	"go.uber.org/zap/buffer"
    15  	"go.uber.org/zap/zapcore"
    16  )
    17  
    18  // A FormatEncoder is a zapcore.Encoder that formats log records according to a
    19  // go-logging based format specifier.
    20  type FormatEncoder struct {
    21  	zapcore.Encoder
    22  	formatters []Formatter
    23  	pool       buffer.Pool
    24  }
    25  
    26  // A Formatter is used to format and write data from a zap log entry.
    27  type Formatter interface {
    28  	Format(w io.Writer, entry zapcore.Entry, fields []zapcore.Field)
    29  }
    30  
    31  func NewFormatEncoder(formatters ...Formatter) *FormatEncoder {
    32  	return &FormatEncoder{
    33  		Encoder: zaplogfmt.NewEncoder(zapcore.EncoderConfig{
    34  			MessageKey:     "", // disable
    35  			LevelKey:       "", // disable
    36  			TimeKey:        "", // disable
    37  			NameKey:        "", // disable
    38  			CallerKey:      "", // disable
    39  			StacktraceKey:  "", // disable
    40  			LineEnding:     "\n",
    41  			EncodeDuration: zapcore.StringDurationEncoder,
    42  			EncodeTime: func(t time.Time, enc zapcore.PrimitiveArrayEncoder) {
    43  				enc.AppendString(t.Format("2006-01-02T15:04:05.999Z07:00"))
    44  			},
    45  		}),
    46  		formatters: formatters,
    47  		pool:       buffer.NewPool(),
    48  	}
    49  }
    50  
    51  // Clone creates a new instance of this encoder with the same configuration.
    52  func (f *FormatEncoder) Clone() zapcore.Encoder {
    53  	return &FormatEncoder{
    54  		Encoder:    f.Encoder.Clone(),
    55  		formatters: f.formatters,
    56  		pool:       f.pool,
    57  	}
    58  }
    59  
    60  // EncodeEntry formats a zap log record. The structured fields are formatted by a
    61  // zapcore.ConsoleEncoder and are appended as JSON to the end of the formatted entry.
    62  // All entries are terminated by a newline.
    63  func (f *FormatEncoder) EncodeEntry(entry zapcore.Entry, fields []zapcore.Field) (*buffer.Buffer, error) {
    64  	line := f.pool.Get()
    65  	for _, f := range f.formatters {
    66  		f.Format(line, entry, fields)
    67  	}
    68  
    69  	encodedFields, err := f.Encoder.EncodeEntry(entry, fields)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	if line.Len() > 0 && encodedFields.Len() != 1 {
    74  		line.AppendString(" ")
    75  	}
    76  	line.AppendString(encodedFields.String())
    77  	encodedFields.Free()
    78  
    79  	return line, nil
    80  }