I found a very cool web site monitoring utility today and set it up on my account. I take no credit for this other than to help explain it a little better. Here is the author's site:
http://joeriks.com/2011/05/17/coding-my-own-automated-web-page-tests-with-google-apps-script-and-a-spreadsheet/Updated 7/20/2012: Added another column so a single error doesn't trigger an email now the URL must fail twice in a row before an email is sent out.
The instructions were good, but not perfect so here are some improvements to help you along.
Create a new Google Spreadsheet as follows:
Then, Add columns A, B, and C. Notice that you can check the response-code, and look if text exists in the response or if text doesn't exist as shown by these examples:
Choose the script editor (later you can view your scripts with the script manager):
Paste in the code
Rename the script
Give it a name and then hit the save button
Now you can test that it runs. Click the Run/checkUrls function as shown:
Now you have to authorize that the script is allowed to email and update the spreadsheet. Hit authorize:
If another confirmation comes up, just close it. Click the Run/checkUrls function again:
Now you can close the script tab (or window) and go back to the spreadsheet window and you should see the spreadsheet (notice that I hovered over column E to show the contents of what was captured):
Now click Resources/All your triggers... and then add new trigger on the window that follows.
Add a trigger as shown (time-driven). This will allow the script to run continually and update the spreadsheet when it's not open in a browser (very cool!). Save it and...
That's it! You now have a functional spreadsheet which will monitor all of your websites and email you if there is an issue.
Enjoy.
Code follows:
function isCellEmpty(cellData) {
return typeof(cellData) == "string" && cellData == "";
}
function checkUrls() {
// The code below iterates over rows in a sheet and uses the value in
// column A as an url, requests it and puts the response code in column B
// and the request string as the comment
var doc = SpreadsheetApp.getActiveSpreadsheet();
var cell = doc.getRange('a1');
var mailMessage = "";
// leftmost resultcolumn
var resultColumn = 3;
cell.offset(0,resultColumn).setValue(new Date());
cell.offset(0,resultColumn+1).setValue("Content type");
//20120704 mhf
cell.offset(0,resultColumn+2).setValue("Success Prior Run?");
cell.offset(0,resultColumn+3).setValue("Success?");
cell.offset(0,resultColumn+4).setValue("Seconds");
cell.offset(0,resultColumn+5).setValue("Comment");
for (var i = 1; i < 20; ++i)
{
var cellData = cell.offset(i,0).getValue();
if (!isCellEmpty(cellData))
{
var command = cell.offset(i,1).getValue();
var optionData = cell.offset(i,2).getValue();
if (optionData=="") optionData="{}";
var options = Utilities.jsonParse(optionData);
var hasError = false;
var startTime = new Date();
if (command=="" | command=="GET")
{
var responseCode = 404;
var requestContentText = "";
var results = "";
var headers;
var requestType ="";
var contentType = "";
var expectedResponseCode = 200;
if (options["response-code"]!=undefined)
expectedResponseCode = options["response-code"];
try
{
var response = UrlFetchApp.fetch(cellData);
responseCode = response.getResponseCode();
requestContentText = response.getContentText();
headers = response.getHeaders();
if (headers!=undefined)
contentType=headers["Content-Type"].toLowerCase();
}
catch (e)
{
requestContentText = e.message;
}
cell.offset(i,resultColumn).setValue(responseCode);
if (responseCode!=expectedResponseCode)
{
hasError = true;
results += "Expected response code: " + expectedResponseCode;
}
if (contentType.indexOf("html")!=-1)
cell.offset(i,resultColumn).setComment(requestContentText);
else
cell.offset(i,resultColumn).setComment("");
cell.offset(i,resultColumn+1).setValue(contentType);
// print results in column
var colOffset = resultColumn+5;
//// not contain the word ERROR
//var containsError = (requestContentText.toLowerCase().indexOf("error") != -1);
////cell.offset(i,colOffset).setValue("Error: " + containsError);
//if (containsError)
//{
// results += "Error found. ";
// hasError = true;
//}
if (options["should-contain"]!=undefined)
{
// not contain the word ERROR
var shouldContain = options["should-contain"].toLowerCase();
var doesContain = (requestContentText.toLowerCase().indexOf(shouldContain) != -1);
if (!doesContain)
{
results += "Not found: " + options["should-contain"] + ". ";
hasError = true;
}
}
if (options["should-not-contain"]!=undefined)
{
var shouldNotContain = options["should-not-contain"].toLowerCase();
var doesContain = (requestContentText.toLowerCase().indexOf(shouldNotContain) != -1);
if (doesContain)
{
results += "Found: " + options["should-not-contain"] + ". ";
hasError = true;
}
}
cell.offset(i,colOffset).setValue(results);
}
// timer
var endTime = new Date();
var timeDiff = endTime-startTime;
// set the prior success column 20120704 mhf
cell.offset(i,resultColumn+2).setValue(cell.offset(i,resultColumn+3).getValue());
cell.offset(i,resultColumn+2).setBackgroundColor(cell.offset(i,resultColumn+3).getBackgroundColor());
// success? (no errors)
cell.offset(i,resultColumn+3).setValue(!hasError);
// Only show an error if it happens 2 times in a row
var priorStatus = cell.offset(i,resultColumn+2).getValue();
var currStatus = cell.offset(i,resultColumn+3).getValue();
if (hasError && currStatus == false && priorStatus == false)
{
cell.offset(i,resultColumn+3).setBackgroundColor("red");
mailMessage += "ERROR on " + cellData + "\n" +
results +
" actual response code: " + responseCode + "\n" +
"request content: " + requestContentText + "\n";
}
else
cell.offset(i,resultColumn+3).setBackgroundColor("green");
// time spent (in seconds)
cell.offset(i,resultColumn+4).setValue(timeDiff/1000);
}
else
{
break;
}
}
if (mailMessage!="")
{
MailApp.sendEmail("spam@mitchellfeinstein.com", "ERROR on your web ", mailMessage);
}
}
function getTime()
{
var startTime = new Date();
Browser.msgBox(startTime);
var endTime = new Date();
var timeDiff = endTime-startTime;
Browser.msgBox(timeDiff);
}