I use the NotifyBecomePrimary() hook in the ZMIRROR routine to call some code to send an email.
Here's the ZMIRROR routine from the %SYS namespace:
ZMIRROR // User-defined code for mirror environment eventsQUIT//// The member has fully become primary so it is now safe to job off processes//// 20230314 - TM - Initial version//
NotifyBecomePrimary()
//// Send an alert email to notify support staff that a mirror failover has occurred//// 20230726 - TM - Initial version//set Namespace = $znspacetry {
znspace"HAPPI"do##class(System.AlertEmail).MirrorFailover()
znspace Namespace
}
catch {
znspace Namespace
}
QUITThe email-sending code from the application namespace references configuration data in a global and constructs a html-formatted message to inform interested parties that a mirror failover has occurred. You should be able to make out what's going on and get it working to your own needs. Here's the class:
/// Description/// -----------////// Grapevine Solutions - HAPPI////// This class implements the alert email methods for various system events.////// Revision History/// ----------------////// 20230726 - TM - Initial version///Class System.AlertEmail Extends%RegisteredObject
{
/// This method sends an alert email message when a mirror failover occurs. It is called from/// the ZMIRROR routine in the %SYS namespace.////// Revision History/// ----------------////// 20230726 - TM - Initial version///ClassMethod MirrorFailover()
{
// get the current timeset EmailTimeStampH = $now()
// get the hostname, e.g. HCPGPO11-V, HCDDMC11-Vset HostName = $zconvert($SYSTEM.INetInfo.LocalHostName(), "U")
// get the environment, e.g. LIVE, TEST, DEVset Environment = ^HAPPIConfig("HostName", HostName)
// get a connection to the email serverset MailServer = ##class(%Net.SMTP).%New()
set MailServer.smtpserver = ^HAPPIConfig("Environment", Environment, "Email", "SMTPServer")
set MailServer.port = ^HAPPIConfig("Environment", Environment, "Email", "SMTPPort")
// check for email server authentication detailsset MailServerUserName = $get(^HAPPIConfig("Environment", Environment, "Email", "Authentication", "UserName"))
set MailServerPassword = $get(^HAPPIConfig("Environment", Environment, "Email", "Authentication", "Password"))
// if there are authentication details then add them to the connectionif ((MailServerUserName '= "") & (MailServerPassword '= "")) {
set MailAuthentication = ##class(%Net.Authenticator).%New()
set MailAuthentication.UserName = MailServerUserName
set MailAuthentication.Password = MailServerPassword
set MailServer.authenticator = MailAuthentication
}
// create a new HTML-formatted mail messageset MailMessage = ##class(%Net.MailMessage).%New()
set MailMessage.IsHTML = 1// set the recipient listset To = $order(^HAPPIConfig("Environment", Environment, "Email", "To", ""))
while (To '= "") {
if (^HAPPIConfig("Environment", Environment, "Email", "To", To) = 1) do MailMessage.To.Insert(To)
set To = $order(^HAPPIConfig("Environment", Environment, "Email", "To", To))
}
// set the senderset MailMessage.From = ^HAPPIConfig("Environment", Environment, "Email", "From")
// set the subjectset Subject = "Mirror Failover Alert on " _ HostName _ " (" _ Environment _ ")"set MailMessage.Subject = Subject
//--------------------------------// build the message html document//--------------------------------// start of html documentdo MailMessage.TextData.WriteLine("<!DOCTYPE html>")
do MailMessage.TextData.WriteLine("<html>")
// start of headerdo MailMessage.TextData.WriteLine("<head>")
do MailMessage.TextData.WriteLine("<meta charset=""UTF-8"">")
do MailMessage.TextData.WriteLine("<title>" _ Subject _ "</title>")
// style sheetdo MailMessage.TextData.WriteLine("<style>")
do MailMessage.TextData.WriteLine("body {font-family: Arial, Helvetica, sans-serif;}")
do MailMessage.TextData.WriteLine("h2 {color: blue; font-size: '125%';}")
do MailMessage.TextData.WriteLine("h3 {color: blue; font-size: '100%';}")
do MailMessage.TextData.WriteLine("table {border: 1px solid #ddd; border-spacing: 10px; border-collapse: separate;}")
do MailMessage.TextData.WriteLine(".good {color: green;}")
do MailMessage.TextData.WriteLine(".bad {color: red;}")
do MailMessage.TextData.WriteLine("</style>")
// end of headerdo MailMessage.TextData.WriteLine("</head>")
// start of bodydo MailMessage.TextData.WriteLine("<body>")
// write subject as message headerdo MailMessage.TextData.WriteLine("<h2>" _ Subject _ "</h2>")
// write alert detailsdo MailMessage.TextData.WriteLine("<h3>Alert Details</h3>")
do MailMessage.TextData.WriteLine("<table>")
do MailMessage.TextData.WriteLine("<tr>")
do MailMessage.TextData.WriteLine("<td>Application</td>")
do MailMessage.TextData.WriteLine("<td>HAPPI</td>")
do MailMessage.TextData.WriteLine("</tr>")
do MailMessage.TextData.WriteLine("<tr class=""bad"">")
do MailMessage.TextData.WriteLine("<td>Alert Reason</td>")
do MailMessage.TextData.WriteLine("<td>Mirror Failover")
do MailMessage.TextData.WriteLine("</tr>")
do MailMessage.TextData.WriteLine("<tr>")
do MailMessage.TextData.WriteLine("<td>Host Name</td>")
do MailMessage.TextData.WriteLine("<td>" _ HostName _ "</td>")
do MailMessage.TextData.WriteLine("</tr>")
do MailMessage.TextData.WriteLine("<tr>")
do MailMessage.TextData.WriteLine("<td>Environment</td>")
do MailMessage.TextData.WriteLine("<td>" _ Environment _ "</td>")
do MailMessage.TextData.WriteLine("</tr>")
do MailMessage.TextData.WriteLine("<tr>")
do MailMessage.TextData.WriteLine("<td>Alert Time</td>")
do MailMessage.TextData.WriteLine("<td>" _ $zdatetime($System.Util.UTCtoLocalWithZTIMEZONE(EmailTimeStampH), 3, 1, 3) _ "</td>")
do MailMessage.TextData.WriteLine("</tr>")
do MailMessage.TextData.WriteLine("</table>")
// write support instructionsdo MailMessage.TextData.WriteLine("<h3>Support Instructions</h3>")
do MailMessage.TextData.WriteLine("<p>")
do MailMessage.TextData.WriteLine("A mirror failover has occurred in the " _ Environment _ " environment and " _ HostName _ " is now the primary failover member.")
do MailMessage.TextData.WriteLine("</p>")
do MailMessage.TextData.WriteLine("<p>")
do MailMessage.TextData.WriteLine("Please ensure that the failover has not disrupted any application processes.")
do MailMessage.TextData.WriteLine("</p>")
do MailMessage.TextData.WriteLine("<p>")
do MailMessage.TextData.WriteLine("Please do not reply to this message as it was automatically generated.")
do MailMessage.TextData.WriteLine("</p>")
// end of bodydo MailMessage.TextData.WriteLine("</body>")
// end of html documentdo MailMessage.TextData.WriteLine("</html>")
// send the messagedo MailServer.Send(MailMessage)
QUIT
}
}- Log in to post comments