My Raspberry Pi Projects
  1. - ie. without using a monitor or keyboard for setup/control -> 
  2. - control an LED on the RasPi via web -> 
  3. Monitor - CPU load, temp, procs, mem, network traffic, etc -----> 
  4. ...

  3. Monitor
I'd like to monitor the RasPi - CPU load, temperature, # processes, memory, network traffic, etc.  This project describes a fairly simple approach, one that I (or you) can play with and customize as desired:
  1. The user displays a web page from the RasPi's webserver.  Javascript on the page automatically starts polling a CGI on the RasPi.
  2. The CGI calls a C program which collects up the counters on the RasPi - some from SNMP and some from calls to command-line tools - and returns them to the browser.
  3. The web page displays them on timeseries plots.
There are only 6 files involved so it's fairly easy to see how it works and modify as you wish - say to add something you would like to monitor on your Raspi.
Here is a sample screenshot of the current version:
  1. This was sampling at 1-minute intervals.  If you select a longer sample interval from the drop-down list, it should lower the overhead this monitor places on the RasPi.  Presently, at 1-minute sample intervals, it's around 10% and incurring a negligible load on the LAN.
  2. There would appear to be a memory leak (the steadily decreasing "Free Memory").  Though this may be lazy garbage collection by the RasPi.  It seems to level off around 150MB.
  3. The "Response Time" is the response time that this UI sees from it's requests to the RasPi for a new sample.  The green line is how long the server took.  Again, the CGI program calls a C program which:
    • samples the clock when invoked (t0)
    • collects the current counts from SNMP and command-line tools
    • samples the clock again (t1) just before returning the results to the Javascript code running in the browser
    It returns t1-t0 to the UI, which is plotted as the green line.  The red line is the total time that the Javascript code (running in the browser) sees.  It includes the network delay.  So, the difference between it and the server delay (t1-t0), is probably mostly your network delay.  Here on the right, I was surfing the web from my laptop and that's what probably caused many of the the spikes in apparent network delay seen by this monitor.  Both my laptop and this monitor shared the same WiFi network.
  4. You can see the temperature go up and down as you exercise the RasPi. :-)
Nueva Gorgona, 24 Sep 2013
I just happened to try displaying this monitor on an iPod Touch 5G (which has the Retina display).  It was surprisingly readable - better than this photo indicates. This was taken after the RasPi had been running for about 8 hours.  The plots show 300 samples.  That is, they are 300 samples wide.  These were at 1 minute per sample interval so 300 minutes or 5 hours of samples are shown.
I logged into the RasPi from my laptop and used Geany a bit to create some activity in the plots.  Note that the counter at the bottom (showing "..." here) is a countdown (in seconds) to the next time this monitor will make a request to the RasPi for the next set of counts.  Then the counter (generally) shows "..." while it is waiting until the counts have been returned.  So, if this counter is either counting down or showing "..." for short periods (see the "Overall" response time on your "Response Time" plot), then things are probably running normally.
I wonder why the temperature went up for a while on the right.  A mystery.
To setup the Raspi, I first installed snmp and snmpd on it as follows:
sudo apt-get update
sudo apt-get install snmpd
sudo apt-get install snmp
sudo /etc/init.d/snmpd restart
Man-O-War Cay, 9 Jan 2015
Dale writes to say that he needed to also install “snmp-mibs-downloader” to avoid error messages during the install.  Thanks Dale.

Then, in /etc/snmp/snmpd.conf, I uncommented the line:
#rocommunity public localhost
to become.. well:
rocommunity public localhost

If you want to install the more friendly MIBs to use with snmp, this note was helpful.  For my purposes though, the list of OIDs found in this note and especially this one were VERY helpful.  There is also Cisco's awesome reference.
Gainesville, 15 Oct 2015
I found it necessary to reboot the Raspi for the snmp update to take effect.

Then, to try the snmp client on the RasPi, in a command-line window on the Raspi:
snmpget -v 1 -c public localhost .
which should return something like:
UCD-SNMP-MIB::memTotalFree.0 = INTEGER: 150412 kB
iso. = INTEGER: 843492

For the charting, I used Flot.
If you're interested in programming it, their Real-time updates example was helpful to understanding their API.  Right click on that page and "View Page Source".  Also, here is their decent description of the API.
Their library is included in my zip file.  From my zip file, copy the flot directory (containing jquery.flot.min.js and jquery.min.js) to /var/www on your RasPi and then set permissions:
sudo chmod +x /var/www/flot
chmod +r /var/www/flot/*
My code
My code is still something of "a work in progress"...
Here is the current version:
Gainesville, 15 Oct 2015
Thank you Dale and Ron for pointing out bugs.

Here are the components - either in that zip file or compiled from them:
Armenia, Colombia, 6 Apr 2019
The default location for the HTML on Apache2 is now /var/www/html/.  It was /var/www/ when I originall did this.  I've updated the table below.

WhatNamedWhere they go on the RasPi
1. The web page that calls the CGI on the RasPi and presents the results to the user mikesmon.html
2. The CGI that calls a C program to collect the counts mikesmon.cgi /usr/lib/cgi-bin/mikesmon.cgi
3. The source code for the C program that collects the counts from SNMP and command-line programs mikesmon.c
You can put these anywhere, let's say in a folder called mon in your home directory on the RasPi
4. The executable from compiling the source code in #3 ("gcc -o mikesmon mikesmon.c") mikesmon /usr/bin/mikesmon
5. The chart-drawing libraries jquery.min.js

To install and run my code:
  1. Copy the files from the zip file to their locations on the RasPi as indicated above.  Set the permissions as necessary.
    Gainesville, 15 Oct 2015
    These should do it:
    sudo chmod 666 /var/www/mikesmon.html
    sudo chmod 544 /var/www/mikesmon-favicon.png
    sudo chmod 755 /usr/lib/cgi-bin/mikesmon.cgi
    sudo chmod 544 /home/pi/mon/*
    sudo chmod 755 /var/www/flot
    sudo chmod 755 /var/www/flot/*
    Armenia, Colombia, 6 Apr 2019
    Well, the good news is that this code still works after all these years.  The (minor, so far) bad news is that apparently you now need to do the following to enable cgi's:
    cd /etc/apache2/mods-enabled
    sudo ln -sT ../mods-available/cgi.load cgi.load
    I am setting up monitoring on my RPi Beowulf cluster.

  2. Change the IP address in /var/www/mikesmon.html (around line 81) to that of your RasPi.  You can use:
    on your RasPi to find out it's IP address.
    Armenia, Colombia, 6 Apr 2019
    It is very important that you use the IP address (the same one as above) when you address the page in your browser - NOT the hostname.  Otherwise, the timeseries won't be shown on the plots and you'll see an error in your browser View>Developer>Developer Tools console about: "No 'Access-Control-Allow-Origin' header"

  3. Say you have created a folder in your home directory called mon, and copied the 3 files, mikesmon.c, myutils.h, and OIDs.h, to it.  Then to compile the C program:
    cd ~/mon
    gcc -o mikesmon mikesmon.c
    and test it:
    You should see something like:

    Gainesville, 18 Oct 2015
     If instead, you see errors such as the following ...
    Error in packet
    Reason: (noSuchName) There is no such variable name in this MIB.
    Failed object: iso.
    Error in packet
    Reason: (noSuchName) There is no such variable name in this MIB.
    Failed object: iso.
    Error in packet
    Reason: (noSuchName) There is no such variable name in this MIB.
    Failed object: iso.
    Error in packet
    Reason: (noSuchName) There is no such variable name in this MIB.
    Failed object: iso.
    it is because the C code is asking SNMP for WiFi counts (what my collection code defaults to) but there is no WiFi interface configured.  If you are using an Ethernet interface, please compile mikesmon.c with -D_IF=2, e.g.
    gcc -o mikesmon mikesmon.c -D_IF=2
    This causes the collection code to ask SNMP for counts on the Ethernet interface.  If you have neither (I guess you could be using a browser on the RasPi to display the monitor), use -D_IF=1, e.g.
    gcc -o mikesmon mikesmon.c -D_IF=1
  4. Then move the executable to /usr/bin and set it's permission as follows:
    sudo mv mikesmon /usr/bin/
    chmod +x /usr/bin/mikesmon
    To test it from the CGI, invoke it using a browser (from anywhere on your LAN with the RasPi on it): (substituting the IP address of your RasPi)
    Again, you should see something like the following, now in your browser window:
    If you don't, look at the RasPi's web server logs in /var/log/apache2/.
  5. Finally, invoke the UI from your browser (again, anywhere on the same network as the Raspi): (substituting the IP address of your RasPi)
    You should see something like the screen shot shown above.  If not, look at the RasPi's web server logs in /var/log/apache2/.

To do
  1. Make the HTTP request to the server asynchronous.  Right now, the UI locks up while the Javascript code is making the request to the RasPi for the next sample.  So, it is not able to respond to user input for several seconds every sample interval - if the user clicks on the Start/Pause button or tries to change the "Sample interval" from the drop-down list.  There is an asynchronous way of making the request.. I just need to implement it.
  2. Shrink the size of the HTML file.  Probably can be done be redoing the switch statements.
-- FIN --