When setting up monitoring jobs, there are often predictable time periods in which you want to change the behavior of a script or prevent it from running at all, without having to manually stop/start the monitoring job each time. For instance, you might want to prevent errors and alert emails during routine maintenance windows, or perhaps you’re only interested in site performance on weekdays during regular business hours. We’ve come up with solutions to a few common situations that will help jump start your scripts.
Overview
At the core of all these examples is a small configuration object that sits at the top of the script for quick changes, and a single function that returns true or false depending on whether or not the current time is within a blackout period. The following is some pseudo-code outlining one way in which you might choose to implement these examples in your own scripts. Don’t forget to add in the appropriate maintenance object and isInMaintenance() function from the examples below to make this work.
// The configuration object for the maintenance window var maintenance = {...} // The maintenance function (plug in the appropriate function) var isInMaintenance = function() { ... } var selenium = browserMob.openBrowser(); if(!browserMob.isValidation() && isInMaintenance()) { // Active maintenance window browserMob.log("Is in maintenance!"); } else { // Run normal script browserMob.beginTransaction(); browserMob.beginStep("Step 1"); selenium.open("http://google.com/search?q=website+monitoring"); ... browserMob.endStep(); browserMob.endTransaction(); }
Web Page Check
The most straight forward way to check for a maintenance window is to have Selenium load a web page and look for an element that’s only present during scheduled down time. You’ll want to be careful not to choose something that is also present when the site is really in trouble or you will never get your alerts!
var maintenance = { check: { url: "http://example.com/home", element: "//img[@title=\"maintenance\"]" } } var isInMaintenance = function() { if(maintenance.check && maintenance.check.url != null && maintenance.check.element != null) { selenium.open(maintenance.url); return selenium.isElementPresent(maintenance.element); } return false; }
Multipe Date Ranges
One of the most common requests we get is for a way to handle scheduled maintenance windows. These windows tend to be one-off date ranges decided well in advance of the actual event. Given a set of start/end dates, you could prevent monitoring errors and email alerts during the blackout periods. When setting the dates, don’t forget to include the time zone abbreviation in the argument string or the script will use the local time of the machine it’s running on.
var maintenance = { dates: [ {start: new Date("05/12/2010 23:00 PDT"), end: new Date("05/13/2010 02:30 PDT")}, {start: new Date("05/24/2010 23:00 PDT"), end: new Date("05/25/2010 02:30 PDT")} ] } var isInMaintenance = function() { var now = new Date(), nowTime = now.getTime(), maintenanceWindows = []; // Check for maintenance date ranges if(maintenance.dates && maintenance.dates.length) { maintenanceWindows = maintenance.dates; } for(var i in maintenanceWindows) { var m = maintenanceWindows[i]; if(nowTime >= m.start.getTime() && nowTime < m.end.getTime()) { return true; } } return false; }
Days of the Week
Here’s an example for blacking out specific days of the week. This will allow you to create a script that, for example, monitors on Mondays, Wednesdays, and Fridays, or only on business days. Simply provide a time zone offset, which is the number of minutes your time zone deviates from coordinated universal time (a.k.a. UTC, GMT, Zulu time), and the days of the week you don’t want to run the script (from 0-6, where 0 is Sunday, 1 is Monday, etc.).
var maintenance = { timezoneOffset: 240, // UTC offset in minutes (eg: NYC (GMT-4) is 4 * 60 days: [0, 6] // Sunday = 0, Saturday = 6 } var isInMaintenance = function(){ var now = new Date(), nowTime = now.getTime(), timezoneOffset = maintenance.timezoneOffset || 0, localTimezoneOffset = now.getTimezoneOffset(), timezoneDiff = localTimezoneOffset - timezoneOffset; // Check for full blackout days (such as weekends) if(maintenance.days != null && maintenance.days.length) { var targetDate = new Date(nowTime + (timezoneDiff * 60 * 1000)), targetDay = targetDate.getDay(); for(var i in maintenance.days) { if(maintenance.days[i] == targetDay) { return true; } } } return false; }
Time of Day
This example shows how you can have a daily blackout range. This code will parse the start/end strings into a daily time range adjusted to the target time zone. Use this if you only want to monitor during banker’s hours, or if you want to prevent a script from running while your database is backing up.
var maintenance = { timezoneOffset: 240, // UTC offset in minutes (eg: NYC (GMT-4) is 4 * 60 hours: {start: "23:30", end: "07:30"} } var isInMaintenance = function(startTime, endTime, offset) { var offset = maintenance.timezoneOffset || 0; var now = new Date(); var nowTime = now.getTime(); var maintenanceWindows = []; var toUtc = function(localTime) { var chunks = localTime.toString().split(":"); var h = parseInt(chunks[0], 10); var m = parseInt(chunks[1], 10) || 0; var d = new Date(); d.setHours(h); d.setMinutes(m + offset); return d.getHours() + ":" + d.getMinutes(); } var sH, eH, sM, eM; startTime = toUtc(maintenance.hours.start); var chunks = startTime.toString().split(":"); sH = parseInt(chunks[0], 10); sM = parseInt(chunks[1], 10) || 0; endTime = toUtc(maintenance.hours.end); chunks = endTime.toString().split(":"); eH = parseInt(chunks[0], 10); eM = parseInt(chunks[1], 10) || 0; var startDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), sH, sM, 0, 0); var endDate = new Date(now.getFullYear(), now.getMonth(), now.getDate(), eH, eM, 0, 0); if(startDate.getTime() <= endDate.getTime()) { // Single range mid-day maintenanceWindows.push({start: startDate, end: endDate}); } else { // Date wraps, which means two blackout ranges in a single day var morning = new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0, 0), midnight = new Date(morning.getTime() + (24 * 60 * 60 * 1000)); maintenanceWindows.push({ start: morning, end: endDate }); maintenanceWindows.push({ start: startDate, end: midnight }); } for(var i in maintenanceWindows) { var m = maintenanceWindows[i]; if(nowTime >= m.start.getTime() && nowTime < m.end.getTime()) { return true; } } return false; }
Now, a few of you might have noticed that the above examples are compatible with one another; you can mix-and-match them as you see fit. Just combine the various maintenance object fields into one config object, combine the contents of all the maintenance methods you want to use (just watch not to overwrite the variable declarations), and you can create something that fits just about any situation.
downtime · javascript · maintenance · maintenance windows · Monitoring · RBU · Scripting · scripts
No comments yet.
Leave a Reply
<< dynaTrace shows how to track AJAX performance with Selenium
