code: func JSON(file string, log *logrus.Entry) (json.RawMessage, error) {
  	out := make(map[string]interface{})
  
  	for _, f := range strings.Split(file, string(os.PathListSeparator)) {
  		if f == "" {
  			continue
  		}
  
  		if _, err := os.Stat(f); os.IsNotExist(err) {
  			log.Warnf("Fact file %s does not exist", f)
  			continue
  		}
  
  		j, err := ioutil.ReadFile(f)
  		if err != nil {
  			log.Errorf("Could not read fact file %s: %s", f, err)
  			continue
  		}
  
  		if strings.HasSuffix(f, "yaml") {
  			j, err = yaml.YAMLToJSON(j)
  			if err != nil {
  				log.Errorf("Could not parse facts file %s as YAML: %s", file, err)
  				continue
  			}
  		}
  
  		facts := make(map[string]interface{})
  		err = json.Unmarshal(j, &facts)
  		if err != nil {
  			log.Errorf("Could not parse facts file: %s", err)
  			continue
  		}
  
  		// does a very dumb shallow merge that mimics ruby Hash#merge
  		// to maintain mcollective compatability
  		for k, v := range facts {
  			out[k] = v
  		}
  	}
  
  	if len(out) == 0 {
  		return json.RawMessage("{}"), fmt.Errorf("no facts were found in %s", file)
  	}
  
  	j, err := json.Marshal(&out)
  	if err != nil {
  		return json.RawMessage("{}"), fmt.Errorf("could not JSON marshal merged facts: %s", err)
  	}
  
  	return json.RawMessage(j), nil
  }
docs: // JSON parses the data, including doing any conversions needed, and returns JSON text