Get server Data with API

May 7, 2017 210 views
API Ubuntu

I want to get server load,uptime and bandiwidth data (5 min interval) through API call from my php web based app with authentication. All my servers are hosted in different providers. Is there any thirdparty apps which can help me?
ALL server os is: Ubuntu 14.04 and 16.04
details guide are welcomed.

1 Answer

@haqmoinul19

PHP has a built-in function for checking the system load -- sys_getloadavg -- which will provide the standard 1, 5, and 15 minute intervals.

For example:

<?php
echo '<pre>';
var_dump( sys_getloadavg() );
echo '</pre>';

Yields:

array(3) {
  [0]=>
  float(0)
  [1]=>
  float(0)
  [2]=>
  float(0)
}

You could assign that to a variable and then call the array 0-2.

<?php
$load = sys_getloadavg();

echo '<pre>';
echo $load[0] . ' - ' . $load[1] . ' - ' . $load[2];
echo '</pre>';

Which would yield:

0 - 0 - 0

You could even use list() to avoid having to call the array by key. It's far cleaner, IMO.

<?php
list( $one, $five, $fifteen ) = sys_getloadavg();

echo $one . ' - ' . $five . ' - ' . $fifteen;

Note, the above is showing 0 because the Droplet I'm demoing the code on isn't loaded at all. On a Droplet that has activity, those numbers would change.

...

As for checking system uptime, you can do that by reading from /proc/uptime.

<?php
$uptime = file_get_contents('/proc/uptime');

echo '<pre>';
var_dump( $uptime );
echo '</pre>';

Which yields something like:

string(22) "1362760.70 2722444.00"

The downside here is that you'll need to do some formatting. The alternative would be shell_exec, which allows you to run shell commands via PHP.

<?php
$uptime = shell_exec('uptime');

var_dump( $uptime );

Which yields something like:

string(70) " 19:53:39 up 15 days, 18:37, 1 user, load average: 0.00, 0.00, 0.00 "

You could also pass -p to uptime in the command to get a bit more specific.

<?php
$uptime = shell_exec('uptime -p');

var_dump( $uptime );

Which yields something like:

string(40) "up 2 weeks, 1 day, 18 hours, 38 minutes "

Regardless of the route, you'll still need to do some formatting unless you want to print the string that is returned as-is.

...

In terms of bandwidth usage, that's a bit more complex. If you're just wanting to calculate how much bandwidth a site has used, you'll need to setup access logs that only contain bytes and then process them per site. You'd need to make sure you have log rotation setup and that you're storing previous data to RAM or a file so that you're not constantly reading from older files.

Log Rotation is important here as you don't want to constantly open and close logs files that are large in size. Without proper log rotation, log sizes can get in to the GB's in size and when PHP tries to read that large a file, it's going to read it to RAM -- if you don't have enough RAM, you'll exhaust resources and services may crash.

If you're trying to get the incoming and outgoing bandwidth in total, you can use ifconfig and break down the results as needed.

For example, if I wanted to get details on eth0 I could use:

<?php
$eth0 = shell_exec('ifconfig eth0');

echo '<pre>';
var_dump( $eth0 );
echo '</pre>';

Which would yield something like:

string(570) "eth0      Link encap:Ethernet  HWaddr ....  
          inet addr:....  Bcast:....  Mask:255.255.255.0
          inet6 addr: ..../64 Scope:Link
          inet6 addr: ..../64 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1041277 errors:0 dropped:0 overruns:0 frame:0
          TX packets:606840 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:736985496 (736.9 MB)  TX bytes:230113880 (230.1 MB)

"

Know what the above provides, we could even be more specific and grab RX bytes.

<?php
$eth0 = shell_exec('ifconfig eth0 | grep "RX bytes"');

echo '<pre>';
var_dump( $eth0 );
echo '</pre>';

The above will actually give us both RX bytes and TX bytes in one string.

string(71) "          RX bytes:737010180 (737.0 MB)  TX bytes:230141424 (230.1 MB)
"

Since there's a lot of extra space in there, you'd probably want to use trim() on the result to get rid of them, which would make the above look like:

string(60) "RX bytes:737024463 (737.0 MB)  TX bytes:230158299 (230.1 MB)"

...

That's just a few ways to do it. I'd recommend either wrapping most of these in to functions or as a multi-class package as most of the data can't be used as-is.

Have another answer? Share your knowledge.