Beispiel #1
0
func (p *Procstat) createProcesses() error {
	var errstring string
	var outerr error

	pids, err := p.getAllPids()
	if err != nil {
		errstring += err.Error() + " "
	}

	for _, pid := range pids {
		_, ok := p.pidmap[pid]
		if !ok {
			proc, err := process.NewProcess(pid)
			if err == nil {
				p.pidmap[pid] = proc
			} else {
				errstring += err.Error() + " "
			}
		}
	}

	if errstring != "" {
		outerr = fmt.Errorf("%s", errstring)
	}

	return outerr
}
Beispiel #2
0
func (sc *ServiceCommand) waitForAnyPort(cancel <-chan struct{}, command *exec.Cmd) error {
	for true {
		time.Sleep(100 * time.Millisecond)

		select {
		case <-cancel:
			return nil
		default:
		}

		connections, err := net.Connections("all")
		if err != nil {
			return errors.WithStack(err)
		}

		proc, err := process.NewProcess(int32(command.Process.Pid))
		if err != nil {
			return errors.WithStack(err)
		}
		if hasPort(proc, connections) {
			return nil
		}
	}
	return errors.New("exited check loop unexpectedly")
}
Beispiel #3
0
func memoryUtil() (value int64, rate float32) {

	pids := apachePID()

	total := make([]int64, len(pids))

	var sum int64

	for i, pid := range pids {
		k, _ := process.NewProcess(int32(pid))
		rss, _ := k.MemoryInfo()

		val := rss.RSS / 1024

		total[i] = int64(val)

	}

	for k := 0; k < len(total); k++ {

		sum = sum + total[k]

	}

	rat := (sum / 1024) * 100

	fmt.Println(sum, rat)

	return sum / 1024, float32(rat)
}
Beispiel #4
0
// pidStats returns the resource usage stats per pid
func (e *UniversalExecutor) pidStats() (map[string]*cstructs.ResourceUsage, error) {
	stats := make(map[string]*cstructs.ResourceUsage)
	e.pidLock.RLock()
	pids := make(map[int]*nomadPid, len(e.pids))
	for k, v := range e.pids {
		pids[k] = v
	}
	e.pidLock.RUnlock()
	for pid, np := range pids {
		p, err := process.NewProcess(int32(pid))
		if err != nil {
			e.logger.Printf("[DEBUG] executor: unable to create new process with pid: %v", pid)
			continue
		}
		ms := &cstructs.MemoryStats{}
		if memInfo, err := p.MemoryInfo(); err == nil {
			ms.RSS = memInfo.RSS
			ms.Swap = memInfo.Swap
			ms.Measured = ExecutorBasicMeasuredMemStats
		}

		cs := &cstructs.CpuStats{}
		if cpuStats, err := p.Times(); err == nil {
			cs.SystemMode = np.cpuStatsSys.Percent(cpuStats.System * float64(time.Second))
			cs.UserMode = np.cpuStatsUser.Percent(cpuStats.User * float64(time.Second))
			cs.Measured = ExecutorBasicMeasuredCpuStats

			// calculate cpu usage percent
			cs.Percent = np.cpuStatsTotal.Percent(cpuStats.Total() * float64(time.Second))
		}
		stats[strconv.Itoa(pid)] = &cstructs.ResourceUsage{MemoryStats: ms, CpuStats: cs}
	}

	return stats, nil
}
Beispiel #5
0
func (spec *Specification) createProcesses() ([]*process.Process, error) {
	var out []*process.Process
	var errstring string
	var outerr error

	pids, err := spec.getAllPids()
	if err != nil {
		errstring += err.Error() + " "
	}

	for _, pid := range pids {
		p, err := process.NewProcess(int32(pid))
		if err == nil {
			out = append(out, p)
		} else {
			errstring += err.Error() + " "
		}
	}

	if errstring != "" {
		outerr = fmt.Errorf("%s", errstring)
	}

	return out, outerr
}
Beispiel #6
0
// pidStats returns the resource usage stats per pid
func (e *UniversalExecutor) pidStats() (map[string]*cstructs.ResourceUsage, error) {
	stats := make(map[string]*cstructs.ResourceUsage)
	e.pidLock.RLock()
	pids := make([]*nomadPid, len(e.pids))
	copy(pids, e.pids)
	e.pidLock.RUnlock()
	for _, pid := range pids {
		p, err := process.NewProcess(int32(pid.pid))
		if err != nil {
			e.logger.Printf("[DEBUG] executor: unable to create new process with pid: %v", pid.pid)
			continue
		}
		ms := &cstructs.MemoryStats{}
		if memInfo, err := p.MemoryInfo(); err == nil {
			ms.RSS = memInfo.RSS
			ms.Swap = memInfo.Swap
		}

		cs := &cstructs.CpuStats{}
		if cpuStats, err := p.Times(); err == nil {
			cs.SystemMode = cpuStats.System
			cs.UserMode = cpuStats.User

			// calculate cpu usage percent
			cs.Percent = pid.cpuStats.Percent(cpuStats.Total())
		}
		stats[strconv.Itoa(pid.pid)] = &cstructs.ResourceUsage{MemoryStats: ms, CpuStats: cs}
	}

	return stats, nil
}
Beispiel #7
0
func main() {
	flag.Parse()

	pid, err := readIntFromFile("pid")
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading pid: %v\n", err)
		os.Exit(254)
	}

	process, err := process.NewProcess(pid)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to create process %d instance: %v\n", pid, err)
		os.Exit(254)
	}

	if force {
		if process.Kill() != nil {
			fmt.Fprintf(os.Stderr, "unable to kill process %d: %v\n", pid, err)
			os.Exit(254)
		}
	} else {
		if process.Terminate() != nil {
			fmt.Fprintf(os.Stderr, "unable to terminate process %d: %v\n", pid, err)
			os.Exit(254)
		}
	}
}
Beispiel #8
0
// GetComponent gets statistics about this component
func GetComponent() *api.ComponentStats {
	status := new(api.ComponentStats)
	status.Uptime = uint64(time.Now().Sub(startTime).Seconds())
	process, err := process.NewProcess(int32(os.Getpid()))
	if err == nil {
		if memory, err := process.MemoryInfo(); err == nil {
			status.Memory = &api.ComponentStats_MemoryStats{
				Memory: memory.RSS,
				Swap:   memory.Swap,
			}
		}
		if cpu, err := process.Times(); err == nil {
			status.Cpu = &api.ComponentStats_CPUStats{
				User:   float32(cpu.User),
				System: float32(cpu.System),
				Idle:   float32(cpu.Idle),
			}
		}
	}
	status.Goroutines = uint64(runtime.NumGoroutine())
	memstats := new(runtime.MemStats)
	runtime.ReadMemStats(memstats)
	status.GcCpuFraction = float32(memstats.GCCPUFraction)
	return status
}
Beispiel #9
0
// dockerData gather date from docker daemon directly (using DOCKER_HOST)
// and from proc/DOCKER_PID/status and publish those to conn
func storeProc(pidfile string, interval time.Duration) {
	pid, err := loadPid(pidfile)
	if err != nil {
		warn(err)
		return
	}

	p, err := process.NewProcess(int32(pid))
	warn(err)
	if err != nil {
		return
	}

	// threads
	threads, err := p.NumThreads()
	warn(err)
	if err != nil {
		return
	}

	mi, err := p.MemoryInfo()
	warn(err)
	if err != nil {
		return
	}

	procData := map[string]interface{}{"threads": threads, "vmsize": int(mi.VMS), "rss": int(mi.RSS)}
	log.Println("proc = ", procData)
	store("process", map[string]string{"pid": strconv.Itoa(int(pid))}, procData)
}
Beispiel #10
0
func (sc *ServiceConfig) Status() ([]ServiceStatus, error) {
	command, err := sc.GetCommand()
	if err != nil {
		return nil, errors.WithStack(err)
	}

	status := ServiceStatus{
		Service: sc,
		Status:  "STOPPED",
	}

	if command.Pid != 0 {
		status.Status = "RUNNING"
		status.Pid = command.Pid
		proc, err := process.NewProcess(int32(command.Pid))
		if err != nil {
			return nil, errors.WithStack(err)
		}
		epochStart, err := proc.CreateTime()
		if err != nil {
			return nil, errors.WithStack(err)
		}
		status.StartTime = time.Unix(epochStart/1000, 0)
		status.Ports, err = sc.getPorts(proc)
		if err != nil {
			return nil, errors.WithStack(err)
		}
	}

	return []ServiceStatus{
		status,
	}, nil
}
Beispiel #11
0
//Returns the command line slice for a given process name
func getProcCmdline(procname string) (cmd []string, err error) {
	var proc *process.Process
	pid := getProcPID(procname)
	proc, err = process.NewProcess(int32(pid))
	cmd, err = proc.CmdlineSlice()
	return cmd, err
}
Beispiel #12
0
Datei: main.go Projekt: nak3/rkt
func killAllChildren(pid int32) error {
	p, err := process.NewProcess(pid)
	if err != nil {
		return err
	}
	processes := []*process.Process{p}
	for i := 0; i < len(processes); i++ {
		children, err := processes[i].Children()
		if err != nil && err != process.ErrorNoChildren {
			return err
		}
		processes = append(processes, children...)
	}
	for _, p := range processes {
		osProcess, err := os.FindProcess(int(p.Pid))
		if err != nil {
			if err.Error() == "os: process already finished" {
				continue
			}
			return err
		}
		err = osProcess.Kill()
		if err != nil {
			return err
		}
	}
	return nil
}
Beispiel #13
0
// Run gathers ps information from gosigar.
func (p *Ps) Run() error {
	pids := sigar.ProcList{}
	err := pids.Get()
	if err != nil {
		return err
	}

	for _, pid := range pids.List {
		state := sigar.ProcState{}
		mem := sigar.ProcMem{}
		time := sigar.ProcTime{}

		if err := state.Get(pid); err != nil {
			continue
		}
		if err := mem.Get(pid); err != nil {
			continue
		}
		if err := time.Get(pid); err != nil {
			continue
		}

		procData := make(map[string]interface{})
		procData["Name"] = state.Name
		procData["Pid"] = pid
		procData["ParentPid"] = state.Ppid
		procData["StartTime"] = time.FormatStartTime()
		procData["RunTime"] = time.FormatTotal()
		procData["MemoryResident"] = mem.Resident / 1024
		procData["State"] = string(state.State)

		gopsutilProcess, err := gopsutil_process.NewProcess(int32(pid))
		if err != nil {
			continue
		}

		mmaps, err := gopsutilProcess.MemoryMaps(false)
		if err == nil {
			procData["MemoryMaps"] = mmaps
		}

		ios, err := gopsutilProcess.IOCounters()
		if err == nil {
			procData["IOCounters"] = ios
		}

		ctxSwitches, err := gopsutilProcess.NumCtxSwitches()
		if err == nil {
			procData["CtxSwitches"] = ctxSwitches
		}

		if len(procData) > 0 {
			p.Data[strconv.Itoa(pid)] = procData
		}
	}

	return nil
}
Beispiel #14
0
func runCpuMonitor(monitor *CpuLoadMonitor) {
	pid := os.Getpid()
	process, _ := process.NewProcess(int32(pid))
	for monitor.running {
		monitor.sample, _ = process.CPUPercent(0)
		monitor.cpu = monitor.alpha*monitor.sample + (1-monitor.alpha)*monitor.cpu
		time.Sleep(monitor.samplingInterval)
	}

}
Beispiel #15
0
func (ds *DaemonStat) ProcessStats() {
	ds.PointsRate = float64(ds.PointsCounter) / float64(ds.Interval)
	p, err := process.NewProcess(int32(os.Getpid()))
	if err == nil {
		ds.MemGauge, _ = p.MemoryInfo()
	} else {
		ds.MemGauge = nil
		log.Errorf("%v", err)
		Stat.ErrorIncr()
	}
}
Beispiel #16
0
func ProcessTable() map[int32]string {
	res := make(map[int32]string)
	pids, _ := process.Pids()

	for i := 0; i < len(pids); i++ {
		pid := pids[i]
		proc, _ := process.NewProcess(pid)
		cline, _ := proc.Cmdline()
		res[pid] = cline
	}
	return res
}
Beispiel #17
0
func getCPU() {
	stats, _ := process.NewProcess(int32(os.Getpid()))
	for {
		cpu, _ := stats.Percent(1 * time.Second)
		if cpu > 30 {
			log.Printf("CPU:%v\n", cpu)
			go WatchCPU()
		}

		time.Sleep(1 * time.Second)
	}
}
Beispiel #18
0
// dockerData gather date from docker daemon directly (using DOCKER_HOST)
// and from proc/DOCKER_PID/status and publish those to conn
func dockerData(tags string, conn net.Conn) {
	if os.Getenv("DOCKER_HOST") == "" {
		log.Fatal(`please provide eg. DOCKER_HOST="tcp://127.0.0.1:8080"`)
	}

	// pid
	pidS := os.Getenv("DOCKER_PID")
	if pidS == "" {
		log.Fatal("cannot find docker deamon - please provide DOCKER_PID - try DOCKER_PID=`sudo lsof -t -sTCP:LISTEN -i :8080`")
	}
	pid, err := strconv.Atoi(pidS)
	if err != nil {
		log.Fatal(err)
	}
	log.Printf("docker pid=%d", pid)

	// docker client
	dockerClient, _ := docker.NewClientFromEnv()
	for {
		p, err := process.NewProcess(int32(pid))
		// threads
		threads, err := p.NumThreads()
		if err != nil {
			log.Fatal(err)
		}
		mi, err := p.MemoryInfo()
		if err != nil {
			log.Fatal(err)
		}
		rss := mi.RSS
		vms := mi.VMS

		// docker info
		info, err := dockerClient.Info()
		// log.Printf("info=%#v", info)

		output := fmt.Sprintf("docker,driver=%s%s containers=%di,goroutines=%di,images=%di,threads=%di,vmsize=%di,rss=%di",
			info.Get("Driver"), tags, info.GetInt("Containers"), info.GetInt("NGoroutines"), info.GetInt("Images"), threads, vms, rss)

		n, err := conn.Write([]byte(output))
		if err != nil {
			log.Fatal(err)
		}
		log.Println(n, output)
		time.Sleep(1 * time.Second)
	}
}
Beispiel #19
0
func GetLoggingLevelByInspectingParent() (logrus.Level, error) {
	ppid := os.Getppid()
	process, err := process.NewProcess(int32(ppid))
	if err != nil {
		return logrus.WarnLevel, err
	}

	cmdline, err := process.Cmdline()
	if err != nil {
		return logrus.WarnLevel, err
	}

	if strings.Contains(cmdline, "-vv") {
		return logrus.DebugLevel, nil
	} else if strings.Contains(cmdline, "-v") {
		return logrus.InfoLevel, nil
	}
	return logrus.WarnLevel, nil
}
Beispiel #20
0
Datei: stop.go Projekt: nak3/rkt
func main() {
	flag.Parse()

	pid, err := readIntFromFile("ppid")
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading pid: %v\n", err)
		os.Exit(1)
	}

	process, err := process.NewProcess(pid)
	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to create process %d instance: %v\n", pid, err)
		os.Exit(1)
	}

	if force {
		children, err := process.Children()
		if err != nil {
			fmt.Fprintf(os.Stderr, "cannot get child processes from %d: %v\n", pid, err)
			os.Exit(1)
		}

		for _, child := range children {
			if err := child.Kill(); err != nil {
				fmt.Fprintf(os.Stderr, "unable to kill process %d: %v\n", child.Pid, err)
				os.Exit(1)
			}
		}

		if err := process.Kill(); err != nil {
			fmt.Fprintf(os.Stderr, "unable to kill process %d: %v\n", pid, err)
			os.Exit(1)
		}
	} else {
		if process.Terminate() != nil {
			fmt.Fprintf(os.Stderr, "unable to terminate process %d: %v\n", pid, err)
			os.Exit(1)
		}
	}
}
Beispiel #21
0
// Run runs the trigger. encountered errors go to the configured channel (if any).
// you probably want to run this in a new goroutine.
func (cpu Cpu) Run() {
	tick := time.NewTicker(cpu.checkEvery)
	pid := os.Getpid()
	p, err := process.NewProcess(int32(pid))
	if err != nil {
		cpu.logError(err)
		return
	}
	for ts := range tick.C {
		percent, err := p.Percent(0)
		if err != nil {
			cpu.logError(err)
			continue
		}
		//fmt.Println("percent is now", percent)
		unix := ts.Unix()
		// we discard the decimals of the percentage. an integer with percent resolution should be good enough.
		if int(percent) >= cpu.threshold && unix >= cpu.lastUnix+int64(cpu.minTimeDiff) {
			f, err := os.Create(fmt.Sprintf("%s/%d.profile-cpu", cpu.path, unix))
			if err != nil {
				cpu.logError(err)
				continue
			}
			err = pprof.StartCPUProfile(f)
			if err != nil {
				cpu.logError(err)
			}
			time.Sleep(cpu.profDur)
			pprof.StopCPUProfile()
			cpu.lastUnix = unix
			err = f.Close()
			if err != nil {
				cpu.logError(err)
			}
		}
	}
}
Beispiel #22
0
Datei: main.go Projekt: nak3/rkt
func getUsage(pid int32) ([]*ProcessStatus, error) {
	var statuses []*ProcessStatus
	pids := []int32{pid}
	for i := 0; i < len(pids); i++ {
		proc, ok := pidMap[pids[i]]
		if !ok {
			var err error
			proc, err = process.NewProcess(pids[i])
			if err != nil {
				return nil, err
			}
			pidMap[pids[i]] = proc
		}
		s, err := getProcStatus(proc)
		if err != nil {
			return nil, err
		}
		statuses = append(statuses, s)

		children, err := proc.Children()
		if err != nil && err != process.ErrorNoChildren {
			return nil, err
		}

	childloop:
		for _, child := range children {
			for _, p := range pids {
				if p == child.Pid {
					fmt.Printf("%d is in %#v\n", p, pids)
					continue childloop
				}
			}
			pids = append(pids, child.Pid)
		}
	}
	return statuses, nil
}
Beispiel #23
0
func (s *ServiceConfig) GetCommand() (*ServiceCommand, error) {

	s.printf("Building control command for: %v\n", s.Name)

	dir := home.EdwardConfig.LogDir

	logs := struct {
		Build string
		Run   string
		Stop  string
	}{
		Build: path.Join(dir, s.Name+"-build.log"),
		Run:   path.Join(dir, s.Name+".log"),
		Stop:  path.Join(dir, s.Name+"-stop.log"),
	}

	path := ""
	if s.Path != nil {
		path = *s.Path
	}

	command := &ServiceCommand{
		Service: s,
		Scripts: struct {
			Build  Script
			Launch Script
			Stop   Script
		}{
			Build: Script{
				Path:    path,
				Command: s.Commands.Build,
				Log:     logs.Build,
			},
			Launch: Script{
				Path:    path,
				Command: s.Commands.Launch,
				Log:     logs.Run,
			},
			Stop: Script{
				Path:    path,
				Command: s.Commands.Stop,
				Log:     logs.Stop,
			},
		},
		Logger: s.Logger,
	}

	// Retrieve the PID if available
	pidFile := command.getPidPath()
	s.printf("Checking pidfile for %v: %v\n", s.Name, pidFile)
	if _, err := os.Stat(pidFile); err == nil {
		dat, err := ioutil.ReadFile(pidFile)
		if err != nil {
			return nil, errors.WithStack(err)
		}
		pid, err := strconv.Atoi(string(dat))
		if err != nil {
			return nil, errors.WithStack(err)
		}
		command.Pid = pid

		exists, err := process.PidExists(int32(command.Pid))
		if err != nil {
			return nil, errors.WithStack(err)
		}
		if !exists {
			s.printf("Process for %v was not found, resetting.\n", s.Name)
			command.clearState()
		}

		proc, err := process.NewProcess(int32(command.Pid))
		if err != nil {
			return nil, errors.WithStack(err)
		}
		cmdline, err := proc.Cmdline()
		if err != nil {
			return nil, errors.WithStack(err)
		}
		if !strings.Contains(cmdline, s.Name) {
			s.printf("Process for %v was not as expected (found %v), resetting.\n", s.Name, cmdline)
			command.clearState()
		}

	} else {
		s.printf("No pidfile for %v", s.Name)
	}
	// TODO: Set status

	return command, nil
}
Beispiel #24
0
// currentState returns the current state of system conforming
// to definitions
func currentState(d Def) State {
	s, err := host.HostInfo()
	if err != nil {
		log.Printf("failed to load host information. (%v)", err.Error())
		return State{}
	}

	state := State{
		Host:      s.Hostname,
		Uptime:    s.Uptime,
		Ports:     []Port{},
		Sockets:   []Socket{},
		Processes: []Process{},
	}

	pids, err := process.Pids()
	if err != nil {
		log.Printf("failed to query running processes. (%v)", err.Error())
		return State{}
	}

	for _, i := range pids {
		p, err := process.NewProcess(i)
		if err != nil {
			log.Printf("failed to get handle of process with ID: %v. (%v)", i, err.Error())
			continue
		}

		n, _ := p.Name()
		cmd, err := p.Cmdline()
		if err != nil {
			log.Printf("failed to query the command which started the process with ID: %v. (%v)", i, err.Error())
			continue
		}

		cnt := false
		for k := range d.Processes {
			if strings.Contains(n, k) {
				cnt = true
				break
			}
		}

		conn, err := p.Connections()
		if err != nil {
			log.Printf("failed to query connections made by process with ID: %v. (%v)", i, err.Error())
			continue
		}

		pr := Process{
			Name:        n,
			Command:     cmd,
			Connections: []Conn{},
		}

		for _, c := range conn {
			ncn := Conn{Local: c.Laddr, Remote: c.Raddr}
			pr.Connections = append(pr.Connections, ncn)

			if _, match := d.Ports[ncn.Local.Port]; match {
				state.Ports = append(state.Ports, Port(ncn.Remote.Port))
			}

			if cnt {
				state.Processes = append(state.Processes, pr)
			}
		}
	}

	for k := range d.Sockets {
		if _, err := os.Stat(k); err != nil {
			state.Sockets = append(state.Sockets, Socket(k))
		}
	}

	return state
}
Beispiel #25
0
func (r region) communicate() {

	//collect region statistics
	ticker := time.NewTicker(5 * time.Second)

	//object holding process reference
	var exe *exec.Cmd
	exe = nil
	var start time.Time
	var proc *process.Process

	//process communication
	terminated := make(chan bool)

	for {
		select {
		case <-terminated:
			//the process exited for some Reason
			exe = nil
		case cmd := <-r.cmds:
			switch cmd.command {
			case "start":
				//if already running, exit
				if exe != nil {
					r.log.Error("Region is already running", r.UUID)
					continue
				}
				//execute binaries
				os.Chdir(r.dir)
				cmdName := "/usr/bin/mono"
				cmdArgs := []string{"OpenSim.exe", "-console", "rest"}
				exe = exec.Command(cmdName, cmdArgs...)
				err := exe.Start()
				if err != nil {
					errMsg := fmt.Sprintf("Error starting process: %s", err.Error())
					r.log.Error(errMsg)
					continue
				}
				r.log.Info("Started Successfully")
				start = time.Now()
				proc, _ = process.NewProcess(int32(exe.Process.Pid))
				go func() {
					//wait for process, ignoring process-specific errors
					_ = exe.Wait()
					r.log.Error("Terminated")
					exe = nil
					terminated <- true
				}()
			case "kill":
				//if not running, exit
				if exe == nil {
					errMsg := fmt.Sprintf("Kill region %v failed, region is not running", r.UUID.String())
					r.log.Error(errMsg)
					continue
				}
				if err := exe.Process.Kill(); err != nil {
					errMsg := fmt.Sprintf("Error killing process: %s", err.Error())
					r.log.Error(errMsg)
				}
			default:
				r.log.Info("Received unexpected command: %v", cmd.command)
			}
		case <-ticker.C:
			stat := mgm.RegionStat{UUID: r.UUID}
			if exe == nil {
				//trivially halted if we never started
				r.rStat <- stat
				continue
			}
			stat.Running = true

			cpuPercent, err := proc.CPUPercent(0)
			if err != nil {
				errMsg := fmt.Sprintf("Error getting cpu for pid: %s", err.Error())
				r.log.Error(errMsg)
			} else {
				stat.CPUPercent = cpuPercent
			}
			//memory info from this module may not be correct....
			memInfo, err := proc.MemoryInfo()
			if err != nil {
				errMsg := fmt.Sprintf("Error getting memory for pid: %s", err.Error())
				r.log.Error(errMsg)
			} else {
				stat.MemKB = (float64(memInfo.RSS) / 1024.0)
			}

			elapsed := time.Since(start)
			stat.Uptime = elapsed

			r.rStat <- stat
		}
	}
}
Beispiel #26
0
func runRktMonitor(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(254)
	}

	d, err := time.ParseDuration(flagDuration)
	if err != nil {
		fmt.Printf("%v\n", err)
		os.Exit(254)
	}

	if os.Getuid() != 0 {
		fmt.Printf("need to be root to run rkt images\n")
		os.Exit(254)
	}

	f, err := os.Open(args[0])
	if err != nil {
		fmt.Printf("%v\n", err)
		os.Exit(254)
	}
	decoder := json.NewDecoder(f)

	podManifest := false
	man := schema.PodManifest{}
	err = decoder.Decode(&man)
	if err == nil {
		podManifest = true
	}

	var flavorType, testImage string
	if flagStage1Path == "" {
		flavorType = "stage1-coreos.aci"
	} else {
		if !fileExist(flagStage1Path) {
			fmt.Fprintln(os.Stderr, "Given stage1 file path doesn't exist")
			os.Exit(254)
		}
		_, flavorType = filepath.Split(flagStage1Path)
	}

	var containerId string
	var stopCmd, execCmd, gcCmd *exec.Cmd
	var loadAvg *load.AvgStat
	var containerStarting, containerStarted, containerStopping, containerStopped time.Time

	records := [][]string{{"Time", "PID name", "PID number", "RSS", "CPU"}}             // csv headers
	summaryRecords := [][]string{{"Load1", "Load5", "Load15", "StartTime", "StopTime"}} // csv summary headers

	var rktBinary string
	if flagRktDir != "" {
		rktBinary = filepath.Join(flagRktDir, "rkt")
		if !fileExist(rktBinary) {
			fmt.Fprintln(os.Stderr, "rkt binary not found!")
			os.Exit(1)
		}
	} else {
		rktBinary = "rkt"
	}

	for i := 0; i < flagRepetitionNumber; i++ {
		// build argument list for execCmd
		argv := []string{"run", "--debug"}

		if flagStage1Path != "" {
			argv = append(argv, fmt.Sprintf("--stage1-path=%v", flagStage1Path))
		}

		if podManifest {
			argv = append(argv, "--pod-manifest", args[0])
		} else {
			argv = append(argv, args[0], "--insecure-options=image")
		}
		argv = append(argv, "--net=default-restricted")

		execCmd = exec.Command(rktBinary, argv...)

		if flagShowOutput {
			execCmd.Stderr = os.Stderr
		}

		cmdReader, err := execCmd.StdoutPipe()
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for execCmd", err)
			os.Exit(254)
		}

		execCmdScanner := bufio.NewScanner(cmdReader)

		startConfirmation := make(chan string, 1)
		go func() {
			var containerId string
			for execCmdScanner.Scan() {
				if flagShowOutput {
					fmt.Println(execCmdScanner.Text())
				}
				if strings.Contains(execCmdScanner.Text(), "APP-STARTED!") {
					startConfirmation <- containerId
				} else if strings.Contains(execCmdScanner.Text(), "Set hostname to") {
					sl := strings.SplitAfter(execCmdScanner.Text(), "<rkt-")
					containerId = sl[len(sl)-1]
					containerId = containerId[:len(containerId)-2]
				}
			}
		}()
		containerStarting = time.Now()
		err = execCmd.Start()
		containerId = <-startConfirmation
		containerStarted = time.Now() //here we are sure - container is running (issue: #3019)
		close(startConfirmation)

		if flagShowOutput {
			execCmd.Stdout = os.Stdout
		}

		if err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(254)
		}

		usages := make(map[int32][]*ProcessStatus)

		timeToStop := time.Now().Add(d)

		for time.Now().Before(timeToStop) {
			usage, err := getUsage(int32(execCmd.Process.Pid))
			if err != nil {
				panic(err)
			}
			if flagVerbose {
				printUsage(usage)
			}

			if flagSaveToCsv {
				records = addRecords(usage, records)
			}

			for _, ps := range usage {
				usages[ps.Pid] = append(usages[ps.Pid], ps)
			}

			_, err = process.NewProcess(int32(execCmd.Process.Pid))
			if err != nil {
				// process.Process.IsRunning is not implemented yet
				fmt.Fprintf(os.Stderr, "rkt exited prematurely\n")
				break
			}

			time.Sleep(time.Second)
		}

		loadAvg, err = load.Avg()
		if err != nil {
			fmt.Fprintf(os.Stderr, "measure load avg failed: %v\n", err)
		}

		stopCmd = exec.Command(rktBinary, "stop", containerId)

		cmdStopReader, err := stopCmd.StdoutPipe()
		if err != nil {
			fmt.Fprintln(os.Stderr, "Error creating StdoutPipe for stopCmd", err)
			os.Exit(254)
		}
		cmdStopScanner := bufio.NewScanner(cmdStopReader)

		containerStopping = time.Now()
		stopConfirmation := make(chan bool, 1)
		go func() {
			for cmdStopScanner.Scan() {
				if strings.Contains(cmdStopScanner.Text(), containerId) {
					stopConfirmation <- true
					return
				}
			}
			stopConfirmation <- false
		}()
		err = stopCmd.Start()
		if !<-stopConfirmation {
			fmt.Println("WARNING: There was a problem stopping the container! (Container already stopped?)")
		}
		containerStopped = time.Now()
		close(stopConfirmation)

		if err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(254)
		}

		gcCmd = exec.Command(rktBinary, "gc", "--grace-period=0")
		gcCmd.Start()

		for _, processHistory := range usages {
			var avgCPU float64
			var avgMem uint64
			var peakMem uint64

			for _, p := range processHistory {
				avgCPU += p.CPU
				avgMem += p.RSS
				if peakMem < p.RSS {
					peakMem = p.RSS
				}
			}

			avgCPU = avgCPU / float64(len(processHistory))
			avgMem = avgMem / uint64(len(processHistory))

			if !flagSaveToCsv {
				fmt.Printf("%s(%d): seconds alive: %d  avg CPU: %f%%  avg Mem: %s  peak Mem: %s\n", processHistory[0].Name, processHistory[0].Pid, len(processHistory), avgCPU, formatSize(avgMem), formatSize(peakMem))
			}
		}

		if flagSaveToCsv {
			summaryRecords = append(summaryRecords, []string{
				strconv.FormatFloat(loadAvg.Load1, 'g', 3, 64),
				strconv.FormatFloat(loadAvg.Load5, 'g', 3, 64),
				strconv.FormatFloat(loadAvg.Load15, 'g', 3, 64),
				strconv.FormatFloat(float64(containerStarted.Sub(containerStarting).Nanoseconds())/float64(time.Millisecond), 'g', -1, 64),
				strconv.FormatFloat(float64(containerStopped.Sub(containerStopping).Nanoseconds())/float64(time.Millisecond), 'g', -1, 64)})
		}

		fmt.Printf("load average: Load1: %f Load5: %f Load15: %f\n", loadAvg.Load1, loadAvg.Load5, loadAvg.Load15)
		fmt.Printf("container start time: %sms\n", strconv.FormatFloat(float64(containerStarted.Sub(containerStarting).Nanoseconds())/float64(time.Millisecond), 'g', -1, 64))
		fmt.Printf("container stop time: %sms\n", strconv.FormatFloat(float64(containerStopped.Sub(containerStopping).Nanoseconds())/float64(time.Millisecond), 'g', -1, 64))
	}

	t := time.Now()
	_, testImage = filepath.Split(args[0])
	prefix := fmt.Sprintf("%d-%02d-%02d_%02d-%02d_%s_%s", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), flavorType, testImage)
	if flagSaveToCsv {
		err = saveRecords(records, flagCsvDir, prefix+"_rkt_benchmark_interval.csv")
		if err != nil {
			fmt.Fprintf(os.Stderr, "Can't write to a file: %v\n", err)
		}
		err = saveRecords(summaryRecords, flagCsvDir, prefix+"_rkt_benchmark_summary.csv")
		if err != nil {
			fmt.Fprintf(os.Stderr, "Can't write to a summary file: %v\n", err)
		}
	}
}
Beispiel #27
0
Datei: main.go Projekt: nak3/rkt
func runRktMonitor(cmd *cobra.Command, args []string) {
	if len(args) != 1 {
		cmd.Usage()
		os.Exit(1)
	}

	d, err := time.ParseDuration(flagDuration)
	if err != nil {
		fmt.Printf("%v\n", err)
		os.Exit(1)
	}

	if os.Getuid() != 0 {
		fmt.Printf("need to be root to run rkt images\n")
		os.Exit(1)
	}

	f, err := os.Open(args[0])
	if err != nil {
		fmt.Printf("%v\n", err)
		os.Exit(1)
	}
	decoder := json.NewDecoder(f)

	podManifest := false
	man := schema.PodManifest{}
	err = decoder.Decode(&man)
	if err == nil {
		podManifest = true
	}

	var flavorType string
	if flagStage1Path == "" {
		flavorType = "stage1-coreos.aci"
	} else {
		_, flavorType = filepath.Split(flagStage1Path)
	}

	var execCmd *exec.Cmd
	var loadAvg *load.AvgStat
	var containerStarting, containerStarted, containerStopping, containerStopped time.Time

	records := [][]string{{"Time", "PID name", "PID number", "RSS", "CPU"}}             // csv headers
	summaryRecords := [][]string{{"Load1", "Load5", "Load15", "StartTime", "StopTime"}} // csv summary headers

	var rktBinary string
	if flagRktDir != "" {
		rktBinary = flagRktDir + "/rkt"
	} else {
		rktBinary = "rkt"
	}

	for i := 0; i < flagRepetitionNumber; i++ {
		containerStarting = time.Now()

		// build argument list for execCmd
		argv := []string{"run"}

		if flagStage1Path != "" {
			argv = append(argv, fmt.Sprintf("--stage1-path=%v", flagStage1Path))
		}

		if podManifest {
			argv = append(argv, "--pod-manifest", args[0])
		} else {
			argv = append(argv, args[0], "--insecure-options=image")
		}
		argv = append(argv, "--net=default-restricted")

		execCmd = exec.Command(rktBinary, argv...)

		if flagShowOutput {
			execCmd.Stdout = os.Stdout
			execCmd.Stderr = os.Stderr
		}

		err = execCmd.Start()
		containerStarted = time.Now()
		if err != nil {
			fmt.Printf("%v\n", err)
			os.Exit(1)
		}

		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt)
		go func() {
			for range c {
				err := killAllChildren(int32(execCmd.Process.Pid))
				if err != nil {
					fmt.Fprintf(os.Stderr, "cleanup failed: %v\n", err)
				}
				os.Exit(1)
			}
		}()

		usages := make(map[int32][]*ProcessStatus)

		timeToStop := time.Now().Add(d)

		for time.Now().Before(timeToStop) {
			usage, err := getUsage(int32(execCmd.Process.Pid))
			if err != nil {
				panic(err)
			}
			if flagVerbose {
				printUsage(usage)
			}

			if flagSaveToCsv {
				records = addRecords(usage, records)
			}

			for _, ps := range usage {
				usages[ps.Pid] = append(usages[ps.Pid], ps)
			}

			_, err = process.NewProcess(int32(execCmd.Process.Pid))
			if err != nil {
				// process.Process.IsRunning is not implemented yet
				fmt.Fprintf(os.Stderr, "rkt exited prematurely\n")
				break
			}

			time.Sleep(time.Second)
		}

		loadAvg, err = load.Avg()
		if err != nil {
			fmt.Fprintf(os.Stderr, "measure load avg failed: %v\n", err)
		}

		containerStopping = time.Now()
		err = killAllChildren(int32(execCmd.Process.Pid))
		containerStopped = time.Now()
		if err != nil {
			fmt.Fprintf(os.Stderr, "cleanup failed: %v\n", err)
		}

		for _, processHistory := range usages {
			var avgCPU float64
			var avgMem uint64
			var peakMem uint64

			for _, p := range processHistory {
				avgCPU += p.CPU
				avgMem += p.RSS
				if peakMem < p.RSS {
					peakMem = p.RSS
				}
			}

			avgCPU = avgCPU / float64(len(processHistory))
			avgMem = avgMem / uint64(len(processHistory))

			if !flagSaveToCsv {
				fmt.Printf("%s(%d): seconds alive: %d  avg CPU: %f%%  avg Mem: %s  peak Mem: %s\n", processHistory[0].Name, processHistory[0].Pid, len(processHistory), avgCPU, formatSize(avgMem), formatSize(peakMem))
			}
		}

		if flagSaveToCsv {
			summaryRecords = append(summaryRecords, []string{
				strconv.FormatFloat(loadAvg.Load1, 'g', 3, 64),
				strconv.FormatFloat(loadAvg.Load5, 'g', 3, 64),
				strconv.FormatFloat(loadAvg.Load15, 'g', 3, 64),
				strconv.FormatInt(containerStarted.Sub(containerStarting).Nanoseconds(), 10),
				strconv.FormatInt(containerStopped.Sub(containerStopping).Nanoseconds(), 10)})
		}

		fmt.Printf("load average: Load1: %f Load5: %f Load15: %f\n", loadAvg.Load1, loadAvg.Load5, loadAvg.Load15)
		fmt.Printf("container start time: %dns\n", containerStarted.Sub(containerStarting).Nanoseconds())
		fmt.Printf("container stop time: %dns\n", containerStopped.Sub(containerStopping).Nanoseconds())
	}

	t := time.Now()
	prefix := fmt.Sprintf("%d-%02d-%02d_%02d-%02d_%s_", t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), flavorType)
	if flagSaveToCsv {
		err = saveRecords(records, flagCsvDir, prefix+"rkt_benchmark_interval.csv")
		if err != nil {
			fmt.Fprintf(os.Stderr, "Can't write to a file: %v\n", err)
		}
		err = saveRecords(summaryRecords, flagCsvDir, prefix+"rkt_benchmark_summary.csv")
		if err != nil {
			fmt.Fprintf(os.Stderr, "Can't write to a summary file: %v\n", err)
		}
	}
}
Beispiel #28
0
// Run gathers ps information from gosigar.
func (p *Ps) Run() error {
	pids := sigar.ProcList{}
	err := pids.Get()
	if err != nil {
		return err
	}

	for _, pid := range pids.List {
		state := sigar.ProcState{}
		mem := sigar.ProcMem{}
		time := sigar.ProcTime{}

		if err := state.Get(pid); err != nil {
			continue
		}
		if err := mem.Get(pid); err != nil {
			continue
		}
		if err := time.Get(pid); err != nil {
			continue
		}

		// If NameFilter is defined, skip process if its name does not match filter.
		if len(p.NameFilter) > 0 {
			matched := false

			for _, nameFilterInterface := range p.NameFilter {
				nameFilter := nameFilterInterface.(string)

				if strings.Contains(state.Name, nameFilter) {
					matched = true
					break
				}
			}

			if matched == false {
				continue
			}
		}

		procData := make(map[string]interface{})
		procData["Name"] = state.Name
		procData["Pid"] = pid
		procData["ParentPid"] = state.Ppid
		procData["StartTime"] = time.FormatStartTime()
		procData["RunTime"] = time.FormatTotal()
		procData["MemoryResident"] = mem.Resident / 1024
		procData["State"] = string(state.State)

		gopsutilProcess, err := gopsutil_process.NewProcess(int32(pid))
		if err != nil {
			continue
		}

		mmaps, err := gopsutilProcess.MemoryMaps(false)
		if err == nil {
			procData["MemoryMaps"] = mmaps
		}

		ios, err := gopsutilProcess.IOCounters()
		if err == nil {
			procData["IOCounters"] = ios
		}

		ctxSwitches, err := gopsutilProcess.NumCtxSwitches()
		if err == nil {
			procData["CtxSwitches"] = ctxSwitches
		}

		if len(procData) > 0 {
			p.Data[strconv.Itoa(pid)] = procData
		}
	}

	return nil
}