cancel
Showing results for 
Search instead for 
Did you mean: 
Create Post
Community Manager
Community Manager

Basic HTML and CSS in Alerts

I realized that I've never posted this anywhere and I really should have done so.

 

I've talked frequently at SWUG about using HTML and CSS in alerts because they are pretty.  This is my example that I talk about for an alert that triggers for disk volumes which have less than 1 GB free and less than 10% free.  I could describe the whole thing, but the important part for this post is the HTML + CSS body of the message and the variables.  Without further ado, here it is:

 

<!doctype html>
<html>
<head>
<title>Orion Alert: ${N=Alerting;M=AlertName} for ${N=SwisEntity;M=Caption} on ${N=SwisEntity;M=Node.Caption}</title>
<style type="text/css">
.alert_header {
    font-family: calibri;
    font-size: 16pt;
    color: navy;
    text-align: left;
    font-weight: bold;
    vertical-align: center;
}
.alert_description {
    font-family: calibri;
    font-size: 14pt;
    color: gray;
    text-align: left;
    font-weight: bold;
    vertical-align: center;
}
.alert_details {
    font-family: calibri;
    font-size: 10pt;
    color: gray;
    text-align: left;
    font-weight: bold;
    vertical-align: center;
}
th {
    font-family: calibri;
    font-size: 12pt;
    font-weight: bold;
    color: white;
    background-color: #f99d1c;
    text-align: left;
    vertical-align: middle;
}
td {
    font-family: calibri;
    font-size: 12pt;
    font-weight: normal;
    color: #04c9d7;
    background-color: #eeeeee;
    text-align: left;
    vertical-align: middle;
}
}
</style>
</head>
<body>
<table cellspacing="0" cellpadding="1" width="792" border="0">
  <tr>
    <td><table cellspacing="0" cellpadding="0" width="792" border="0">
        <tr>
          <td class='alert_header'>${N=SwisEntity;M=Caption} on ${N=SwisEntity;M=Node.Caption} has less than 10% and 1GB free space.</td>
        </tr>
        <tr>
          <td class='alert_description'>There is less than 10% and 1GB free on ${N=SwisEntity;M=Caption} on ${N=SwisEntity;M=Node.Caption}.  Temp files and extraneous logs have already been removed.</td>
        </tr>
        <tr>
          <td class='alert_details'>Alert Name: ${N=Alerting;M=AlertName} / Trigger Time: ${N=Alerting;M=AlertTriggerTime;F=DateTime}</td>
        </tr>
      </table>
      <table cellspacing="0" cellpadding="1" width="792" border="1" bordercolor="#003366">
        <tr>
          <td><table cellspacing="0" cellpadding="3" width="100%" border="0">
              <tr>
                <th>Node</th>
                <td><img src="http://OrionServer/Orion/images/StatusIcons/${N=SwisEntity;M=Node.StatusLED}" alt="${N=SwisEntity;M=Node.StatusDescription}" width="16" height="16"></td>
                <td><a href="http://OrionServer/Orion/NetPerfMon/NodeDetails.aspx?NetObject=N:${N=SwisEntity;M=NodeID}">${N=SwisEntity;M=Node.Caption} / ${N=SwisEntity;M=Node.IP_Address}</a></td>
              </tr>
              <tr>
                <th>Volume</th>
                <td><img src="http://OrionServer/NetPerfMon/images/Volumes/${N=SwisEntity;M=Icon}" alt="${N=SwisEntity;M=Caption}" width="16" height="16"></td>
                <td><a href="http://OrionServer/Orion/NetPerfMon/VolumeDetails?NetObject=V:${N=SwisEntity;M=VolumeID}">${N=SwisEntity;M=Caption}</a></td>
              </tr>
              <tr>
                <th>Volume Status</th>
                <td><img src="http://OrionServer/Orion/images/StatusIcons/${N=SwisEntity;M=StatusIcon}" width="16" height="16" alt="${N=SwisEntity;M=Status}"></td>
                <td>${N=SwisEntity;M=StatusDescription}</td>
              </tr>
              <tr>
                <th>Free Space</th>
                <td> </td>
                <td>${N=SwisEntity;M=VolumeSpaceAvailable} of ${N=SwisEntity;M=VolumeSize} (${N=SwisEntity;M=VolumePercentAvailable} free)</td>
              </tr>
            </table></td>
        </tr>
      </table></td>
  </tr>
  <tr>
    <td class="alert_details">Alert Details: ${N=Alerting;M=AlertDescription}</td>
  </tr>
  <tr>
    <td class="alert_details">Acknowledge ${N=Alerting;M=AcknowledgeUrl}</td>
  </tr>
</table>
</body>
</html>

 

It's not the easiest thing to read, but the important parts are there.  The CSS block at the top (lines 5-49) control the color, the font and the rest of the prettiness.

 

This is a rudimentary example, but it makes a pretty alert.  In my experience "pretty" alerts get read while plain alerts get filed.

pastedImage_1.png

Please note that the above numbers are simulation numbers and wouldn't actually trigger the alert.

 

Also, if you are encountering extra lines showing up, then you can flip a switch in the database (required SQL access).

/************************************
Fix Alert Email New Line Replacement
*************************************/
UPDATE [dbo].[WebSettings]
SET SettingValue = 'FALSE'
WHERE SettingName = 'Email_ReplaceNewLinesHtml'
  AND SettingValue <> 'FALSE'

 

This is a "fix," but you should totally upvote: EOL Conversion in HTML Alerts 

 

SQL for EOL Conversions section was added by: Kevin M. Sparenberg

"Shoot for the stars to reach the moon"
18 Replies
Level 11

@KMSigma I was on the Virtual SWUG the other day and I thought this was very cool. I started working on it right after the session was over and then bumped onto your post when trying to figure out why my css was not being interpreted properly 🙂 

Long story short: 

ioan_bucsa_0-1590127607135.png

 

0 Kudos
Level 12

Should the query to update not be as follows?

 

UPDATE [dbo].[WebSettings]
SET SettingValue = 'FALSE'
WHERE SettingName = 'Email_ReplaceNewLinesHtml'
AND SettingValue <> 'FALSE'
Level 12

Very nice! I came back to NPM after doing some work with in 5 years ago and see somethings have improved in the platform. As my alerts are all received internally I link to external stylesheets which gives me really good flexibility. 

0 Kudos

I love this, I am looking to embed a few images in the email to match our internal email format. Right now I have to do it via powershell so that I can add an attachment for the embedded logo, can you think of a way to do that without powershell?
Code I use in PowerShell to attach image:

$msg = new-object Net.Mail.MailMessage
$att = new-object Net.Mail.Attachment("C:\Scripts\Email_Resources\logo.jpg")
$att.ContentDisposition.Inline = $True
$att.ContentDisposition.DispositionType = "Inline"
$att.ContentType.MediaType = "image/jpg"
$att.ContentId = "logo"

And then in the body html I call the image:

<img src='cid:logo'>

0 Kudos
Level 12

This will scale horribly! I host them on a website that's available internally and externally or embedded them with base64 but the latter bloats the mail size and some security products don't like it. 

0 Kudos

There's not maybe a public or internal url holding those images that your users would reliably be able to load is there?  Instead of adding the image to the payload of the email just put in an <img> that points to the company website or something?

- Marc Netterfield, Github
0 Kudos

I should be able to dig one up, its a much simpler solution. Maybe even drop the one onto Orion and pull it from there.

Edit: I should say that I don't pick the format/image, we have a specific approved formatting for message I am matching so users know the content came from IT. Otherwise just any logo image from the site would do.

0 Kudos
Level 13

Still doesn't work without compressing the HTML

0 Kudos
Level 11

Not if you run the SQL query at the end of the original post.

0 Kudos
Level 14

This is fantastic! I recently had to brush the dust off my HTML memories and created "pretty" alerts for our team. I do have a question however... I found a "bug" (for lack of a better word) where you can't maintain the HTML formatting in the "message" field when you are creating the alert, you have to smash all the lines together. This makes it even harder to read and troubleshooting a simple typo is a nightmare. Is there a better method? Or will that be corrected? Currently, I create nicely formatted HTML page in notepadd ++, then merge all the lines together before pasting in to the message field. Otherwise, it takes all the line breaks literally and the alert looks like junk.

D

Level 12

I wrote a ton of stuff but decided to move it to a feature request ( ).  I don't want to detract from what KMSigma posted, as its unrelated to his original posts content.

Level 13

Use this site to compress the HTML:  Compress HTML

Level 14

Shame we have to do this, but that doesn't take away from the amazing code KMSigma​ shared. I'm definitely going back through my alerts and looking for ways to enhance them using his content. Been a long time since this network engineer had to code HTML!

D

0 Kudos
Community Manager
Community Manager

You don't technically have to do it... You I just updated this with a little "hack" to make it behave as you think.

"Shoot for the stars to reach the moon"
Level 14

And these "little hacks" are why we gripe and complain in a polite, respectful way. I'm definitely using that hack and your code! This stuff is awesome for a someone like myself.

D

Community Manager
Community Manager

Not sure if you noticed, but the Feature Request I mentioned was my own.  I may be an employee of SolarWinds, but I was also a customer.

"Shoot for the stars to reach the moon"
Level 14

0 Kudos
Level 12

Thanks for sharing!  I was fortunate enough to attend one of the SWUG's last year and would highly recommend it.  It was great to speak to yourself, the other SolarWinds employees, and THWACK MVP's.