func()

in clusterloader2/pkg/measurement/common/pod_command.go [579:670]


func (p *podPeriodicCommandMeasurement) gather() ([]measurement.Summary, error) {
	p.stop()

	klog.V(2).Infof("%s: gathered %d command results", podPeriodicCommandMeasurementName, len(p.results))

	// Create summary for all results.
	content, err := util.PrettyPrintJSON(p.results)
	if err != nil {
		// Ignore p.params.FailOnError here, since this is fatal.
		return nil, fmt.Errorf("unable to convert results to JSON: %w", err)
	}

	measurements := []measurement.Summary{
		measurement.CreateSummary(podPeriodicCommandMeasurementName, "json", content),
	}

	// Hold error to be returned to signal that the measurement failed, or nil.
	// Should only be non-nil if one of the FailOnXYZ params is set.
	var resultErr error

	// Create individual results for stdout and stderr.
	// Saving these as a value in a json document can lead to weird issues in reading the data
	// properly, especially if the data is binary, such as for profiling results.
	// Additionally, check for any errors or timeouts that may have occurred.
	for _, r := range p.results {
		getSummaryName := func(c *runCommandResult, suffix string) string {
			return strings.Join(
				[]string{
					podPeriodicCommandMeasurementName, c.StartTime.Format(time.RFC3339), r.Namespace, r.Pod, c.Name, suffix,
				}, "-",
			)
		}

		for _, c := range r.Commands {
			if c.stdout != "" {
				measurements = append(measurements, measurement.CreateSummary(getSummaryName(c, "stdout"), "txt", c.stdout))
			}
			if c.stderr != "" {
				measurements = append(measurements, measurement.CreateSummary(getSummaryName(c, "stderr"), "txt", c.stderr))
			}

			// If the result error has already been set, we don't need to set it again.
			if resultErr != nil {
				continue
			}

			if p.params.FailOnCommandError && c.ExitCode != 0 {
				resultErr = fmt.Errorf(
					"unexpected non-zero RC while executing command %s in pod %s/%s: got RC %d",
					c.Name, r.Namespace, r.Pod, c.ExitCode,
				)
				continue
			}

			if p.params.FailOnExecError && c.ExecError != "" {
				resultErr = fmt.Errorf(
					"unexpected error while executing command %s in pod %s/%s: %s", c.Name, r.Namespace, r.Pod, c.ExecError,
				)
				continue
			}

			if p.params.FailOnTimeout && c.HitTimeout {
				resultErr = fmt.Errorf(
					"hit timeout of %s while executing command %s in pod %s/%s",
					c.Timeout, c.Name, r.Namespace, r.Pod,
				)
			}
		}
	}

	// Create summary for stats.
	p.stats.Measurements = len(measurements) + 1 // Adding another measurement for the stats.
	content, err = util.PrettyPrintJSON(p.stats)
	if err != nil {
		// Ignore p.params.FailOnError here, since this is fatal.
		return nil, fmt.Errorf("unable to convert stats to JSON: %w", err)
	}

	measurements = append(
		measurements,
		measurement.CreateSummary(
			strings.Join([]string{podPeriodicCommandMeasurementName, "stats"}, "-"), "json", content,
		),
	)

	// resultErr can only be set if one of the FailOnXYZ params is set.
	if resultErr != nil {
		return measurements, resultErr
	}

	return measurements, nil
}