In my recent blog http://www.element14.com/community/community/raspberry-pi/raspberrypi_projects/blog/2014/02/24/raspberry-pi-as-a-lamp-server I described how I went about setting up my Pi as a LAMP server. like most people, once I had got this working, I needed to work out something useful to do with it! here at work we have a couple of servers that we use for developing/testing web code, and these come up and down during the day as new builds are deployed, etc. Its sometimes a pain when they are down so I thought it would be really useful if there was a continually updating page that could show their status.
I decided I would write a simple PHP app which needed to do the following
- Ping the external server
- Display a message indicating whether the server is currently up or down
- Refresh the display
To make it look a bit more interesting, I decided to show an image based on whether the server is up or down. I also decided to monitor two servers at the same time, called 'Dev' (the Development server) and 'Staging' ( a testing server). I also decided to show an image depending on whether the relevant server was up or down.
( I decided to monitor our live servers as well, just to make things a bit more interesting. Of course we have a dedicated team which look after this in our production environment, and we get notified immediately if anything happens to them so this is a bit redundant - I just added them in to the mix here to make the screen look more complete !);
Before doing this, I made sure I could ftp files to the pi (using FileZilla) and also access the PI remotely using Putty. If you don't know how to do this there's load of articles on the web ! (see the links at the bottom of the blog).
In the following sections I'll explain how I wrote the php to accomplish the various functions, and then in the final section explain how I've set up the Pi so that it 'just runs' - I don't have to do anything to it ! I'm not the world's most experienced php developer so there may be better ways of doing this !
Ping the external server
The php function file_get_contents allows the contents of a url to be written to a file. If the URL isn't available it throws an error. So all we need to do is to run this function, and if an error occurs, the site is down. I didn't want to just use ping or wget because sometimes our servers are in a 'holding page - e.g. while a new build is running. When this happens we want to consider the server 'down' - wget and ping will not throw an error, but file_get_contents does, because our holding page process returns a 501 error.
I coded the following to this (note that I have obfuscated the actual url used !)
try { file_get_contents('http://www.myserver.com'); } catch (Exception $e) { //do something here }
At first the above didn't trap an error even though I could see an error being thrown in the server error logs (e.g. at /var/www/logs/apache2/error.log). I found the following advice on the net and inserted this code before and after
I put this at the top of the php code ...
/* * Override the standard error handing so that it will throw an exception that we can trap */ set_error_handler( create_function( '$severity, $message, $file, $line', 'throw new ErrorException($message, $severity, $severity, $file, $line);' ) );
... then I put this at the bottom
/* * reset the error handling */ restore_error_handler();
Finally, I created a variable to hold the result of the server status - e.g.
$devstatus = "up"; try { file_get_contents('http://jive6devcommunity.premierfarnell.net/community'); } catch (Exception $e) { $devstatus = "down"; }
Display a message indicating whether the server is currently up or down
Now we have a variable to indicate whether the server is up or down, I needed a neat way to show it on the screen I could have just put out a message 'Server is up/Down' but wanted something to look a bit neater! I decided that for each server I would display an image to show the status plus some text. To make things more interesting, if the server was down I would change the image randomly to keep the user's attention. I think the following code snippet explains it clearly enough !
/* * Assign image (held as serverdown1.jpg, serverdown2.jpg, etc) * Using static image for up, random one for 'down' */ $serverupImage = "serverup1.jpg"; $randomSuffix = rand(1, 5); $serverdownImage = "serverdown" . $randomSuffix . ".jpg"; // Display appropriate icon and description in a table print '<div style="width: 810px ; margin-left: auto ; margin-right: auto ;">'; print ' <table> '; print '<tr align="center"><th colspan="2" ><h1>Servers\' Status</h1></th></tr>'; // Server name print '<tr>'; print '<th width=400px">'; // If server is down, put name in Red if ($devstatus == "down"){ print '<h2 style="color:red">Dev Server</h2>'; } else { print '<h2>Dev Server</h2>'; } print '</th>'; print '</tr>'; // Decription print '<tr>'; if ($devstatus == "up"){ print '<td><hr><h3>Dev is Up</h3></td>'; } if ($devstatus == "down"){ print '<td><hr><h3 style="color:red">Dev is Down</h3></td>'; } print '</tr>'; // icons print '<tr>'; print ' <td><img src="'; if ($devstatus == "up"){ print $serverupImage; } if ($devstatus == "down"){ print $serverdownImage; } print '">'; print '</td>'; print '</tr>'; print '</table>'; print '</div>';
Refresh the display
A web page will auto refresh if the following code is included in the header : <meta http-equiv="refresh" content="30" > (in this case every 30 seconds)
e.g.
<head> <meta charset="utf-8"> <title>Status of Servers</title> <script type="text/javascript" src="script.js"></script> <meta http-equiv="refresh" content="30" > </head>
Implementing it on the PI
Getting it to run on the PI is fairly straight forward (assuming you've got your LAMP setup running !). I created a separate sub directory (remoteserver) under /var/www and copied all my files into there using FileZilla(i.e. the php file and the images). Don't forget that you will need to make sure that the files can be read by the server - I used chmod to make sure they were accessible - e.g.
cd /var/www/remoteserver sudo chmod 777 *
Once I have done this I can display the page simply by typing 192.168.1.1/remoteserver/serverstatus.php into the browser of any computer on my network (assuming that my Pi's IP Address is 192.168.1.1, and that my php file is serverstatus.php, deployed in directory /var/www/remoteserver).
I want to run this permanently displayed in a screen attached to my Pi, but I don't want to have to load the browser each time I start up the PI. Luckily, its quite easy to configure the browser to open automatically at startup, and also to change the home page of the browser to be my server status url.
Change browser homepage
I'm using the Midori browser (installed on my Pi by default). Open the browser, then click on the Tool menu (the 'cog' icon at the top right hand side). select preferences and it will open a dialog where you can change the home page. Put in the URL that you want the browser to load when it opens. (Note that this isn't strictly required if you are going to do the following step as the initial page is specified there anyway.)
Load browser on startup (Midori)
When the Pi starts up, by default it loads the LXDE page. You need to change this so that instead it loads the browser. this is done by editing file autostart in /etc/xdg/lxsession/LXDE.
sudo nano /etc/xdg/lxsession/LXDE/autostart
Comment out all the lines that are already there and insert the following
# Auto run the browser @xset s off @xset -dpms @xset s noblank @midori -e Fullscreen -a httl://192.168.1.1/remoteserver/serverstatus.php
This will have the dual effect of not loading the desktop when the Pi boots up, and automatically loading Midori in full screen mode with the specified url.
Note that if you want to display the LXDE desktop again the future you will have to reverse this change !
Load browser on startup (Chrome)
I decided to try using chrome - this doesnt require the above to load the browser on startup - instead you can alter the .profile file in the pi user home directory and add the following line at the bottom;
chromium --kiosk --incognito
This will launch Chrome at startup. Note that with Chrome it doesnt seem possible to edit the browser to get to the desktop which means that you MUST be able to ssh to the pi externally (e.g. via Putty) - if you cant do this then don't make the above change as you will be unable to do anything on the Pi !
(hint - take a copy of the disk image with the above commented out ..)
This is what it looks like up and running on the desk !
Running without keyboard and mouse
The Pi is now ready to go, and you don't need a keyboard or mouse attached. You will find that the cursor appears in the middle of the page - luckily you can get rid of this. There are full details at http://raspberrypi.stackexchange.com/questions/10209/how-to-disable-mouse-cursor-on-lxde
- what you have to do is as follows ;
Edit file /etc/X11/xinit/xserverrc and add the -nocursor option to the /usr/bin/X command as shown below;
#!/bin/sh exec /usr/bin/X -nolisten -nocursor tcp "$@"
Without the keyboard, it means that we can neaten up the desktop by mounting the PI using a VESA adaptor on the back of the screen like this - the Pi also acts a useful cable tidy !
We had some fun deciding on images to display if any of the servers are down - as I said earlier we have five available and the app picks one at random - this is my favourite;
Useful Links
Function | Link |
---|---|
Setting up Putty | http://cplus.about.com/od/raspberrypi/a/How-Do-I-Setup-Ssh-On-Raspberry-Pi.htm |
FileZilla | https://filezilla-project.org/ |
Autorun browser on startup | Autorun browser on startup « Raspberry Pi Projects |
How to disable the cursor | raspbian - How to disable mouse cursor on LXDE? - Raspberry Pi Stack Exchange |
PI Vesa mount | RASPBERRY PI, VESA PLATE, CPC - PI-PLATE-CPC - PRO SIGNAL |