{"id":4321,"date":"2012-09-11T08:42:09","date_gmt":"2012-09-11T08:42:09","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/sql-monitors-data-repository-alerts\/"},"modified":"2016-07-28T10:51:45","modified_gmt":"2016-07-28T10:51:45","slug":"sql-monitors-data-repository-alerts","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/sql-monitors-data-repository-alerts\/","title":{"rendered":"SQL Monitor&#8217;s data repository: Alerts"},"content":{"rendered":"<p>In <a href=\"http:\/\/www.simple-talk.com\/blogs\/2012\/08\/23\/sql-monitor-data-repository\/\">my previous post<\/a>, I introduced the SQL Monitor data repository, and described how the monitored objects are stored in a hierarchy in the <em>data<\/em> schema, in a series of tables with a <em>_Keys<\/em> suffix. In this post I had planned to describe how the actual data for the monitored objects is stored in corresponding tables with <em>_StableSamples<\/em> and <em>_UnstableSamples<\/em> suffixes. However, I&#8217;m going to postpone that until my next post, as I&#8217;ve had a request from a SQL Monitor user to explain how alerts are stored.<\/p>\n<p>In the SQL Monitor data repository, alerts are stored in tables belonging to the <em>alert<\/em> schema, which contains the following five tables:<\/p>\n<ol>\n<li>alert.Alert<\/li>\n<li>alert.Alert_Cleared<\/li>\n<li>alert.Alert_Comment<\/li>\n<li>alert.Alert_Severity<\/li>\n<li>alert.Alert_Type<\/li>\n<\/ol>\n<p>In this post, I&#8217;m only going to cover the <em>alert.Alert<\/em> and <em>alert.Alert_Type<\/em> tables. I may cover the other three tables in a later post. The most important table in this schema is <em>alert.Alert<\/em>, as each row in this table corresponds to a single alert. So let&#8217;s have a look at it.<\/p>\n<pre class=\"lang:tsql theme:ssms2012\">SELECT TOP 100 AlertId,\n    AlertType,\n    TargetObject,\n    [Read],\n    SubType\n  FROM alert.Alert\n  ORDER BY AlertId DESC;<\/pre>\n<div class=\"sql-query-results\">\n<table>\n<tbody>\n<tr>\n<th>&#160;<\/th>\n<th>AlertId<\/th>\n<th>AlertType<\/th>\n<th>TargetObject<\/th>\n<th>Read<\/th>\n<th>SubType<\/th>\n<\/tr>\n<tr>\n<th>1<\/th>\n<td>65550<\/td>\n<td>39<\/td>\n<td>7:Cluster,1,4:Name,s29:srp-mr03.testnet.red-gate.com,9:SqlServer,1,4:Name,s0:,<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>2<\/th>\n<td>65549<\/td>\n<td>38<\/td>\n<td>7:Cluster,1,4:Name,s29:srp-mr03.testnet.red-gate.com,7:Machine,1,4:Name,s0:,<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>3<\/th>\n<td>65548<\/td>\n<td>18<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s15:FavouriteThings,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>4<\/th>\n<td>65547<\/td>\n<td>15<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s15:FavouriteThings,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>5<\/th>\n<td>65546<\/td>\n<td>14<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s15:FavouriteThings,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>6<\/th>\n<td>65545<\/td>\n<td>18<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>7<\/th>\n<td>65544<\/td>\n<td>15<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>8<\/th>\n<td>65543<\/td>\n<td>14<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>9<\/th>\n<td>65542<\/td>\n<td>18<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s4:msdb,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>10<\/th>\n<td>65541<\/td>\n<td>14<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s4:msdb,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>11<\/th>\n<td>&#8230;<\/td>\n<td>&#160;<\/td>\n<td>&#160;<\/td>\n<td>&#160;<\/td>\n<td>&#160;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>So what are we seeing here, then? Well, <em>AlertId<\/em> is an auto-incrementing identity column, so <em>ORDER BY AlertId DESC<\/em> ensures that we see the most recent alerts first. <em>AlertType<\/em> indicates the type of each alert, such as <em>Job failed (6)<\/em>, <em>Backup overdue (14)<\/em> or <em>Long-running query (12)<\/em>. The <em>TargetObject<\/em> column indicates which monitored object the alert is associated with. The <em>Read<\/em> column acts as a flag to indicate whether or not the alert has been read. And finally the <em>SubType<\/em> column is used in the case of a <em>Custom metric (40)<\/em> alert, to indicate which custom metric the alert pertains to.<\/p>\n<p>Okay, now lets look at some of those columns in more detail. The <em>AlertType<\/em> column is an easy one to start with, and it brings use nicely to the next table, <em>data.Alert_Type<\/em>. Let&#8217;s have a look at what&#8217;s in this table:<\/p>\n<pre class=\"lang:tsql theme:ssms2012\">SELECT AlertType,\n    Event,\n    Monitoring,\n    Name,\n    Description\n  FROM alert.Alert_Type\n  ORDER BY AlertType;<\/pre>\n<div class=\"sql-query-results\">\n<table>\n<tbody>\n<tr>\n<th>&#160;<\/th>\n<th>AlertType<\/th>\n<th>Event<\/th>\n<th>Monitoring<\/th>\n<th>Name<\/th>\n<th>Description<\/th>\n<\/tr>\n<tr>\n<th>1<\/th>\n<td>1<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Processor utilization<\/td>\n<td>Processor utilization (CPU) on a host machine stays above a threshold percentage for longer than a specified duration<\/td>\n<\/tr>\n<tr>\n<th>2<\/th>\n<td>2<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>SQL Server error log entry<\/td>\n<td>An error is written to the SQL Server error log with a severity level above a specified value.<\/td>\n<\/tr>\n<tr>\n<th>3<\/th>\n<td>3<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>Cluster failover<\/td>\n<td>The active cluster node fails, causing the SQL Server instance to switch nodes.<\/td>\n<\/tr>\n<tr>\n<th>4<\/th>\n<td>4<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>Deadlock<\/td>\n<td>SQL deadlock occurs.<\/td>\n<\/tr>\n<tr>\n<th>5<\/th>\n<td>5<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Processor under-utilization<\/td>\n<td>Processor utilization (CPU) on a host machine remains below a threshold percentage for longer than a specified duration<\/td>\n<\/tr>\n<tr>\n<th>6<\/th>\n<td>6<\/td>\n<td>1<\/td>\n<td>0<\/td>\n<td>Job failed<\/td>\n<td>A job does not complete successfully (the job returns an error code).<\/td>\n<\/tr>\n<tr>\n<th>7<\/th>\n<td>7<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Machine unreachable<\/td>\n<td>Host machine (Windows server) cannot be contacted on the network.<\/td>\n<\/tr>\n<tr>\n<th>8<\/th>\n<td>8<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server instance unreachable<\/td>\n<td>The SQL Server instance is not running or cannot be contacted on the network.<\/td>\n<\/tr>\n<tr>\n<th>9<\/th>\n<td>9<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Disk space<\/td>\n<td>Disk space used on a logical disk drive is above a defined threshold for longer than a specified duration.<\/td>\n<\/tr>\n<tr>\n<th>10<\/th>\n<td>10<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Physical memory<\/td>\n<td>Physical memory (RAM) used on the host machine stays above a threshold percentage for longer than a specified duration.<\/td>\n<\/tr>\n<tr>\n<th>11<\/th>\n<td>11<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Blocked process<\/td>\n<td>SQL process is blocked for longer than a specified duration.<\/td>\n<\/tr>\n<tr>\n<th>12<\/th>\n<td>12<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Long-running query<\/td>\n<td>A SQL query runs for longer than a specified duration.<\/td>\n<\/tr>\n<tr>\n<th>13<\/th>\n<td>14<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Backup overdue<\/td>\n<td>No full backup exists, or the last full backup is older than a specified time.<\/td>\n<\/tr>\n<tr>\n<th>14<\/th>\n<td>15<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Log backup overdue<\/td>\n<td>No log backup exists, or the last log backup is older than a specified time.<\/td>\n<\/tr>\n<tr>\n<th>15<\/th>\n<td>16<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Database unavailable<\/td>\n<td>Database changes from Online to any other state.<\/td>\n<\/tr>\n<tr>\n<th>16<\/th>\n<td>17<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Page verification<\/td>\n<td>Torn Page Detection or Page Checksum is not enabled for a database.<\/td>\n<\/tr>\n<tr>\n<th>17<\/th>\n<td>18<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Integrity check overdue<\/td>\n<td>No entry for an integrity check (DBCC DBINFO returns no date for dbi_dbccLastKnownGood field), or the last check is older than a specified time.<\/td>\n<\/tr>\n<tr>\n<th>18<\/th>\n<td>19<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Fragmented indexes<\/td>\n<td>Fragmentation level of one or more indexes is above a threshold percentage.<\/td>\n<\/tr>\n<tr>\n<th>19<\/th>\n<td>24<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Job duration unusual<\/td>\n<td>The duration of a SQL job duration deviates from its baseline duration by more than a threshold percentage.<\/td>\n<\/tr>\n<tr>\n<th>20<\/th>\n<td>25<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>Clock skew<\/td>\n<td>System clock time on the Base Monitor computer differs from the system clock time on a monitored SQL Server host machine by a specified number of seconds.<\/td>\n<\/tr>\n<tr>\n<th>21<\/th>\n<td>27<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server Agent Service status<\/td>\n<td>The SQL Server Agent Service status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>22<\/th>\n<td>28<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server Reporting Service status<\/td>\n<td>The SQL Server Reporting Service status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>23<\/th>\n<td>29<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server Full Text Search Service status<\/td>\n<td>The SQL Server Full Text Search Service status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>24<\/th>\n<td>30<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server Analysis Service status<\/td>\n<td>The SQL Server Analysis Service status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>25<\/th>\n<td>31<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server Integration Service status<\/td>\n<td>The SQL Server Integration Service status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>26<\/th>\n<td>33<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server Browser Service status<\/td>\n<td>The SQL Server Browser Service status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>27<\/th>\n<td>34<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>SQL Server VSS Writer Service status<\/td>\n<td>The SQL Server VSS Writer status matches the status specified.<\/td>\n<\/tr>\n<tr>\n<th>28<\/th>\n<td>35<\/td>\n<td>0<\/td>\n<td>1<\/td>\n<td>Deadlock trace flag disabled<\/td>\n<td>The monitored SQL Server&#8217;s trace flag cannot be enabled.<\/td>\n<\/tr>\n<tr>\n<th>29<\/th>\n<td>36<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Monitoring stopped (host machine credentials)<\/td>\n<td>SQL Monitor cannot contact the host machine because authentication failed.<\/td>\n<\/tr>\n<tr>\n<th>30<\/th>\n<td>37<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Monitoring stopped (SQL Server credentials)<\/td>\n<td>SQL Monitor cannot contact the SQL Server instance because authentication failed.<\/td>\n<\/tr>\n<tr>\n<th>31<\/th>\n<td>38<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Monitoring error (host machine data collection)<\/td>\n<td>SQL Monitor cannot collect data from the host machine.<\/td>\n<\/tr>\n<tr>\n<th>32<\/th>\n<td>39<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Monitoring error (SQL Server data collection)<\/td>\n<td>SQL Monitor cannot collect data from the SQL Server instance.<\/td>\n<\/tr>\n<tr>\n<th>33<\/th>\n<td>40<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Custom metric<\/td>\n<td>The custom metric value has passed an alert threshold.<\/td>\n<\/tr>\n<tr>\n<th>34<\/th>\n<td>41<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<td>Custom metric collection error<\/td>\n<td>SQL Monitor cannot collect custom metric data from the target object.<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Basically, <em>alert.Alert_Type<\/em> is just a big reference table containing information about the 34 different alert types supported by SQL Monitor (note that the largest id is 41, not 34 &#8211; some alert types have been retired since SQL Monitor was first developed). The <em>Name<\/em> and <em>Description<\/em> columns are self evident, and I&#8217;m going to skip over the <em>Event<\/em> and <em>Monitoring<\/em> columns as they&#8217;re not very interesting. The <em>AlertId<\/em> column is the primary key, and is referenced by <em>AlertId<\/em> in the <em>alert.Alert<\/em> table. As such, we can rewrite our earlier query to join these two tables, in order to provide a more readable view of the alerts:<\/p>\n<pre class=\"lang:tsql theme:ssms2012\">SELECT TOP 100 AlertId,\n    Name,\n    TargetObject,\n    [Read],\n    SubType\n  FROM alert.Alert a \n    JOIN alert.Alert_Type at ON a.AlertType = at.AlertType\n  ORDER BY AlertId DESC;<\/pre>\n<div class=\"sql-query-results\">\n<table>\n<tbody>\n<tr>\n<th>&#160;<\/th>\n<th>AlertId<\/th>\n<th>Name<\/th>\n<th>TargetObject<\/th>\n<th>Read<\/th>\n<th>SubType<\/th>\n<\/tr>\n<tr>\n<th>1<\/th>\n<td>65550<\/td>\n<td>Monitoring error (SQL Server data collection)<\/td>\n<td>7:Cluster,1,4:Name,s29:srp-mr03.testnet.red-gate.com,9:SqlServer,1,4:Name,s0:,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>2<\/th>\n<td>65549<\/td>\n<td>Monitoring error (host machine data collection)<\/td>\n<td>7:Cluster,1,4:Name,s29:srp-mr03.testnet.red-gate.com,7:Machine,1,4:Name,s0:,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>3<\/th>\n<td>65548<\/td>\n<td>Integrity check overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s15:FavouriteThings,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>4<\/th>\n<td>65547<\/td>\n<td>Log backup overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s15:FavouriteThings,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>5<\/th>\n<td>65546<\/td>\n<td>Backup overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s15:FavouriteThings,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>6<\/th>\n<td>65545<\/td>\n<td>Integrity check overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>7<\/th>\n<td>65544<\/td>\n<td>Log backup overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>8<\/th>\n<td>65543<\/td>\n<td>Backup overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>9<\/th>\n<td>65542<\/td>\n<td>Integrity check overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s4:msdb,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<tr>\n<th>10<\/th>\n<td>65541<\/td>\n<td>Backup overdue<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s4:msdb,<\/td>\n<td>0<\/td>\n<td>0<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>Okay, the next column to discuss in the <em>alert.Alert<\/em> table is <em>TargetObject<\/em>. Oh boy, this one&#8217;s a bit tricky! The <em>TargetObject<\/em> of an alert is a serialized string representation of the position in the monitored object hierarchy of the object to which the alert pertains. The serialization format is somewhat convenient for parsing in the C# source code of SQL Monitor, and has some helpful characteristics, but it&#8217;s probably very awkward to manipulate in T-SQL.<\/p>\n<p>I could document the serialization format here, but it would be very dry reading, so perhaps it&#8217;s best to consider an example from the table above. Have a look at the alert with an <em>AlertID<\/em> of 65543. It&#8217;s a <em>Backup overdue<\/em> alert for the <em>SqlMonitorData<\/em> database running on the default instance of <em>granger<\/em>, my laptop. Each different alert type is associated with a specific type of monitored object in the object hierarchy (I described the hierarchy in <a href=\"http:\/\/www.simple-talk.com\/blogs\/2012\/08\/23\/sql-monitor-data-repository\/\">my previous post<\/a>). The <em>Backup overdue<\/em> alert is associated with databases, whose position in the object hierarchy is <em>root &#8594; Cluster &#8594; SqlServer &#8594; Database<\/em>. The <em>TargetObject<\/em> value identifies the target object by specifying the key properties at each level in the hierarchy, thus:<\/p>\n<ul>\n<li>Cluster: Name = &#8220;granger&#8221;<\/li>\n<li>SqlServer: Name = &#8220;&#8221; (an empty string, denoting the default instance)<\/li>\n<li>Database: Name = &#8220;SqlMonitorData&#8221;<\/li>\n<\/ul>\n<p>Well, look at the actual <em>TargetObject<\/em> value for this alert: &#8220;7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s14:SqlMonitorData,&#8221;. It is indeed composed of three parts, one for each level in the hierarchy:<\/p>\n<ul>\n<li>Cluster: &#8220;7:Cluster,1,4:Name,s7:granger,&#8221;<\/li>\n<li>SqlServer: &#8220;9:SqlServer,1,4:Name,s0:,&#8221;<\/li>\n<li>Database: &#8220;8:Database,1,4:Name,s14:SqlMonitorData,&#8221;<\/li>\n<\/ul>\n<p>Each part is handled in exactly the same way, so let&#8217;s concentrate on the first part, &#8220;7:Cluster,1,4:Name,s7:granger,&#8221;. It comprises the following:<\/p>\n<ul>\n<li>&#8220;7:Cluster,&#8221; &#8211; This identifies the level in the hierarchy.<\/li>\n<li>&#8220;1,&#8221; &#8211; This indicates how many different key properties there are to uniquely identify a cluster (we saw in my last post that each cluster is identified by a single property, its <em>Name<\/em>).<\/li>\n<li>&#8220;4:Name,s14:SqlMonitorData,&#8221; &#8211; This represents the <em>Name<\/em> property, and its corresponding value, <em>SqlMonitorData<\/em>. It&#8217;s split up like this:\n<ul>\n<li>&#8220;4:Name,&#8221; &#8211; Indicates the name of the key property.<\/li>\n<li>&#8220;s&#8221; &#8211; Indicates the type of the key property, in this case, it&#8217;s a string.<\/li>\n<li>&#8220;14:SqlMonitorData,&#8221; &#8211; Indicates the value of the property.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>At this point, you might be wondering about the format of some of these strings. Why is the string &#8220;Cluster&#8221; stored as &#8220;7:Cluster,&#8221;? Well an encoding scheme is used, which consists of the following:<\/p>\n<ul>\n<li>&#8220;7&#8221; &#8211; This is the length of the string &#8220;Cluster&#8221;<\/li>\n<li>&#8220;:&#8221; &#8211; This is a delimiter between the length of the string and the actual string&#8217;s contents.<\/li>\n<li>&#8220;Cluster&#8221; &#8211; This is the string itself. 7 characters.<\/li>\n<li>&#8220;,&#8221; &#8211; This is a final terminating character that indicates the end of the encoded string.<\/li>\n<\/ul>\n<p>You can see that &#8220;4:Name,&#8221;, &#8220;8:Database,&#8221; and &#8220;14:SqlMonitorData,&#8221; also conform to the same encoding scheme.<\/p>\n<p>In the example above, the &#8220;s&#8221; character is used to indicate that the value of the <em>Name<\/em> property is a string. If you explore the <em>TargetObject<\/em> property of alerts in your own SQL Monitor data repository, you might find other characters used for other non-string key property values. The different value types you might possibly encounter are as follows:<\/p>\n<ol>\n<li>&#8220;I&#8221; &#8211; Denotes a bigint value. For example, &#8220;I65432,&#8221;.<\/li>\n<li>&#8220;g&#8221; &#8211; Denotes a GUID value. For example, &#8220;g32116732-63ae-4ab5-bd34-7dfdfb084c18,&#8221;.<\/li>\n<li>&#8220;d&#8221; &#8211; Denotes a datetime value. For example, &#8220;d634815384796832438,&#8221;. The value is stored as a bigint, rather than a native SQL datetime value. I&#8217;ll describe how datetime values are handled in the SQL Monitor data repostory in a future post.<\/li>\n<\/ol>\n<p>I suggest you have a look at the alerts in your own SQL Monitor data repository for further examples, so you can see how the <em>TargetObject<\/em> values are composed for each of the different types of alert. Let me give one further example, though, that represents a <em>Custom metric<\/em> alert, as this will help in describing the final column of interest in the <em>alert.Alert<\/em> table, <em>SubType<\/em>. Let me show you the alert I&#8217;m interested in:<\/p>\n<pre class=\"lang:tsql theme:ssms2012\">SELECT AlertId,\n    a.AlertType,\n    Name,\n    TargetObject,\n    [Read],\n    SubType\n  FROM alert.Alert a \n    JOIN alert.Alert_Type at ON a.AlertType = at.AlertType\n  WHERE AlertId = 65769;<\/pre>\n<div class=\"sql-query-results\">\n<table>\n<tbody>\n<tr>\n<th>&#160;<\/th>\n<th>AlertId<\/th>\n<th>AlertType<\/th>\n<th>Name<\/th>\n<th>TargetObject<\/th>\n<th>Read<\/th>\n<th>SubType<\/th>\n<\/tr>\n<tr>\n<th>1<\/th>\n<td>65769<\/td>\n<td>40<\/td>\n<td>Custom metric<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s6:master,12:CustomMetric,1,8:MetricId,I2,<\/td>\n<td>0<\/td>\n<td>2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>An <em>AlertType<\/em> value of 40 corresponds to the <em>Custom metric<\/em> alert type. The <em>Name<\/em> taken from the <em>alert.Alert_Type<\/em> table is simply <em>Custom metric<\/em>, but this doesn&#8217;t tell us anything about the specific custom metric that this alert pertains to. That&#8217;s where the <em>SubType<\/em> value comes in. For custom metric alerts, this provides us with the <em>Id<\/em> of the specific custom alert definition that can be found in the <em>settings.CustomAlertDefinitions<\/em> table. I don&#8217;t really want to delve into custom alert definitions yet (maybe in a later post), but an extra join in the previous query shows us that this alert pertains to the <em><a href=\"http:\/\/sqlmonitormetrics.red-gate.com\/average-runnable-task-count\/\">CPU pressure (avg runnable task count)<\/a><\/em> custom metric alert.<\/p>\n<pre class=\"lang:tsql theme:ssms2012\">SELECT AlertId,\n    a.AlertType,\n    at.Name,\n    cad.Name AS CustomAlertName,\n    TargetObject,\n    [Read],\n    SubType\n  FROM alert.Alert a \n    JOIN alert.Alert_Type at ON a.AlertType = at.AlertType\n    JOIN settings.CustomAlertDefinitions cad ON a.SubType = cad.Id\n  WHERE AlertId = 65769;<\/pre>\n<div class=\"sql-query-results\">\n<table>\n<tbody>\n<tr>\n<th>&#160;<\/th>\n<th>AlertId<\/th>\n<th>AlertType<\/th>\n<th>Name<\/th>\n<th>CustomAlertName<\/th>\n<th>TargetObject<\/th>\n<th>Read<\/th>\n<th>SubType<\/th>\n<\/tr>\n<tr>\n<th>1<\/th>\n<td>65769<\/td>\n<td>40<\/td>\n<td>Custom metric<\/td>\n<td>CPU pressure (avg runnable task count)<\/td>\n<td>7:Cluster,1,4:Name,s7:granger,9:SqlServer,1,4:Name,s0:,8:Database,1,4:Name,s6:master,12:CustomMetric,1,8:MetricId,I2,<\/td>\n<td>0<\/td>\n<td>2<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>The <em>TargetObject<\/em> value in this case breaks down like this:<\/p>\n<ul>\n<li>&#8220;7:Cluster,1,4:Name,s7:granger,&#8221; &#8211; Cluster named &#8220;granger&#8221;.<\/li>\n<li>&#8220;9:SqlServer,1,4:Name,s0:,&#8221; &#8211; SqlServer named &#8220;&#8221; (the default instance).<\/li>\n<li>&#8220;8:Database,1,4:Name,s6:master,&#8221; &#8211; Database named &#8220;master&#8221;.<\/li>\n<li>&#8220;12:CustomMetric,1,8:MetricId,I2,&#8221; &#8211; Custom metric with an <em>Id<\/em> of 2.<\/li>\n<\/ul>\n<p>Note that the hierarchy for a custom metric is slightly different compared to the earlier <em>Backup overdue<\/em> alert. It&#8217;s <em>root &#8594; Cluster &#8594; SqlServer &#8594; Database &#8594; CustomMetric<\/em>. Also notice that, unlike <em>Cluster<\/em>, <em>SqlServer<\/em> and <em>Database<\/em>, the key property for <em>CustomMetric<\/em> is called <em>MetricId<\/em> (not <em>Name<\/em>), and the value is a bigint (not a string).<\/p>\n<p>Finally, delving into the custom metric tables is beyond the scope of this post, but for the sake of avoiding any future confusion, I&#8217;d like to point out that whilst the <em>SubType<\/em> references a custom alert definition, the <em>MetricID<\/em> value embedded in the <em>TargetObject<\/em> value references a custom metric definition. Although in this case both the custom metric definition and custom alert definition share the same <em>Id<\/em> value of 2, this is not generally the case.<\/p>\n<p>Okay, that&#8217;s enough for now, not least because as I&#8217;m typing this, it&#8217;s almost 2am, I have to go to work tomorrow, and my alarm is set for 6am &#8211; eek! In my next post, I&#8217;ll either cover the remaining three tables in the <em>alert<\/em> schema, or I&#8217;ll delve into the way SQL Monitor stores its monitoring data, as I&#8217;d originally planned to cover in this post.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In my previous post, I introduced the SQL Monitor data repository, and described how the monitored objects are stored in a hierarchy in the data schema, in a series of tables with a _Keys suffix. In this post I had planned to describe how the actual data for the monitored objects is stored in corresponding&#8230;&hellip;<\/p>\n","protected":false},"author":37766,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-4321","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/4321","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/37766"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=4321"}],"version-history":[{"count":11,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/4321\/revisions"}],"predecessor-version":[{"id":42219,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/4321\/revisions\/42219"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=4321"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=4321"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=4321"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=4321"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}