...

Source file src/github.com/sirupsen/logrus/json_formatter.go

Documentation: github.com/sirupsen/logrus

     1  package logrus
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"fmt"
     7  )
     8  
     9  type fieldKey string
    10  
    11  // FieldMap allows customization of the key names for default fields.
    12  type FieldMap map[fieldKey]string
    13  
    14  func (f FieldMap) resolve(key fieldKey) string {
    15  	if k, ok := f[key]; ok {
    16  		return k
    17  	}
    18  
    19  	return string(key)
    20  }
    21  
    22  // JSONFormatter formats logs into parsable json
    23  type JSONFormatter struct {
    24  	// TimestampFormat sets the format used for marshaling timestamps.
    25  	TimestampFormat string
    26  
    27  	// DisableTimestamp allows disabling automatic timestamps in output
    28  	DisableTimestamp bool
    29  
    30  	// DataKey allows users to put all the log entry parameters into a nested dictionary at a given key.
    31  	DataKey string
    32  
    33  	// FieldMap allows users to customize the names of keys for default fields.
    34  	// As an example:
    35  	// formatter := &JSONFormatter{
    36  	//   	FieldMap: FieldMap{
    37  	// 		 FieldKeyTime:  "@timestamp",
    38  	// 		 FieldKeyLevel: "@level",
    39  	// 		 FieldKeyMsg:   "@message",
    40  	// 		 FieldKeyFunc:  "@caller",
    41  	//    },
    42  	// }
    43  	FieldMap FieldMap
    44  
    45  	// PrettyPrint will indent all json logs
    46  	PrettyPrint bool
    47  }
    48  
    49  // Format renders a single log entry
    50  func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) {
    51  	data := make(Fields, len(entry.Data)+4)
    52  	for k, v := range entry.Data {
    53  		switch v := v.(type) {
    54  		case error:
    55  			// Otherwise errors are ignored by `encoding/json`
    56  			// https://github.com/sirupsen/logrus/issues/137
    57  			data[k] = v.Error()
    58  		default:
    59  			data[k] = v
    60  		}
    61  	}
    62  
    63  	if f.DataKey != "" {
    64  		newData := make(Fields, 4)
    65  		newData[f.DataKey] = data
    66  		data = newData
    67  	}
    68  
    69  	prefixFieldClashes(data, f.FieldMap, entry.HasCaller())
    70  
    71  	timestampFormat := f.TimestampFormat
    72  	if timestampFormat == "" {
    73  		timestampFormat = defaultTimestampFormat
    74  	}
    75  
    76  	if entry.err != "" {
    77  		data[f.FieldMap.resolve(FieldKeyLogrusError)] = entry.err
    78  	}
    79  	if !f.DisableTimestamp {
    80  		data[f.FieldMap.resolve(FieldKeyTime)] = entry.Time.Format(timestampFormat)
    81  	}
    82  	data[f.FieldMap.resolve(FieldKeyMsg)] = entry.Message
    83  	data[f.FieldMap.resolve(FieldKeyLevel)] = entry.Level.String()
    84  	if entry.HasCaller() {
    85  		data[f.FieldMap.resolve(FieldKeyFunc)] = entry.Caller.Function
    86  		data[f.FieldMap.resolve(FieldKeyFile)] = fmt.Sprintf("%s:%d", entry.Caller.File, entry.Caller.Line)
    87  	}
    88  
    89  	var b *bytes.Buffer
    90  	if entry.Buffer != nil {
    91  		b = entry.Buffer
    92  	} else {
    93  		b = &bytes.Buffer{}
    94  	}
    95  
    96  	encoder := json.NewEncoder(b)
    97  	if f.PrettyPrint {
    98  		encoder.SetIndent("", "  ")
    99  	}
   100  	if err := encoder.Encode(data); err != nil {
   101  		return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err)
   102  	}
   103  
   104  	return b.Bytes(), nil
   105  }
   106  

View as plain text