func getXraySamplingRuleManifest()

in agent/envoy_bootstrap/envoy_bootstrap.go [716:778]


func getXraySamplingRuleManifest(fileUtil FileUtil) (string, error) {
	// This function will try to get the file path for the xray sampling rule manifest.
	// The input can either be the json file specified via XRAY_SAMPLING_RULE_MANIFEST
	// or just the sampling rate specified via XRAY_SAMPLING_RATE env variable.
	// For more info about the format and specification of this json file refer xray docs at
	// https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-go-configuration.html#xray-sdk-go-configuration-sampling
	const envSrmKey = "XRAY_SAMPLING_RULE_MANIFEST"
	const envSrKey = "XRAY_SAMPLING_RATE"
	const srmFile = "/tmp/sampling-rules.json"
	const defaultFixedTarget = int64(1)
	const defaultVersion = int(2)
	const unsupportedVersion = int(1)

	if v := env.Get(envSrmKey); v != "" {
		// XRAY_SAMPLING_RULE_MANIFEST is given so validate the json file it points to.
		if data, err := fileUtil.Read(v); err != nil {
			return "", fmt.Errorf("could not read file %s=\"%s\": %w", envSrmKey, v, err)
		} else if ruleManifest, err := sampling.ManifestFromJSONBytes(data); err != nil {
			// ManifestFromJSONBytes method from aws xray go sdk will parse the data and validate.
			return "", fmt.Errorf("validation failed for file %s=\"%s\": %w", envSrmKey, v, err)
		} else if unsupportedVersion == ruleManifest.Version {
			// Sampling manifest can have two possible versions (1 & 2) but envoy xray extension doesn't support version 1.
			return "", fmt.Errorf("validation failed for file %s=\"%s\": version %d is not supported", envSrmKey, v, ruleManifest.Version)
		} else {
			log.Infof("%s is defined as %s, merging it with the x-ray tracing config.", envSrmKey, v)
			return v, nil
		}
	} else if v := env.Get(envSrKey); v != "" {
		// XRAY_SAMPLING_RULE_MANIFEST is not given but XRAY_SAMPLING_RATE is given so create the sampling-rules.json.
		var fixedRate float64
		var err error
		// The fixed rate is a decimal between 0 and 1.00 (100%).
		if fixedRate, err = strconv.ParseFloat(v, 32); err != nil || float64(0) > fixedRate || float64(1) < fixedRate {
			return "", fmt.Errorf("%s environment variable (\"%s\") must be a decimal between 0 and 1.00 (100%%)", envSrKey, v)
		}
		// Round off to the nearest 2 decimal point precision.
		fixedRate = math.Round(fixedRate*100) / 100
		// If fixed rate is 0.05 (5%) then no-op
		if fixedRate == 0.05 {
			log.Infof("%s is defined as %s, but not creating a sampling manifest as ~0.05 is the X-Ray default", envSrKey, v)
			return "", nil
		}
		localManifest := &sampling.RuleManifest{
			Version: defaultVersion,
			Default: &sampling.Rule{
				Properties: &sampling.Properties{
					FixedTarget: defaultFixedTarget,
					Rate:        fixedRate,
				},
			},
			Rules: []*sampling.Rule{},
		}
		if data, err := json.Marshal(localManifest); err != nil {
			return "", err
		} else if err = fileUtil.Write(srmFile, data, 0644); err != nil {
			return "", err
		} else {
			log.Infof("%s is defined as %s, localized sampling rate is set to %.2f (%d%%)", envSrKey, v, fixedRate, int(fixedRate*100))
			return srmFile, nil
		}
	}
	return "", nil
}