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

Basic HTML and CSS in Alerts

If there's one thing that I hear from customers is that people ignore alerts.  What I've found in the past is that plain text alerts go unread, get automatically filed, or get deleted.  But if you take a little time and play with basic HTML and CSS, your email alerts will get the attention they deserve.

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: #292929;
        text-align: left;
        font-weight: bold;
        vertical-align: center;
      }

      .alert_description {
        font-family: calibri;
        font-size: 14pt;
        color: #444444;
        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;
      }

      .header_table {
        border: none;
        width: 100%;
      }

      .metrics_table {
        border: 1px solid #04C9D7;
        border-collapse: collapse;
        width: 100%;
      }

      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: #B8D757;
        background-color: #eeeeee;
        text-align: left;
        vertical-align: middle;
      }

      body {
        background-color: #eeeeee; /* not quite white */
      }
    </style>
  </head>

  <body>
    <table cellspacing="0" cellpadding="1" width="792px">
      <tr>
        <td>
          <table class="header_table" cellspacing="0" cellpadding="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}.
                <ol>
                  <li>Temporary files have already been deleted by an alert action</li>
                  <li>Web logs older than 14 days have already been deleted by an alert action</li>
                </ol>
              </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 class="metrics_table" cellspacing="0" cellpadding="1" width="792">
            <tr>
              <td>
                <table cellspacing="0" cellpadding="3" width="100%">
                  <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 Description: ${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.

KMSigma_0-1593635285362.png

Please note that the above numbers are simulation numbers and wouldn't actually trigger the alert. (which is also why there is no Acknowledge URL displayed.

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
Updated to use proper CSS language for 'table' elements by: Kevin M. Sparenberg

"Shoot for the stars to reach the moon"
32 Replies
Level 7

I love this, Thanks! Only problem I have is the icons don't show up. I changed the URL to ours. I.e.:

<img src="https://Solarwinds/Orion/images/StatusIcons/${N=SwisEntity;M=StatusIcon}" width="16" height="16" alt="${N=SwisEntity;M=Status}"

but none of the icons display

0 Kudos

The icons (like everything in the Orion website) require authentication.  It works for me because I'm using Windows Integrated Authentication.  Otherwise, you can change up the URL to include the DirectLink authentication.

 

"Shoot for the stars to reach the moon"
0 Kudos

I would like a bit more info on the tradeoff. We use WMI authentication for these alerts. It seems Windows Integrated needs XML on the server side and code on the client side. I guess the XML goes into the Orion web server Web.config. What mechanism would a mail client use to allow the Windows authentication? Am I missing something?

I don't need to share with non-Orion users, which is in the description for DirectLink and what would be the mechanism for remote mail clients to use the user crested in DirectLink?

Thanks

0 Kudos

Sorry - I think I was unclear.  There are two ways that you can "see" the images (that I know of).

  1. Add the DirectLink authorization to the end of each image URL (https://server.domain.local/images/things.png?AccountID=DirectLink&OtherStuff=1)
  2. Enable Windows Integrated Authentication on the website for login (it's done during the configuration wizard when the website is first built).

There are probably other ways to do this, but these are the "easier" ones that come immediately to mind.  

"Shoot for the stars to reach the moon"

I created the DirectLink account and the syntax didn't work and when I went back to the original URL, it worked - without invoking the DirectLink user. This is what I came up with:

Well, the icons had been working but stopped...

mgheffler_0-1605647363370.png

Thanks!

0 Kudos

Had an action corruption and lost a few things: This is the reset:

 

mgheffler_0-1605647450158.png

 

0 Kudos

The simulation of the alert:

 

mgheffler_0-1605647650564.png

 

0 Kudos

Looks correct.  The issue is that your email client is trying to pull in graphics from a third-party website.

This can be caused by a few things - for example with Outlook, it'll block third-party graphics by default unless you add them to a whitelist (it's buried somewhere in the registry and I haven't done it in years.).  Otherwise, your email client may not be able to "find" the graphics at all (meaning that this is not able to read the image files from the web server).  This second issue is most likely because it's trying to read the graphics, but the email client cannot "authenticate" which is why I was suggesting using DirectLink just for the images.

Are you getting the same rendering problems on your mobile device?

"Shoot for the stars to reach the moon"
0 Kudos
Level 7

@KMSigma 

Could you share the program list that you used to craft the alert that you showed us in the video please?  That part went by very fast and I didnt get a chance to catch it so I can work on my alerts the same way you did.

I remember notepad++, but there was something from Microsoft Visual Studio with HTML...   and some others...  ?

 

Thank you

0 Kudos
Community Manager
Community Manager

KMSigma_0-1605218968839.png

For my THWACKcamp session, I was using Microsoft Visual Studio Code with some extensions:

  • IntelliSense for CSS class names in HTML
  • Live Server
  • Prettier - Code Formatter

 

"Shoot for the stars to reach the moon"
0 Kudos
Level 10

@KMSigma when I tried this in an email the <html> tags freaked out the alert webpage and the web page was missing sections like the alert code was overwritting the HTML of the web page.  If I just added the code as a using <table> tags in the web page nothing unexpected occurred.  Is this a known issue?

0 Kudos

Good call there - yes, you are correct.  Pages generally don't like multiple <html> tags.  I should have been more clear.  That's not technically a "bug" since we are doing something in the rendering of the page that the browser doesn't like.  The rub is that (I think) most email systems require the <html> tag to render correctly within the email program.  So, it's a general catch-22.

This is the kind of stuff that I want people to call out so we can each learn, so thank you for calling it out.

"Shoot for the stars to reach the moon"
0 Kudos
Level 13

Although I can give this Kudos and agree that this might help, most of our alerts are sent to Remedy On Demand(now BMC Helix).   We have to send Remedy plain text or the alert itself would just have all the raw HTML code in it and be completely unreadable.  Remedy doesn't use the code.

This is kind of a vote for more Service Desk integrations.

John Handberg
0 Kudos

Totally get it @jhandberg - we used a similar system where I came from that was an HP (?) system.  For my part is was much easier building the alerts that were all plain text.  If you have a specific need for a certain type of Service Desk integration, you can always use the SolarWinds Orion API.

"Shoot for the stars to reach the moon"
0 Kudos
Level 12

@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

 

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

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