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
}