Hi,
does anyone know what conky displays as CPU usage for a process? The values are different in conky and top, for example, top might show 11.6 for a process while conky says 3.01.
On Thu, Jul 18, 2013 at 05:13:12PM +0200, lee wrote:
Hi,
does anyone know what conky displays as CPU usage for a process? The values are different in conky and top, for example, top might show 11.6 for a process while conky says 3.01.
Not on my system. The polling times are a bit different I think, so I see same ballpark numbers: 2.53 vs 2.4, etc.
Maybe you could fiddle with these two:
cpu_avg_samples 2 update_interval 1.0
Hope this helps,
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
On Thu, Jul 18, 2013 at 05:13:12PM +0200, lee wrote:
Hi,
does anyone know what conky displays as CPU usage for a process? The values are different in conky and top, for example, top might show 11.6 for a process while conky says 3.01.
Not on my system. The polling times are a bit different I think, so I see same ballpark numbers: 2.53 vs 2.4, etc.
Yes, top has 3 seconds update interval by default, and I have conky at 10 seconds. I wish I knew what the effect of that actually is, i. e. will it display averages for the last 10 seconds, or does it always display what it is seeing at the very moment the information is displayed?
Maybe you could fiddle with these two:
cpu_avg_samples 2
Do you know what this actually does? Google hasn't been helpful at all with it.
It didn't seem to change anything. The documentation only says "The number of samples to average for CPU monitoring.".
Afaik, the cpu load is read from /proc/stat. Does conky read this file more often per update interval when you increase cpu_avg_samples?
update_interval 1.0
Even with an update interval of one second in both conky and top, there is no correlation between the cpu usage for the process. With 'cpu_avg_samples 4', conky shows something between 0.5 and 1.10 for a process that is around 3% in top.
BTW, conky also ignores an update interval specified for mail checking. I specified an hour and it updates every 10 seconds. Maybe I'll write my own monitor so I do know what it does, or stay with xosview ...
Sadly I do not have answers to any of your questions. However I have to say, I have been using conky for 5 years now; it has been incredibly reliable for me. If you think it would help, I could share my conkyrc.
Cheers,
On 19.07.2013 12:32, lee wrote:
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
On Thu, Jul 18, 2013 at 05:13:12PM +0200, lee wrote:
Hi,
does anyone know what conky displays as CPU usage for a process? The values are different in conky and top, for example, top might show 11.6 for a process while conky says 3.01.
Not on my system. The polling times are a bit different I think, so I see same ballpark numbers: 2.53 vs 2.4, etc.
Yes, top has 3 seconds update interval by default, and I have conky at 10 seconds. I wish I knew what the effect of that actually is, i. e. will it display averages for the last 10 seconds, or does it always display what it is seeing at the very moment the information is displayed?
Maybe you could fiddle with these two:
cpu_avg_samples 2
Do you know what this actually does? Google hasn't been helpful at all with it.
It didn't seem to change anything. The documentation only says "The number of samples to average for CPU monitoring.".
Afaik, the cpu load is read from /proc/stat. Does conky read this file more often per update interval when you increase cpu_avg_samples?
update_interval 1.0
Even with an update interval of one second in both conky and top, there is no correlation between the cpu usage for the process. With 'cpu_avg_samples 4', conky shows something between 0.5 and 1.10 for a process that is around 3% in top.
BTW, conky also ignores an update interval specified for mail checking. I specified an hour and it updates every 10 seconds. Maybe I'll write my own monitor so I do know what it does, or stay with xosview ...
Answer for all your questions is in conky's source code. In file src/linux.cc, there is a function called get_cpu_count which grabs data from /proc/stat . After this function you'll find several other functions that open /proc/stat .
Mateusz Marzantowicz
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
Sadly I do not have answers to any of your questions. However I have to say, I have been using conky for 5 years now; it has been incredibly reliable for me. If you think it would help, I could share my conkyrc.
Thank you, I guess it won"t hurt to share it. I'm going to re-use a little program I wrote to be used with i3 and add some graphics to it. That way, I'll know what it does :)
Mateusz Marzantowicz mmarzantowicz@osdf.com.pl writes:
On 19.07.2013 12:32, lee wrote:
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
On Thu, Jul 18, 2013 at 05:13:12PM +0200, lee wrote:
Hi,
does anyone know what conky displays as CPU usage for a process? The values are different in conky and top, for example, top might show 11.6 for a process while conky says 3.01.
BTW, conky also ignores an update interval specified for mail checking. I specified an hour and it updates every 10 seconds. Maybe I'll write my own monitor so I do know what it does, or stay with xosview ...
Answer for all your questions is in conky's source code. In file src/linux.cc, there is a function called get_cpu_count which grabs data from /proc/stat . After this function you'll find several other functions that open /proc/stat .
Did you find an explanation for why it displays different numbers than top does or why it ignores the update interval for checking mail? I thought it probably uses the same data sources for this information and didn't really want to look at the source code.
On 21.07.2013 09:55, lee wrote:
Mateusz Marzantowicz mmarzantowicz@osdf.com.pl writes:
On 19.07.2013 12:32, lee wrote:
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
On Thu, Jul 18, 2013 at 05:13:12PM +0200, lee wrote:
Hi,
does anyone know what conky displays as CPU usage for a process? The values are different in conky and top, for example, top might show 11.6 for a process while conky says 3.01.
BTW, conky also ignores an update interval specified for mail checking. I specified an hour and it updates every 10 seconds. Maybe I'll write my own monitor so I do know what it does, or stay with xosview ...
Answer for all your questions is in conky's source code. In file src/linux.cc, there is a function called get_cpu_count which grabs data from /proc/stat . After this function you'll find several other functions that open /proc/stat .
Did you find an explanation for why it displays different numbers than top does or why it ignores the update interval for checking mail? I thought it probably uses the same data sources for this information and didn't really want to look at the source code.
I can download source code for top and try to compare it with conky. This is the olny reliable way to know the difference. I strongly recommend that you check source code yourself because it's the fastest method for answering questions not answered in documentation about how software is designed.
Mateusz Marzantowicz
On Sun, Jul 21, 2013 at 09:48:11AM +0200, lee wrote:
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
Sadly I do not have answers to any of your questions. However I have to say, I have been using conky for 5 years now; it has been incredibly reliable for me. If you think it would help, I could share my conkyrc.
Thank you, I guess it won"t hurt to share it.
Okay, here it is then. Hope my settings help you.
:)
Mateusz Marzantowicz mmarzantowicz@osdf.com.pl writes:
On 21.07.2013 09:55, lee wrote:
Did you find an explanation for why it displays different numbers than top does or why it ignores the update interval for checking mail? I thought it probably uses the same data sources for this information and didn't really want to look at the source code.
I can download source code for top and try to compare it with conky. This is the olny reliable way to know the difference. I strongly recommend that you check source code yourself because it's the fastest method for answering questions not answered in documentation about how software is designed.
Yes, I know, I just don't want to look at their sources. In this case, it's easier and more fun to write something myself which then does exactly what I want.
I've done that yesterday. It's working already, showing an automatically scaling graph of the used network bandwidth over 360 samples, with the update interval given on the command line. Let it update every 10 seconds, and you see the last hour. Xosview can't do that, and conky probably can't, either.
It also has almost zero CPU usage, and memory usage is only 40064/2272 virt/res. Now I could add showing processes or whatever I like to see :)
On Mon, Jul 22, 2013 at 12:33:53PM +0200, lee wrote:
I've done that yesterday. It's working already, showing an automatically scaling graph of the used network bandwidth over 360 samples, with the update interval given on the command line. Let it update every 10 seconds, and you see the last hour. Xosview can't do that, and conky probably can't, either.
It also has almost zero CPU usage, and memory usage is only 40064/2272 virt/res. Now I could add showing processes or whatever I like to see :)
If you do not mind, it be educational for me to see your source.
:)
Suvayu Ali fatkasuvayu+linux@gmail.com writes:
On Mon, Jul 22, 2013 at 12:33:53PM +0200, lee wrote:
I've done that yesterday. It's working already, showing an automatically scaling graph of the used network bandwidth over 360 samples, with the update interval given on the command line. Let it update every 10 seconds, and you see the last hour. Xosview can't do that, and conky probably can't, either.
It also has almost zero CPU usage, and memory usage is only 40064/2272 virt/res. Now I could add showing processes or whatever I like to see :)
If you do not mind, it be educational for me to see your source.
:)
Sure --- you'll need libsx to compile it, though. Since the Fedora package providing libsx unfortunately is orphaned, I took the Debian source package, applied their patches as much as possible and managed to compile libsx. I can tar up what I have and send it to you if you want, just let me know.
I added load average monitoring today. The code is somewhat ugly because it's a derivative of a monitor I wrote to use with i3, and that one doesn't have any graphics.
Ah, two keys are currently defined:
q: quit t: set update interval
If you know a faster way to shift arrays, please let me know. I tried memmove() and it segfaulted, and I haven't looked into it further yet.
The text display can be messed up for you, depending on what fonts it will use. With libsx, you can only get the width of a text to be printed with a particular font but not the height, so for now I simply hardcoded the positions so that it fits the font it's using here.
// bwstats // This software is licensed under the GPL. // Author: lee@yun.yagibdah.de, 2013-07-21 // // compile with something like: // gcc -lsx -lXpm -lXaw -lXt -lX11 -O2 -Wall -fomit-frame-pointer // -fexpensive-optimizations -march=native bwstat.c -o bwstat // // That should compile without warnings. Now run: // // bwstat /sys/class/net/em1/statistics/rx_bytes // /sys/class/net/em1/statistics/tx_bytes // // Replace these files with whatever files have the statistics // of the network interface you want to monitor. //
#include <stdio.h> #include <sys/time.h> #include <time.h> #include <unistd.h> #include <string.h> #include <stdlib.h> #include <sys/sysinfo.h>
#include <libsx.h>
#define BUFFSIZE 128 #define KIB (1024)
#define SAMPLES 360 #define TEXT 64
typedef struct { unsigned long rx; unsigned long tx; struct timeval tv; } rxtx;
typedef struct { FILE *rx; FILE *tx; char buffer[BUFFSIZE]; } filestuff;
typedef struct { double rxbw; double txbw; time_t timestamp; } bandwidth;
typedef struct { Widget w; int width; int height; float valuesTX[SAMPLES]; float valuesRX[SAMPLES]; float loadavgs[SAMPLES]; int index; } DrawAreaData;
typedef struct { Widget w; int width; int height; } DrawAreaText;
typedef struct { int txbar; int rxbar; int sepline; int loadavg; int bg; } colours;
typedef struct { filestuff *t; rxtx *new; rxtx *old; bandwidth *bw; int notimeout; unsigned long tick; DrawAreaData Data; DrawAreaText Text; colours col; } mydata;
typedef struct { float maxTX; float maxRX; float maxAV; } maxtxrx;
typedef struct { int days; int hours; int minutes; int seconds; } updays;
void sec2days(long seconds, updays *ud) { ud->days = seconds / 86400; seconds -= 86400 * ud->days; ud->hours = seconds / 3600; seconds -= 3600 * ud->hours; ud->minutes = seconds / 60; ud->seconds = seconds - 60 * ud->minutes; }
int getstat(filestuff *f, rxtx *s) { int ret = 0;
if(gettimeofday( &(s->tv), NULL) ) { perror("gettimeofday"); ret = 3; } else { bzero(f->buffer, BUFFSIZE); int c; unsigned long offset = 0; while( ( ( c = fgetc(f->rx) ) != EOF) && offset < BUFFSIZE) { *(f->buffer + offset) = c; offset++; } if(offset < BUFFSIZE) { s->rx = atol(f->buffer);
bzero(f->buffer, BUFFSIZE); offset = 0; while( ( ( c = fgetc(f->tx) ) != EOF) && offset < BUFFSIZE) { *(f->buffer + offset) = c; offset++; } if(offset < BUFFSIZE) { s->tx = atol(f->buffer); } else { ret = 2; } } else { ret = 1; } }
return ret; }
void delta(rxtx *old, rxtx *new, bandwidth *bw) { unsigned long drx = new->rx - old->rx; unsigned long dtx = new->tx - old->tx;
double dtime = (double)(new->tv.tv_sec - old->tv.tv_sec) + (double)( (double)(new->tv.tv_usec - old->tv.tv_usec) / (double)1000000.0);
bw->rxbw = (double)drx / dtime; bw->txbw = (double)dtx / dtime; bw->timestamp = new->tv.tv_sec; }
void array_shift_left(float arrayRX[], float arrayTX[], float arrayAV[], int idx) { int n = 1; while(n <= idx) { arrayRX[n] = arrayRX[n + 1]; arrayTX[n] = arrayTX[n + 1]; arrayAV[n] = arrayAV[n + 1]; n++; } }
void get_data(mydata *d) { rewind(d->t->rx); rewind(d->t->tx);
if( !getstat(d->t, d->new) ) { delta(d->old, d->new, d->bw); memcpy(d->old, d->new, sizeof(rxtx) );
double loads[1]; if(getloadavg(loads, 1) != 1) { loads[0] = 0.0; puts("error: getloadavg() failed"); }
if(d->Data.index < SAMPLES - 1) { d->Data.valuesRX[d->Data.index] = (float)(d->bw->rxbw / (double)KIB); d->Data.valuesTX[d->Data.index] = (float)(d->bw->txbw / (double)KIB); d->Data.loadavgs[d->Data.index] = (float)loads[0]; (d->Data.index)++; } else { array_shift_left(d->Data.valuesRX, d->Data.valuesTX, d->Data.loadavgs, d->Data.index); d->Data.valuesRX[d->Data.index] = (float)(d->bw->rxbw / (double)KIB); d->Data.valuesTX[d->Data.index] = (float)(d->bw->txbw / (double)KIB); d->Data.loadavgs[d->Data.index] = (float)loads[0]; } } else { puts("error: getstat() failed"); } }
void get_maxval(float vTX[], float vRX[], float vAV[], maxtxrx *m, int idx) { m->maxTX = m->maxRX = m->maxAV = 0.0; int n = 0; while(n <= idx) { if(m->maxTX < vTX[n] ) { m->maxTX = vTX[n]; } if(m->maxRX < vRX[n] ) { m->maxRX = vRX[n]; } if(m->maxAV < vAV[n] ) { m->maxAV = vAV[n]; } n++; } }
float comp_percentage(float ref, float this) { return ( (ref == 0.0) ? 0 : (int)(this * 100.0 / ref + 0.5) ); }
int comp_percent(float from, float percentage) { return (int)(percentage * from / 100.0 + 0.5); }
void draw_bar(void *data) { mydata *d = data;
SetDrawArea(d->Data.w); SetColor(d->col.sepline); SetLineWidth(2); ClearDrawArea(); int height = d->Data.height; --height; int halfheight = height / 2; DrawLine(0, halfheight, d->Data.width, halfheight); SetLineWidth(d->Data.width / SAMPLES);
int idx = d->Data.index; maxtxrx m; get_maxval(d->Data.valuesTX, d->Data.valuesRX, d->Data.loadavgs, &m, idx);
XPoint pline[SAMPLES]; int n = 0; while(n <= idx) { float percentage = comp_percentage(m.maxTX, d->Data.valuesTX[n] ); int h = comp_percent( (float)halfheight, percentage); SetColor(d->col.txbar); DrawLine(n, halfheight - 1, n, halfheight - h);
percentage = comp_percentage(m.maxRX, d->Data.valuesRX[n] ); h = comp_percent( (float)halfheight, percentage); SetColor(d->col.rxbar); DrawLine(n, halfheight + 1, n, halfheight + h);
percentage = comp_percentage(m.maxAV, d->Data.loadavgs[n] ); h = comp_percent( (float)height, percentage); pline[n].x = n; pline[n].y = height - h;
n++; } SetColor(d->col.loadavg); DrawPolyline(pline, idx);
// SyncDisplay(); SetDrawArea(d->Text.w); ClearDrawArea(); idx -= idx < SAMPLES - 1;
double loads[3]; if(getloadavg(loads, 3) == 3) { char txt[TEXT * 2]; snprintf(txt, TEXT * 2 - 1, "rx: %8.2f (%8.2f) tx: %8.2f (%8.2f)", d->Data.valuesRX[idx], m.maxRX, d->Data.valuesTX[idx], m.maxTX); SetColor(d->col.txbar); DrawText(txt, 8, 14);
struct sysinfo syi; updays up; if( !sysinfo( &syi) ) { sec2days(syi.uptime, &up); } else { memset( &up, 0, sizeof(updays) ); }
snprintf(txt, TEXT * 2 - 1, "%5.2f %5.2f %5.2f (%5.2f), up: %d:%02d:%02d:%02d", d->Data.loadavgs[idx], loads[1], loads[2], m.maxAV, up.days, up.hours, up.minutes, up.seconds); SetColor(d->col.loadavg); DrawText(txt, 12, 28); } else { char txt[TEXT * 2]; snprintf(txt, TEXT * 2 - 1, "rx: %8.2f (%8.2f) tx: %8.2f (%8.2f), %5.2f (%5.2f)", d->Data.valuesRX[idx], m.maxRX, d->Data.valuesTX[idx], m.maxTX, d->Data.loadavgs[idx], m.maxAV); DrawText(txt, 10, d->Text.height - 10); puts("error: getloadavg() failed"); } // SyncDisplay(); }
void update_display(void *data) { mydata *d = data;
if( !(d->notimeout) ) { get_data(d); }
draw_bar(d);
if( !(d->notimeout) ) { AddTimeOut(d->tick, update_display, data); } else { d->notimeout = 0; } }
void cleanup(void *data) { mydata *d = data; if(d->t->rx != NULL) { fclose(d->t->rx); } if(d->t->tx != NULL) { fclose(d->t->tx); } }
void keypress(Widget w, char *input, int up_or_down, void *data) { if( *input == 'q') { mydata *d = data; cleanup(d); exit(0); }
if( ( *input == 't') && up_or_down) { char txt[TEXT]; mydata *d = data; snprintf(txt, TEXT - 1, "%f", (float)(d->tick / 1000.0) ); char *enter = GetText("Update Interval", txt, 128, 50); if(enter) { d->tick = (unsigned long)(atof(enter) * 1000.0); if(d->tick <= 0) { d->tick = 1000; } } } }
void cb_drawarea(Widget w, int width, int height, void *data) { mydata *d = data; if(w == d->Data.w) { d->Data.width = width; d->Data.height = height; } if(w == d->Text.w) { d->Text.width = width; d->Text.height = height; }
d->notimeout = 1; update_display(data); }
int main(int argc, char *argv[] ) {
if( !OpenDisplay(argc, argv) ) { puts("cannot open display"); exit(1); }
if(argc != 3) { puts("usage: bwstat interval /path/to/statsfile-rx /path/to/statsfile-tx"); exit(1); }
filestuff t; t.rx = fopen(argv[1], "r"); if(t.rx == NULL) { perror(argv[1] ); exit(2); } t.tx = fopen(argv[2], "r"); if(t.tx == NULL) { perror(argv[2] ); fclose(t.rx); exit(3); }
bandwidth bw; memset( &bw, 0, sizeof(bandwidth) ); rxtx new; memset( &new, 0, sizeof(rxtx) ); rxtx old; memset( &old, 0, sizeof(rxtx) );
mydata display; memset( &display, 0, sizeof(mydata) ); display.t = &t; display.new = &new; display.old = &old; display.bw = &bw; display.Data.width = 360; display.Data.height = 201; display.Text.width = display.Data.width; display.Text.height = 32; display.notimeout = 0; display.tick = 5000; display.Data.w = MakeDrawArea(display.Data.width, display.Data.height, cb_drawarea, &display); display.Text.w = MakeDrawArea(display.Text.width, display.Text.height, cb_drawarea, &display);
SetWidgetPos(display.Text.w, PLACE_UNDER, display.Data.w, NO_CARE, NULL); SetKeypressCB(display.Data.w, keypress); SetKeypressCB(display.Text.w, keypress);
ShowDisplay();
display.col.rxbar = GetNamedColor("green"); display.col.txbar = GetNamedColor("darkgreen"); display.col.sepline = GetNamedColor("darkgoldenrod"); display.col.loadavg = GetNamedColor("lightslategray"); display.col.bg = GetNamedColor("gray6");
SetBgColor(display.Data.w, display.col.bg); SetBgColor(display.Text.w, display.col.bg);
update_display( (void *)( &display) ); MainLoop();
exit(0); }