-
Notifications
You must be signed in to change notification settings - Fork 2.4k
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
export DragonFlyBSD CPU time #310
Conversation
Might not be lined up correctly? Weird output data in the second CPU.
Don't need it since we aren't malloc'ing
Moved to exporting via a string, which is then split and parsed. The string is sometimes duplicated, however.
Duplication was caused by malloc returning a region of memory that already had data in it.
The correct frequency is the systimer frequency, not the stathz. From one of the DragonFly developers: The bump upon each statclock is: ((cur_systimer - prev_systimer) * systimer_freq) >> 32 systimer_freq can be extracted from following sysctl in userspace: sysctl kern.cputimer.freq
This is the code that was lifted from the freebsd implementation, but was not correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I think I prefer pulling values out instead of the string conversion (and associated buffer size issues).
I think in general it would be beneficial to do less in C and more in Go; this should make it easier to verify the C parts.
What about tests?
|
||
// string needs to hold (5*ncpu)(uint64_t + char) | ||
// The char is the space between values. | ||
int cputime_size = (sizeof(uint64_t)+sizeof(char))*(5*ncpu); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sizeof(uint64_t)
is not the size of the decimal expansion you're actually putting into the string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any help is welcome, I'm not a C programmer :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sizeof is the size of the binary representation (8), but (if the number is large) the decimal representation you're putting in this array will be longer. 2^64-1 has 20 digits, so I think if you just put in 5_ncpu_21 it'll be enough?
Additionally, instead of malloc+bzero you can use calloc below – memory returned from calloc is initialized to 0: *cputime = calloc(ncpu, 5*21)
should do.
I'm not a C programmer either …
uint64_t user, nice, sys, intr, idle; | ||
user = nice = sys = intr = idle = 0; | ||
for (int i = 0; i < ncpu; ++i) { | ||
user = ((double) cp_t[i].cp_user) / freq; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this is integer seconds? This conversion/division is very lossy; can we get more granularity out? Either by putting micro- or nanoseconds in the string, or by using floats?
Or read the frequency separately, get cp_t out in to Go land as is, and do the math in Go?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Happy to read out the values separately and do the math in Go land. I would prefer to stick with exporting in a string, as my initial attempts at pulling out the struct and moving it to go didn't end well.
Export cpu mode times as original uint64_t data, and update frequency, and do the conversion to float64 and subsequent division in go.
@matthiasr I think this latest commit might address both your concerns. The value being written to the string is now Example scrape output:
Where previous values were just integers. |
@matthiasr moved to doing all the math in go-land (exporting values as I'm really not sure what you're looking for regarding the test. Let me know. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you!
any chance you wanna merge this? :) |
@fabxc any love? |
Hey,
This reports the node cpu time for machines running DragonFlyBSD. It is analogous to
cpu_freebsd.go
, but unfortunately DragonFly required a different implementation.The code here is heavily influenced by the FreeBSD implementation, as well as this:
https://www.dragonflybsd.org/mailarchive/users/2010-04/msg00056.html
I have a separate implementation that uses creates a go slice from a C array of the double values, instead of how this implementation uses a string, if that is preferred: https://github.com/stuartnelson3/node_exporter/blob/dfly-cpu-doubles/collector/cpu_dragonfly.go
Note:
The units seem to be off by perhaps 3 orders of magnitude. I'm waiting for a response from the DragonFly community as to what the units for the various cpu modes.
FIXED: It seems I was using the incorrect value to find cpu time. The value I should use is the systimer_freq. The pr has been updated to use that.