The notify() method in UpdaterStatus is called from ServerUpdate.
It can use the Entity Manager and configuration references created when UpdaterStatus was initalised.
The notification in phpServerMon and sfServermon support:
$message = \Swift_Message::newInstance();
$message->setSubject($this->server->parseMessage($this->status_new, 'email_subject'))
->setFrom($this->config['email_from_email'])
->setTo('johnr@reidyint.com')
->setBody($this->server->parseMessage($this->status_new, 'email_body'));
$this->mailer->send($message);
}
This version has a hard coded recipient email address, the users to notify are specified in the users table - which is document in a future post in this series.
- Email.
- Logging.
- SMS - implemented as a seperate bundle.
These are enabled (and checked for here, in the application configuration).
Also each server can be specified as supporting any of the 3 methods to notify:
- Always - everytime the status is checked - as a 'heartbeat'.
- If server is offline.
- If server status has changed.
These are checked for first:
public function notify() {
if ($this->config['email_status'] == false && ! $this->config['config_status'] == false && $this->config['log_status'] == false) {
//nothing to log;
return;
}
$notify = false;
$logWarning = false;
switch($this->config['alert_type']) {
case 'always':
if($this->status_new == 'off') {
// server is offline. we are in error state.
$notify = true;
}
break;
case 'offline':
// only send a notification if the server goes down for the first time!
if($this->status_new == 'off' && $this->status_org == 'on') {
$notify = true;
}
break;
case 'status':
if($this->status_new != $this->status_org) {
// status has been changed!
$notify = true;
}
break;
}
if(!$notify && !$logWarning) {
return false;
}
Log Notification:
Log notification is simply created a new log entity and saving it to the database:
if($this->config['log_status']) {
$log = new MonitorLog();
$log->setServer($this->server);
$log->setType('status');
$log->setMessage('status');
$log->setDateTime(new \DateTime());
$log->setuserId(0);
$log->setMessage($this->server->parseMessage($this->status_new, 'sms'
, array('label'=>$this->server->getLabel()
, 'ip'=>$this->server->getIp()
, 'port'=>$this->server->getPort()
, 'error'=>$this->server->getError())
));
$this->em->persist($log);
$this->em->flush();
phpServerMon had the parseMessage in a utility class, however I have moved it to the server entity, as I thought it made sense for an entity to know how to generate a status message for itself.
The parseMessage method:
public function parseMessage($status, $type, $vars)
{
$notifications = array(
'off_sms' => 'Server \'%LABEL%\' is DOWN: ip=%IP%, port=%PORT%. Error=%ERROR%',
'off_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is DOWN',
'off_email_body' => "Failed to connect to the following server:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
'on_sms' => 'Server \'%LABEL%\' is RUNNING: ip=%IP%, port=%PORT%',
'on_email_subject' => 'IMPORTANT: Server \'%LABEL%\' is RUNNING',
'on_email_body' => "Server '%LABEL%' is running again:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Date: %DATE%",
'warn_sms' => 'Server \'%LABEL%\' needs ATTENTION: ip=%IP%, port=%PORT%. Error=%ERROR%',
'warn_email_subject' => 'IMPORTANT: Server \'%LABEL%\' need ATTENTION',
'warn_email_body' => "check server load or disk usage:<br/><br/>Server: %LABEL%<br/>IP: %IP%<br/>Port: %PORT%<br/>Error: %ERROR%<br/>Date: %DATE%",
);
$message = '';
//$message = sm_get_lang('notifications', $status . '_' . $type);
$message=$notifications[$status . '_' . $type];
if(!$message) {
return $message;
}
$vars['date'] = date('Y-m-d H:i:s');
foreach($vars as $k => $v) {
$message = str_replace('%' . strtoupper($k) . '%', $v, $message);
}
return $this->message = $message;
}
If course the vars associative array should be generated within the class, so the method becomes:
public function parseMessage($status, $type)
{
$vars = array('label'=>$this->getLabel()
, 'ip'=>$this->getIp()
, 'port'=>$this->getPort()
, 'error'=>$this->getError());
$message = '';
//$message = sm_get_lang('notifications', $status . '_' . $type);
$message=$this->notifications[$status . '_' . $type];
if(!$message) {
return $message;
}
$vars = array('label'=>$this->getLabel()
, 'ip'=>$this->getIp()
, 'port'=>$this->getPort()
, 'error'=>$this->getError());
$vars['date'] = date('Y-m-d H:i:s');
foreach($vars as $k => $v) {
$message = str_replace('%' . strtoupper($k) . '%', $v, $message);
}
return $this->message = $message;
}
Note - this is an initial version of the parseMessage method will be recoded as part of a future post to add internationalisation support.
public function parseMessage($status, $type)
{
$vars = array('label'=>$this->getLabel()
, 'ip'=>$this->getIp()
, 'port'=>$this->getPort()
, 'error'=>$this->getError());
$message = '';
//$message = sm_get_lang('notifications', $status . '_' . $type);
$message=$this->notifications[$status . '_' . $type];
if(!$message) {
return $message;
}
$vars = array('label'=>$this->getLabel()
, 'ip'=>$this->getIp()
, 'port'=>$this->getPort()
, 'error'=>$this->getError());
$vars['date'] = date('Y-m-d H:i:s');
foreach($vars as $k => $v) {
$message = str_replace('%' . strtoupper($k) . '%', $v, $message);
}
return $this->message = $message;
}
Email Notification.
For email notification we will use Swiftmailerbundle - available as a common addition to Symfony installations.
The code for this:
protected function notifyByEmail() {
$message = \Swift_Message::newInstance();
$message->setSubject($this->server->parseMessage($this->status_new, 'email_subject'))
->setFrom($this->config['email_from_email'])
->setTo('johnr@reidyint.com')
->setBody($this->server->parseMessage($this->status_new, 'email_body'));
$this->mailer->send($message);
}
This version has a hard coded recipient email address, the users to notify are specified in the users table - which is document in a future post in this series.
This needs a reference to the mailer. One was added to the service configuration for ServerUpdate:
services:
server_update:
class: JMPR\ServerMonBundle\Update\ServerUpdate
arguments: [ @doctrine.orm.entity_manager, @mailer ]
And the constructor was updated:
class ServerUpdate
{
protected $em;
protected $mailer;
public function __construct($em, $mailer)
{
$this->em = $em;
$this->mailer = $mailer;
}
A reference is then passed to the constructor for the UpdaterStatus class.
SMS Notification - SMS Messages.
The third type of notification supported are SMS text messages. This functionality is implemented as a seperate bundle and documented in the next post.
No comments:
Post a Comment