code: func JsonFormatEx(pretty, lineSeparated bool) LogFormat {
  	jsonMarshal := json.Marshal
  	if pretty {
  		jsonMarshal = func(v interface{}) ([]byte, error) {
  			return json.MarshalIndent(v, "", "    ")
  		}
  	}
  
  	return FormatFunc(func(r *Record) []byte {
  		props := make(map[string]interface{})
  
  		props["t"] = r.Time
  		props["lvl"] = levelString[r.Level]
  		props["msg"] = r.Message
  		for k, v := range r.Context {
  			props[k] = formatJsonValue(v)
  		}
  
  		b, err := jsonMarshal(props)
  		if err != nil {
  			b, _ = jsonMarshal(map[string]string{
  				errorKey: err.Error(),
  			})
  			return b
  		}
  
  		if lineSeparated {
  			b = append(b, '\n')
  		}
  
  		return b
  	})
  }
docs: // JsonFormatEx formats log records as JSON objects. If pretty is true,
  // records will be pretty-printed. If lineSeparated is true, records
  // will be logged with a new line between each record.