Skip to content

Commit

Permalink
Completed the mechanism for sending alerts on Critical/Warning states
Browse files Browse the repository at this point in the history
when polling power and/or sensor via SNMP.   Added as config screen items
so it is completely optional.

Fixed #1112
  • Loading branch information
samilliken committed Mar 4, 2019
1 parent c6a0ae6 commit d4a083f
Show file tree
Hide file tree
Showing 3 changed files with 183 additions and 7 deletions.
89 changes: 86 additions & 3 deletions classes/Device.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -2335,9 +2335,13 @@ static function UpdateSensors($CabinetID=null){
global $dbh;

// If CabinetID isn't specified try to update all sensors for the system
$cablimit=(is_null($CabinetID))?"":" AND Cabinet=$cab->CabinetID";
$sql="SELECT DeviceID FROM fac_Device WHERE DeviceType=\"Sensor\" AND
PrimaryIP!=\"\" AND TemplateID>0 AND SNMPFailureCount<3$cablimit;";
$cablimit=(is_null($CabinetID))?"":" AND a.Cabinet=$cab->CabinetID";
$sql="SELECT a.DeviceID, b.DataCenterID, a.Cabinet, b.Location, a.BackSide, c.Name FROM fac_Device a, fac_Cabinet b, fac_DataCenter c WHERE
DeviceType=\"Sensor\" AND PrimaryIP!=\"\" AND TemplateID>0 AND SNMPFailureCount<3 AND a.Cabinet=b.CabinetID AND
b.DataCenterID=c.DataCenterID $cablimit order by c.Name ASC, b.Location ASC;";

$AlertList = "";
$htmlMessage = "";

foreach($dbh->query($sql) as $row){
if(!$dev=Device::BasicTests($row['DeviceID'])){
Expand Down Expand Up @@ -2392,6 +2396,85 @@ static function UpdateSensors($CabinetID=null){
error_log( "UpdateSensors::PDO Error: {$info[2]} SQL=$insertsql" );
return false;
}

// Ignore rear sensors
if ( $row['BackSide'] == 0 && $config->ParameterArray["SensorAlertsEmail"] == "enabled" ) {
if ( $temp >= $config->ParameterArray["TemperatureRed"] ) {
$AlertList .= sprintf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $row["Name"], $row["Location"], __("Temperature"), $temp, __("Critical"));
} elseif ( $temp >= $config->ParameterArray["TemperatureYellow"] ) {
$AlertList .= sprintf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $row["Name"], $row["Location"], __("Temperature"), $temp, __("Warning"));
}

if ( ( $humidity >= $config->ParameterArray["HumidityRedHigh"] ) || ( $humidity <= $config->ParameterArray["HumidityRedLow"] ) ) {
$AlertList .= sprintf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $row["Name"], $row["Location"], __("Humidity"), $temp, __("Critical"));
} elseif ( ( $humidity >= $config->ParameterArray["HumidityYellowHigh"] ) || ( $humidity <= $config->ParameterArray["HumidityYellowLow"] ) ) {
$AlertList .= sprintf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $row["Name"], $row["Location"], __("Humidity"), $temp, __("Warning"));
}
}
}

if ( $config->ParameterArray["SensorAlertsEmail"] == "enabled" && $AlertList != "" ) {
// If any port other than 25 is specified, assume encryption and authentication
if($config->ParameterArray['SMTPPort']!= 25){
$transport=Swift_SmtpTransport::newInstance()
->setHost($config->ParameterArray['SMTPServer'])
->setPort($config->ParameterArray['SMTPPort'])
->setEncryption('ssl')
->setUsername($config->ParameterArray['SMTPUser'])
->setPassword($config->ParameterArray['SMTPPassword']);
}else{
$transport=Swift_SmtpTransport::newInstance()
->setHost($config->ParameterArray['SMTPServer'])
->setPort($config->ParameterArray['SMTPPort']);
}

$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::NewInstance()->setSubject( __("Data Center Sensor Alerts Report" ) );

// Set from address
try{
$message->setFrom($config->ParameterArray['MailFromAddr']);
}catch(Swift_RfcComplianceException $e){
$error.=__("MailFrom").": <span class=\"errmsg\">".$e->getMessage()."</span><br>\n";
}

// Add data center team to the list of recipients
try{
$message->addTo($config->ParameterArray['FacMgrMail']);
}catch(Swift_RfcComplianceException $e){
$error.=__("Facility Manager email address").": <span class=\"errmsg\">".$e->getMessage()."</span><br>\n";
}

$logofile=getcwd().'/images/'.$config->ParameterArray["PDFLogoFile"];
$logo=$message->embed(Swift_Image::fromPath($logofile)->setFilename($logofile));

$style = "
<style type=\"text/css\">
@media print {
h2 {
page-break-before: always;
}
}
</style>";


$htmlMessage = sprintf( "<!doctype html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><title>%s</title>%s</head><body><div id=\"header\" style=\"padding: 5px 0;background: %s;\"><center><img src=\"%s\"></center></div><div class=\"page\"><p>\n", __("Data Center Sensor Alerts"), $style, $config->ParameterArray["HeaderColor"], $logo );

$htmlMessage .= sprintf( "<table>\n<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", __("Data Center"), __("Cabinet"), __("Sensor"), __("Value"), __("Alert Level") );


// Add the alerts to the html message, now
$htmlMessage .= $AlertList . "</table>\n";;

$message->setBody($htmlMessage,'text/html');

try {
$result = $mailer->send( $message );
} catch( Swift_RfcComplianceException $e) {
$error .= "Send: " . $e->getMessage() . "<br>\n";
} catch( Swift_TransportException $e) {
$error .= "Server: <span class=\"errmsg\">" . $e->getMessage() . "</span><br>\n";
}
}

return true;
Expand Down
94 changes: 90 additions & 4 deletions classes/PowerDistribution.class.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,16 @@ function LogManualWattage($Wattage){
function UpdateStats(){
global $config;
global $dbh;

$AlertList = "";
$htmlMessage = "";

$sql="SELECT a.PDUID, d.SNMPVersion, b.Multiplier, b.OID1,
b.OID2, b.OID3, b.ProcessingProfile, b.Voltage, c.SNMPFailureCount FROM fac_PowerDistribution a,
fac_CDUTemplate b, fac_Device c, fac_DeviceTemplate d WHERE a.PDUID=c.DeviceID and a.TemplateID=b.TemplateID
AND a.TemplateID=d.TemplateID AND b.Managed=true AND c.PrimaryIP>'' and c.SNMPFailureCount<3";
$sql="SELECT a.PDUID, a.BreakerSize, b.Voltage, b.Amperage, d.SNMPVersion, b.Multiplier, b.OID1, b.OID2, b.OID3,
b.ProcessingProfile, b.Voltage, c.Label, c.SNMPFailureCount, e.Location, f.Name
FROM fac_PowerDistribution a, fac_CDUTemplate b, fac_Device c, fac_DeviceTemplate d, fac_Cabinet e, fac_DataCenter f
WHERE a.PDUID=c.DeviceID and a.TemplateID=b.TemplateID AND a.TemplateID=d.TemplateID and a.CabinetID=e.CabinetID and
e.DataCenterID=f.DataCenterID AND b.Managed=true AND c.PrimaryIP>'' and c.SNMPFailureCount<3
ORDER BY f.Name ASC, e.Location ASC";

// The result set should have no PDU's with blank IP Addresses or SNMP Community, so we can forge ahead with processing them all
foreach($this->query($sql) as $row){
Expand Down Expand Up @@ -450,6 +455,22 @@ function UpdateStats(){
$info=$dbh->errorInfo();
error_log("PowerDistribution::UpdateStats::PDO Error: {$info[2]} SQL=$sql");
}

$maxWatts = $row["Voltage"] * $row["Amperage"];
if ( $row["BreakerSize"] == 3 ) {
$maxWatts *= 1.732;
}

// Derate everything 80% per standard
$maxWatts += 0.8;

if ( $config->ParameterArray["PowerAlertsEmail"] == "enabled" ) {
if ( $watts >= $config->ParameterArray["PowerRed"] / 100 * $maxWatts ) {
$AlertList .= sprintf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $row["Name"], $row["Location"], $row["Label"], $watts, __("Critical"));
} elseif ( $watts >= $config->ParameterArray["PowerYellow"] / 100 * $maxWatts ) {
$AlertList .= sprintf( "<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>\n", $row["Name"], $row["Location"], $row["Label"], $watts, __("Warning"));
}
}

$this->PDUID=$row["PDUID"];
if($ver=$this->GetSmartCDUVersion()){
Expand All @@ -459,6 +480,71 @@ function UpdateStats(){
error_log("PowerDistribution::UpdateStats::PDO Error: {$info[2]} SQL=$sql");
}
}

}

if ( $config->ParameterArray["PowerAlertsEmail"] == "enabled" && $AlertList != "" ) {
// If any port other than 25 is specified, assume encryption and authentication
if($config->ParameterArray['SMTPPort']!= 25){
$transport=Swift_SmtpTransport::newInstance()
->setHost($config->ParameterArray['SMTPServer'])
->setPort($config->ParameterArray['SMTPPort'])
->setEncryption('ssl')
->setUsername($config->ParameterArray['SMTPUser'])
->setPassword($config->ParameterArray['SMTPPassword']);
}else{
$transport=Swift_SmtpTransport::newInstance()
->setHost($config->ParameterArray['SMTPServer'])
->setPort($config->ParameterArray['SMTPPort']);
}

$mailer = Swift_Mailer::newInstance($transport);
$message = Swift_Message::NewInstance()->setSubject( __("Data Center Power Alerts Report" ) );

// Set from address
try{
$message->setFrom($config->ParameterArray['MailFromAddr']);
}catch(Swift_RfcComplianceException $e){
$error.=__("MailFrom").": <span class=\"errmsg\">".$e->getMessage()."</span><br>\n";
}

// Add data center team to the list of recipients
try{
$message->addTo($config->ParameterArray['FacMgrMail']);
}catch(Swift_RfcComplianceException $e){
$error.=__("Facility Manager email address").": <span class=\"errmsg\">".$e->getMessage()."</span><br>\n";
}

$logofile=getcwd().'/images/'.$config->ParameterArray["PDFLogoFile"];
$logo=$message->embed(Swift_Image::fromPath($logofile)->setFilename($logofile));

$style = "
<style type=\"text/css\">
@media print {
h2 {
page-break-before: always;
}
}
</style>";


$htmlMessage = sprintf( "<!doctype html><html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><title>%s</title>%s</head><body><div id=\"header\" style=\"padding: 5px 0;background: %s;\"><center><img src=\"%s\"></center></div><div class=\"page\"><p>\n", __("Data Center Power Alerts"), $style, $config->ParameterArray["HeaderColor"], $logo );

$htmlMessage .= sprintf( "<table>\n<tr><th>%s</th><th>%s</th><th>%s</th><th>%s</th><th>%s</th></tr>\n", __("Data Center"), __("Cabinet"), __("CDU"), __("Value"), __("Alert Level") );


// Add the alerts to the html message, now
$htmlMessage .= $AlertList . "</table>\n";;

$message->setBody($htmlMessage,'text/html');

try {
$result = $mailer->send( $message );
} catch( Swift_RfcComplianceException $e) {
$error .= "Send: " . $e->getMessage() . "<br>\n";
} catch( Swift_TransportException $e) {
$error .= "Server: <span class=\"errmsg\">" . $e->getMessage() . "</span><br>\n";
}
}
}

Expand Down
7 changes: 7 additions & 0 deletions db-18.02-to-19.01.sql
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ INSERT INTO fac_Config set Parameter='ReservationExpiration', Value='0', UnitOfM
CREATE INDEX ObjectID on fac_GenericLog (ObjectID);
CREATE INDEX ObjectTime on fac_GenericLog (ObjectID, Time);

--
-- Add in new configuration items for Alert Emails
--

INSERT INTO fac_Config set Parameter='PowerAlertsEmail', Value='disabled', UnitOfMeasure='Enabled/Disabled', ValType='string', DefaultVal='disabled';
INSERT INTO fac_Config set Parameter='SensorAlertsEmail', Value='disabled', UnitOfMeasure='Enabled/Disabled', ValType='string', DefaultVal='disabled';

--
-- Bump up the database version (uncomment below once released)
--
Expand Down

0 comments on commit d4a083f

Please sign in to comment.