func monitorCommand()

in agent/agent.go [87:139]


func monitorCommand(pid int, messageSource *messagesources.MessageSources, pollInterval time.Duration) syscall.WaitStatus {

	// This loop uses non-blocking calls to check the state of the process and
	// continually write to messageSource.processState channel
	var wstatus syscall.WaitStatus
	var rusage syscall.Rusage
	var options int = syscall.WNOHANG
	var pidIsAlive bool = true

	start := time.Now()
	ticker := time.NewTicker(pollInterval)
	defer ticker.Stop()

	for pidIsAlive {
		select {
		case <-ticker.C:
			if messageSource.GetTerminateProcess() {
				log.Infof("Sending sigterm to pid [%d]", pid)
				syscall.Kill(pid, syscall.SIGTERM)
			}

			wpid, err := syscall.Wait4(pid, &wstatus, options, &rusage)
			log.Tracef("[%d] WaitPid returned [%d - %v]", pid, wpid, err)

			if err != nil {
				log.Errorf("Error returned while waiting for Envoy process [%d]: %v", pid, err)
				pidIsAlive = false
			}

			if wpid == pid {
				log.Warnf("[Envoy process %d] Exited with code [%d]", wpid, wstatus.ExitStatus())

				if wstatus.Exited() {
					log.Infof("[Envoy process %d] exited normally with code: [%d]", wpid, wstatus.ExitStatus())
				} else if wstatus.Signaled() {
					log.Warnf("[Envoy process %d] was terminated by signal: [%v] with Core Dump: [%t]", wpid, wstatus.Signal(), wstatus.CoreDump())
				}

				pidIsAlive = false
			}

			messageSource.SetPid(pid)
			messageSource.SetProcessState(pidIsAlive)
			messageSource.SetPidCheckTime(time.Now().Unix()) // This data isn't used yet
		}
	}

	log.Debugf("[%d] Process exited after [%f seconds]...", pid, time.Since(start).Seconds())
	messageSource.SetProcessState(pidIsAlive)
	messageSource.SetCheckEnvoyState()

	return wstatus
}