func logSerialOutput()

in step_create_instances.go [54:122]


func logSerialOutput(ctx context.Context, s *Step, ii InstanceInterface, ib *InstanceBase, port int64, interval time.Duration) {
	w := s.w
	w.stepWait.Add(1)
	defer w.stepWait.Done()

	logsObj := path.Join(w.logsPath, fmt.Sprintf("%s-serial-port%d.log", ii.getName(), port))
	w.LogStepInfo(s.name, "CreateInstances", "Streaming instance %q serial port %d output to https://storage.cloud.google.com/%s/%s", ii.getName(), port, w.bucket, logsObj)
	var start int64
	var buf bytes.Buffer
	var gcsErr bool
	var readFromSerial bool
	var numErr int
	tick := time.Tick(interval)

Loop:
	for {
		select {
		case <-tick:
			resp, err := w.ComputeClient.GetSerialPortOutput(path.Base(ib.Project), path.Base(ii.getZone()), ii.getName(), port, start)
			if err != nil {
				numErr++
				status, sErr := w.ComputeClient.InstanceStatus(path.Base(ib.Project), path.Base(ii.getZone()), ii.getName())
				switch status {
				case "TERMINATED", "STOPPED", "STOPPING":
					// Instance is stopped or stopping.
					if sErr == nil {
						break Loop
					}
				}
				if numErr > 10 {
					// Only emit an error log if we were able to read *some* data from the
					// instance, since there's a race condition where an instance can shut
					// down fast enough that the call to InstanceStatus will return a 404.
					if !readFromSerial {
						w.LogStepInfo(s.name, "CreateInstances",
							"Instance %q: error getting serial port: %v", ii.getName(), err)
					}
					break Loop
				}
				continue
			}
			readFromSerial = true
			numErr = 0
			start = resp.Next
			buf.WriteString(resp.Contents)
			w.Logger.AppendSerialPortLogs(w, ii.getName(), resp.Contents)
			wc := w.StorageClient.Bucket(w.bucket).Object(logsObj).NewWriter(ctx)
			wc.ContentType = "text/plain"
			if _, err := wc.Write(buf.Bytes()); err != nil && !gcsErr {
				gcsErr = true
				w.LogStepInfo(s.name, "CreateInstances", "Instance %q: error writing log to GCS: %v", ii.getName(), err)
				continue
			} else if err != nil { // dont try to close the writer
				continue
			}
			if err := wc.Close(); err != nil && !gcsErr {
				gcsErr = true
				w.LogStepInfo(s.name, "CreateInstances", "Instance %q: error saving log to GCS: %v", ii.getName(), err)
				continue
			}

			if w.isCanceled {
				break Loop
			}
		}
	}

	w.Logger.WriteSerialPortLogsToCloudLogging(w, ii.getName())
}