Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proc.Percent() #318

Closed
adityacs opened this issue Feb 21, 2017 · 19 comments
Closed

proc.Percent() #318

adityacs opened this issue Feb 21, 2017 · 19 comments

Comments

@adityacs
Copy link

adityacs commented Feb 21, 2017

I am trying to get cpu usage for a process. However, I am getting 0 as the value always.
Below is my sample code. I am using telegraf procstat plugin. Even there it's returning 0 value

`
func main() {

var pid int32
pid = 10172
proc, _ := process.NewProcess(pid)
p, err := proc.Percent(time.Duration(0))
if err != nil {
   fmt.Println(err)
}

}`

Thanks

@adityacs
Copy link
Author

if interval > 0:
time.Sleep(interval)
doesn't seem to be working. If I add 5 seconds sleep I can see some value

Below is the change I made
if interval > 0 { p.lastCPUTimes = cpuTimes p.lastCPUTime = now time.Sleep(10 * time.Second) cpuTimes, err = p.Times() now = time.Now() fmt.Println("hi") if err != nil { return 0, err }

Also,
if p.lastCPUTimes == nil {
// invoked first time
p.lastCPUTimes = cpuTimes
p.lastCPUTime = now
fmt.Println(p.lastCPUTimes)
return 0, nil
}
why the code is returning 0 here?

@sparrc
Copy link
Contributor

sparrc commented Feb 22, 2017

@adityacs do you have proof that the CPU usage of your process is not 0?

@adityacs
Copy link
Author

I have verified this on many processes. It will show 0 value. However, if I do sleep for 3 to 5 secs then I can get the value.

@sparrc
Copy link
Contributor

sparrc commented Feb 22, 2017

I think this issue can be closed,

@adityacs in this comment you are only collecting the process information once: #318 (comment)

CPU usage requires TWO data points in order to be calculated (and there needs to be measurable time between the two collections). So your first collection will always be 0.

Try sleeping for a few hundred milliseconds between two collections and you should see a usage reading.

@adityacs
Copy link
Author

@sparrc sleeping is handled by this part of the code right?. line time.Sleep(interval)

if interval > 0 { 
p.lastCPUTimes = cpuTimes 
p.lastCPUTime = now 
time.Sleep(interval) 
cpuTimes, err = p.Times() now = time.Now()
 if err != nil {
   return 0, err 
}

what will be the use of the else part?

else {
                if p.lastCPUTimes == nil {
                        // invoked first time
                        p.lastCPUTimes = cpuTimes
                        p.lastCPUTime = now
                        return 0, nil
                }

@sparrc
Copy link
Contributor

sparrc commented Feb 22, 2017

Where is that code from exactly? I was referring to your main() function that you pasted above.

Would help if you could try formatting your code a bit better, use "```" to surround either side of a single block of code.

@adityacs
Copy link
Author

in https://github.com/shirou/gopsutil/blob/master/process/process.go

func (p *Process) Percent(interval time.Duration) (float64, error) {
	cpuTimes, err := p.Times()
	if err != nil {
		return 0, err
	}
	now := time.Now()

	if interval > 0 {
		p.lastCPUTimes = cpuTimes
		p.lastCPUTime = now
		time.Sleep(interval)
		cpuTimes, err = p.Times()
		now = time.Now()
		if err != nil {
			return 0, err
		}
	} else {
		if p.lastCPUTimes == nil {
			// invoked first time
			p.lastCPUTimes = cpuTimes
			p.lastCPUTime = now
			return 0, nil
		}
	}

	numcpu := runtime.NumCPU()
	delta := (now.Sub(p.lastCPUTime).Seconds()) * float64(numcpu)
	ret := calculatePercent(p.lastCPUTimes, cpuTimes, delta, numcpu)
	p.lastCPUTimes = cpuTimes
	p.lastCPUTime = now
	return ret, nil
}

@adityacs
Copy link
Author

Some sleep is required for calculating cpu_percent. For processes which use low cpu(just running in background without high usage of the process), /proc/pid/stat show same values over the time as shown in below scrreenshot
splunk-pid

For processes which are constantly in use, cpu usage will be updated frequently as shown in below screenshot
influx-pid

If we don't add a sleep of at least 100ms we will be getting 0% cpu for processes consuming less cpu, which is not correct. Also, cpu usage may be 0 in the current millisecond and and 0.2% in next millisecond. So, on the average of 1-3 seconds we can get the cpu_percent.

I may be wrong. At least that is how i see other systems implementing the calculation of cpu_usage.

@adityacs
Copy link
Author

Any update on this?

@sparrc
Copy link
Contributor

sparrc commented Feb 24, 2017

@adityacs so what are you saying is the bug? proc.Percent already provides a way to call it with a sleep. Are you asking that the default behavior be changed?

@adityacs
Copy link
Author

@sparrc If we don't change the implementation here, then in telegraf procstat plugin we will have to add some sleep instead of time.Duration(0).

@sparrc
Copy link
Contributor

sparrc commented Feb 24, 2017

no it won't, proc.Percent() caches the previous call and uses that if time.Duration == 0

@adityacs
Copy link
Author

@sparrc In telegraf my interval is 10s. However, I always receive "0"% for cpu_usage.

@adityacs
Copy link
Author

@sparrc "no it won't, proc.Percent() caches the previous call and uses that if time.Duration == 0". Caching is working for me absolutely fine when I try from a sample code. I am not sure why from telegraf I am getting "0" value.

@sparrc
Copy link
Contributor

sparrc commented Mar 1, 2017

@adityacs I think you are confusing a telegraf issue with a gopsutil issue. The problem is a recently merged PR on the master branch of Telegraf. I am reverting that commit here: influxdata/telegraf#2479

@shirou I think you can close this issue.

@adityacs
Copy link
Author

adityacs commented Mar 1, 2017

@sparrc Sorry for the confusion. In my first comment of this issue itself I mentioned I am using procstat telegraf pluign.
NP.
Thanks for fixing this.

@adityacs adityacs closed this as completed Mar 1, 2017
@shirou
Copy link
Owner

shirou commented Mar 1, 2017

@sparrc Thank you for your replying.

@adityacs If you find some other problem related to gopsutil, feel free to open a new issue.

@adityacs
Copy link
Author

adityacs commented Mar 1, 2017

@shirou Sure

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants