My Raspberry Pi Projects |
Contact: |
- Headless Setup - ie. without using a monitor or keyboard for setup/control ->
- Hello World Remote Controller - control an LED on the RasPi via web ->
- Monitor - CPU load, temp, procs, mem, network traffic, etc ----->
- ...
3. Monitor |
- The user displays a web page from the RasPi's webserver. Javascript on the page automatically starts polling a CGI on the RasPi.
- 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.
- The web page displays them on timeseries plots.
Here is a sample screenshot of the current version:

- 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.
- 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.
- 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
- 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.

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
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 .1.3.6.1.4.1.2021.4.11.0
which should return something like:
UCD-SNMP-MIB::memTotalFree.0 = INTEGER: 150412 kB
or
iso.3.6.1.4.1.2021.4.11.0 = 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 codechmod +r /var/www/flot/*
My code is still something of "a work in progress"...
Here is the current version: raspi-mon-19Oct2015.zip.
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.
What | Named | Where 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 mikesmon-favicon.png |
/var/www/html/mikesmon.html /var/www/html/mikesmon-favicon.png |
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 myutils.h OIDs.h |
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 jquery.flot.min.js |
/var/www/flot/jquery.min.js /var/www/flot/jquery.flot.min.js |
To install and run my code:
- Copy the files from the zip file to their locations on the RasPi as indicated above.
Set the permissions as necessary.
Gainesville, 15 Oct 2015These 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 2019Well, 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-enabledI am setting up monitoring on my RPi Beowulf cluster.
sudo ln -sT ../mods-available/cgi.load cgi.load
- Change the IP address in /var/www/mikesmon.html (around line 81) to that of your RasPi.
You can use:
ifconfigon your RasPi to find out it's IP address.Armenia, Colombia, 6 Apr 2019It 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"
- 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 ~/monand test it:
gcc -o mikesmon mikesmon.c
./mikesmonYou should see something like:H,raspberrypi,T,43312,CRU,7567,CRN,0,CRS,4582,CRI,1160245,TRF,377540,SP,80,NIO3,448556,NOO3,390299,NIE3,0,NOE3,0,RT,5575,
Gainesville, 18 Oct 2015If 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.3.6.1.2.1.2.2.1.10.3
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: iso.3.6.1.2.1.2.2.1.16.3
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: iso.3.6.1.2.1.2.2.1.14.3
Error in packet
Reason: (noSuchName) There is no such variable name in this MIB.
Failed object: iso.3.6.1.2.1.2.2.1.20.3
H,raspberrypi,T,39007,CRU,2057,CRN,0,CRS,2078,CRI,498879,TRF,123456,SP,106,NIO3,0,NOO3,0,NIE3,0,NOE3,0,RT,215,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=2This 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 - Then move the executable to /usr/bin and set it's
permission as follows:
sudo mv mikesmon /usr/bin/To test it from the CGI, invoke it using a browser (from anywhere on your LAN with the RasPi on it):
chmod +x /usr/bin/mikesmonhttp://192.168.0.103/cgi-bin/mikesmon.cgi (substituting the IP address of your RasPi)Again, you should see something like the following, now in your browser window:H,raspberrypi,T,44388,CRU,6268,CRN,0,CRS,4118,CRI,1009417,TRF,377276,SP,80,NIO3,412078,NOO3,384715,NIE3,0,NOE3,0,RT,5747,If you don't, look at the RasPi's web server logs in /var/log/apache2/. - Finally, invoke the UI from your browser (again, anywhere on the same
network as the Raspi):
http://192.168.0.103/mikesmon.html (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
- 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.
- Shrink the size of the HTML file. Probably can be done be redoing the switch statements.