Hi Andreas,
I went for the easy way first but you are right. Here is a version which
loops over all network interfaces and omits all loopback devices:
g_val_t
bytes_in_func( void )
{
g_val_t val;
perfstat_id_t name;
perfstat_netinterface *nif_buf, *p;
static u_longlong_t last_bytes_in = 0, bytes_in;
longlong_t d;
int i, nr_netif;
static double last_time = 0.0;
double now, delta_t;
struct timeval timeValue;
struct timezone timeZone;
gettimeofday( &timeValue, &timeZone );
now = (double) (timeValue.tv_sec - boottime) + (timeValue.tv_usec /
1000000.0);
nr_netif = perfstat_netinterface( NULL, NULL, sizeof(
perfstat_netinterface_t ), 0 );
if (nr_netif == -1)
val.f = 0.0;
else
{
/* We can allocate enough memory for the buffer */
nif_buf = (perfstat_netinterface_t *)
malloc( NrOfNetinterfaces * sizeof(
perfstat_netinterface_t));
if (nif_buf == NULL)
/* couldn't allocate enough memory */
val.f = 0.0;
else
{
/* In order to get all of the network interfaces statistics,
* we will first ask for the network interface which name is "",
* that can be considered as as an alias for the name of the first
* network interface.
*/
strcpy( name.name, FIRST_NETINTERFACE );
if (perfstat_netinterface( &name,
nif_buf,
sizeof( perfstat_netinterface_t ),
nr_netif ) == -1)
val.f = 0.0;
else
{
bytes_in = 0L;
/* Ok, we could get the statistics, we can now use it. */
for (i = 0, p = nif_buf; i < nr_netif; i++, p++ )
if (p->type != IFT_LOOP)
bytes_in += p->ibytes;
}
/* free allocated memory again */
free( nif_buf );
/* get the number of bytes transferred in, check for integer overrun */
d = bytes_in - last_bytes_in;
if (d < 0) d += ULONG_MAX;
delta_t = now - last_time;
if ( delta_t )
val.f = (double) d / delta_t;
else
val.f = 0.0;
last_bytes_in = d;
}
}
last_time = now;
return( val );
}
Regards,
Michael
Andreas Schoenfeld wrote:
Hi Michael,
to subtract the traffic on lo0: will do for lost installations of cause.
But if the loop back device has an other name or if there is more then
one, it wont fit.
An more flexible way would be to loop over all network devices with
collecting "perfstat_netinterface" and sum all that have nif.type!=IFT_LOOP.
Best Regards
Andreas
Michael Perzl schrieb:
Hi Andreas,
please see my other email with regards to the overrun.
The problem that the loopback traffic is counted also is part of the
perfstat_netinterface_total() routine. When looking at some of the
metric implementations for bytes_in I found the following:
- AIX, your version and my version have that "problem"
- Linux, specifically "filters" out the "lo:" network traffic
- Solaris, seems to also have that "problem"
- FreeBSD, specifically "filters" out the loopback traffic
- HP-UX, no implementation for bytes_in
- IRIX, no implementation for bytes_in
- Darwin, specifically "filters" out the loopback traffic
- ....
So I would guess, that it is a wanted feature to filter out the loopback
traffic for the total number of bytes_in. The same thing would be true
for bytes_out, pkts_in and pkts_out.
Here is a version which would hopefully implement all that and should
take care of the integer ovverun too:
g_val_t
bytes_in_func( void )
{
g_val_t val;
perfstat_netinterface_total_t n;
perfstat_id_t name;
perfstat_netinterface nif;
static u_longlong_t last_bytes_in = 0, bytes_in;
longlong_t d;
static double last_time = 0.0;
double now, delta_t;
struct timeval timeValue;
struct timezone timeZone;
gettimeofday( &timeValue, &timeZone );
now = (double) (timeValue.tv_sec - boottime) + (timeValue.tv_usec /
1000000.0);
if (perfstat_netinterface_total( NULL, &n, sizeof(
perfstat_netinterface_total_t ), 1 ) == -1)
val.f = 0.0;
else
{
strcpy( name.name, "lo0" );
if (perfstat_netinterface( &name, &nif, sizeof(
perfstat_netinterface_t ), 1) == -1)
val.f = 0.0;
else
{
/* subtract the loopback device bytes, check for integer overrun */
d = n.ibytes - nif.ibytes;
if (d < 0) d += ULONG_MAX;
/* get the number of bytes transferred in, check for integer overrun */
d -= last_bytes_in;
if (d < 0) d += ULONG_MAX;
delta_t = now - last_time;
if ( delta_t )
val.f = (double) d / delta_t;
else
val.f = 0.0;
last_bytes_in = d;
}
}
last_time = now;
return( val );
}
Any comments/takers ?
Best Regards,
Michael