Advertisement
Drainedsoul

Uptime Monitor Downtime

Jun 1st, 2012
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
T-SQL 9.88 KB | None | 0 0
  1. /*  Gets the value of an option for a connection.
  2.     First checks to see if the option is set on a per-connection basis, and then
  3.     checks to see if it's set globally.
  4.     Returns whichever it finds first.
  5.     If the option is not found, returns NULL.
  6. */
  7. CREATE FUNCTION GetConnectionOption (@connection_id int, @option_name varchar(25))
  8. RETURNS varchar(50)
  9. AS
  10. BEGIN
  11.  
  12. --  Fall through is to return NULL
  13.     DECLARE @return_this varchar(50);
  14.     SET @return_this=NULL;
  15.    
  16. --  Pre-convert the option_name to upper to save time
  17.     DECLARE @to_upper varchar(25);
  18.     SET @to_upper=UPPER(@option_name);
  19.    
  20. --  Is this option set on a per-connection basis?
  21.     IF (
  22.         SELECT
  23.             COUNT(*)
  24.         FROM
  25.             connection_options
  26.         WHERE
  27.             @connection_id=connection_id AND
  28.             @to_upper=UPPER(option_name)
  29.     )<>0
  30.    
  31.         SET @return_this=(
  32.             SELECT TOP 1
  33.                 option_value
  34.             FROM
  35.                 connection_options
  36.             WHERE
  37.                 @connection_id=connection_id AND
  38.                 @to_upper=UPPER(option_name)
  39.         );
  40.  
  41. --  If not, is it set at all?
  42.     ELSE IF (
  43.         SELECT
  44.             COUNT(*)
  45.         FROM
  46.             options
  47.         WHERE
  48.             @to_upper=UPPER(option_name)
  49.     )<>0
  50.    
  51.         SET @return_this=(
  52.             SELECT TOP 1
  53.                 option_value
  54.             FROM
  55.                 options
  56.             WHERE
  57.                 @to_upper=UPPER(option_name)
  58.         );
  59.  
  60. --  Return whatever value we've managed to find (if any)
  61.     RETURN @return_this;
  62.  
  63. END;
  64.  
  65. GO
  66.  
  67. /*  Gets four tables which reveals the connection's details:
  68.     1.  Connection information.
  69.     2.  A list of datapoints for display in a graph.
  70.     3.  A list of the downtimes which exceed the set threshold for this connection.
  71.     4.  A list of the high latency periods which exceed the set threshold for this connection.
  72. */
  73. CREATE PROCEDURE GetConnectionDetail
  74.     @connection_id int
  75. AS
  76.  
  77.     SET NOCOUNT ON;
  78.  
  79. --  Make sure the database remains in a consistent state
  80.     BEGIN TRANSACTION get_detail;
  81.  
  82. --  BEGIN DATA GATHERING
  83.    
  84. --  Grab the number of minutes per period
  85.     DECLARE @minutes_per_period int;
  86.     SET @minutes_per_period=CONVERT(
  87.         INT,
  88.         dbo.GetConnectionOption(
  89.             @connection_id,
  90.             'minutes_per_period'
  91.         )
  92.     );
  93.    
  94. --  Convert to number of seconds per period
  95.     DECLARE @seconds_per_period bigint;
  96.     SET @seconds_per_period=@minutes_per_period*60;
  97.  
  98. --  We need somewhere to store the filtered pings table
  99.     DECLARE @pings_temp TABLE
  100.     (
  101.         row_num bigint NOT NULL PRIMARY KEY,
  102.         datetime datetime2 NOT NULL,
  103.         latency bigint NOT NULL
  104.     );
  105.    
  106.     INSERT INTO @pings_temp
  107.     (
  108.         row_num,
  109.         datetime,
  110.         latency
  111.     )
  112.     SELECT
  113.         ROW_NUMBER() OVER (ORDER BY datetime ASC),
  114.         datetime,
  115.         latency
  116.     FROM
  117.         pings
  118.     WHERE
  119.         connection_id=@connection_id AND
  120.         datetime>DATEADD(
  121.             minute,
  122.             @minutes_per_period*-1,
  123.             GETDATE()
  124.         );
  125.        
  126. --  Building incrementally on that, we need somewhere to store only the pings occuring as the first in,
  127. --  or right after a downtime
  128.     DECLARE @downtimes_temp TABLE
  129.     (
  130.         row_num bigint NOT NULL PRIMARY KEY,
  131.         datetime datetime2 NOT NULL,
  132.         latency bigint NOT NULL
  133.     );
  134.    
  135.     INSERT INTO @downtimes_temp
  136.     (
  137.         row_num,
  138.         datetime,
  139.         latency
  140.     )
  141.     SELECT
  142.         ROW_NUMBER() OVER (ORDER BY row_num ASC),
  143.         datetime,
  144.         latency
  145.     FROM
  146.         @pings_temp AS outer_query
  147.     WHERE
  148.         (
  149.             latency=-1 AND
  150.             (
  151.                 SELECT TOP 1
  152.                     subquery.latency
  153.                 FROM
  154.                     @pings_temp AS subquery
  155.                 WHERE
  156.                     subquery.row_num=outer_query.row_num-1
  157.             )<>-1
  158.         )
  159.         OR
  160.         (
  161.             latency<>-1 AND
  162.             (
  163.                 SELECT TOP 1
  164.                     subquery.latency
  165.                 FROM
  166.                     @pings_temp AS subquery
  167.                 WHERE
  168.                     subquery.row_num=outer_query.row_num-1
  169.             )=-1
  170.         );
  171.        
  172. --  Now we build the second table -- a list of downtimes, with their start and end times, total downtime
  173. --  and number of pings missed
  174.     DECLARE @downtimes_final_temp TABLE
  175.     (
  176.         start_time datetime2 NOT NULL,
  177.         end_time datetime2 NOT NULL,
  178.         downtime int NOT NULL,
  179.         count int NOT NULL
  180.     );
  181.    
  182.     INSERT INTO @downtimes_final_temp
  183.     (
  184.         start_time,
  185.         end_time,
  186.         downtime,
  187.         count
  188.     )
  189.     SELECT
  190.         start_table.datetime AS start_time,
  191.         end_table.datetime AS end_time,
  192.         DATEDIFF(
  193.             second,
  194.             start_table.datetime,
  195.             end_table.datetime
  196.         ),
  197.         (
  198.             SELECT
  199.                 COUNT(*)+1
  200.             FROM
  201.                 @pings_temp AS pings_temp
  202.             WHERE
  203.                 pings_temp.datetime>start_table.datetime AND
  204.                 pings_temp.datetime<end_table.datetime
  205.         )
  206.     FROM
  207.         @downtimes_temp AS start_table,
  208.         @downtimes_temp AS end_table
  209.     WHERE
  210.         start_table.row_num=end_table.row_num-1 AND
  211.         start_table.row_num%2=1;
  212.        
  213. --  Now we need to get a table of all the high latency periods
  214.     DECLARE @latency_temp TABLE
  215.     (
  216.         row_num bigint NOT NULL PRIMARY KEY,
  217.         datetime datetime2 NOT NULL,
  218.         latency bigint NOT NULL
  219.     );
  220.    
  221.     DECLARE @latency_threshold int;
  222.     SET @latency_threshold=CONVERT(
  223.         INT,
  224.         dbo.GetConnectionOption(
  225.             @connection_id,
  226.             'latency_threshold'
  227.         )
  228.     );
  229.    
  230.     INSERT INTO @latency_temp
  231.     (
  232.         row_num,
  233.         datetime,
  234.         latency
  235.     )
  236.     SELECT
  237.         ROW_NUMBER() OVER (ORDER BY row_num ASC),
  238.         datetime,
  239.         latency
  240.     FROM
  241.         @pings_temp AS outer_query
  242.     WHERE
  243.         (
  244.             latency<=@latency_threshold AND
  245.             (
  246.                 SELECT TOP 1
  247.                     subquery.latency
  248.                 FROM
  249.                     @pings_temp AS subquery
  250.                 WHERE
  251.                     subquery.row_num=outer_query.row_num-1
  252.             )>@latency_threshold
  253.         )
  254.         OR
  255.         (
  256.             latency>@latency_threshold AND
  257.             (
  258.                 SELECT TOP 1
  259.                     subquery.latency
  260.                 FROM
  261.                     @pings_temp AS subquery
  262.                 WHERE
  263.                     subquery.row_num=outer_query.row_num-1
  264.             )<=@latency_threshold
  265.         );
  266.        
  267. --  Building the fourth table, same as second for high latency periods
  268.     DECLARE @latency_final_temp TABLE
  269.     (
  270.         start_time datetime2 NOT NULL,
  271.         end_time datetime2 NOT NULL,
  272.         downtime int NOT NULL,
  273.         count int NOT NULL
  274.     );
  275.    
  276.     INSERT INTO @latency_final_temp
  277.     (
  278.         start_time,
  279.         end_time,
  280.         downtime,
  281.         count
  282.     )
  283.     SELECT
  284.         start_table.datetime AS start_time,
  285.         end_table.datetime AS end_time,
  286.         DATEDIFF(
  287.             second,
  288.             start_table.datetime,
  289.             end_table.datetime
  290.         ),
  291.         (
  292.             SELECT
  293.                 COUNT(*)+1
  294.             FROM
  295.                 @pings_temp AS pings_temp
  296.             WHERE
  297.                 pings_temp.datetime>start_table.datetime AND
  298.                 pings_temp.datetime<end_table.datetime
  299.         )
  300.     FROM
  301.         @latency_temp AS start_table,
  302.         @latency_temp AS end_table
  303.     WHERE
  304.         start_table.row_num=end_table.row_num-1 AND
  305.         start_table.row_num%2=1;
  306.        
  307.     DECLARE @row_skip int;
  308.     SET @row_skip=CONVERT(
  309.         INT,
  310.         (
  311.             SELECT
  312.                 COUNT(*)
  313.             FROM
  314.                 @pings_temp
  315.         )/CONVERT(
  316.             INT,
  317.             dbo.GetConnectionOption(
  318.                 @connection_id,
  319.                 'points_per_period'
  320.             )
  321.         )
  322.     );
  323.    
  324.     IF @row_skip=0 SET @row_skip=1;
  325.        
  326. --  DATA GATHERING COMPLETE
  327.  
  328. --  OUTPUT DATA
  329.  
  330. --  #1
  331. --  Connection information
  332.     SELECT
  333.         connections.mnemonic AS mnemonic,
  334.         connections.remote_addr AS remote_addr,
  335.         @minutes_per_period AS minutes_per_period,
  336.         dbo.GetConnectionOption(@connection_id,'latency_threshold') AS latency_threshold,
  337.         dbo.GetConnectionOption(@connection_id,'downtime_ping_count') AS downtime_ping_count,
  338.         dbo.GetConnectionOption(@connection_id,'downtime_latency_count') AS downtime_latency_count,
  339.         up_down.status AS up_down_status,
  340.         up_down.since_when AS up_down_since_when,
  341.         high_low.status AS high_low_status,
  342.         high_low.since_when AS high_low_since_when,
  343.         downtime_sum.downtime AS up_down_downtime,
  344.         latency_sum.downtime AS high_low_downtime,
  345.         avg_latency.avg_latency AS avg_latency
  346.     FROM
  347.         connections,
  348.         (
  349.             SELECT TOP 1
  350.                 CASE WHEN latency=-1
  351.                     THEN 'Down'
  352.                     ELSE 'Up'
  353.                 END AS status,
  354.                 CASE WHEN latency=-1
  355.                     THEN
  356.                     (
  357.                         SELECT TOP 1
  358.                             datetime
  359.                         FROM
  360.                             @downtimes_temp
  361.                         ORDER BY
  362.                             datetime DESC
  363.                     )
  364.                     ELSE NULL
  365.                 END AS since_when
  366.             FROM
  367.                 @pings_temp
  368.             ORDER BY
  369.                 datetime DESC
  370.         ) AS up_down,
  371.         (
  372.             SELECT TOP 1
  373.                 CASE WHEN latency>@latency_threshold
  374.                     THEN 'High"'
  375.                     ELSE 'Low'
  376.                 END AS status,
  377.                 CASE WHEN latency>@latency_threshold
  378.                     THEN
  379.                     (
  380.                         SELECT TOP 1
  381.                             datetime
  382.                         FROM
  383.                             @latency_temp
  384.                         ORDER BY
  385.                             datetime DESC
  386.                     )
  387.                     ELSE NULL
  388.                 END AS since_when
  389.             FROM
  390.                 @pings_temp
  391.             ORDER BY
  392.                 datetime DESC
  393.         ) AS high_low,
  394.         (
  395.             SELECT
  396.                 CASE WHEN subquery.downtime IS NULL OR subquery.downtime=0
  397.                     THEN 100.00
  398.                     ELSE ROUND((1-(subquery.downtime/CAST(@seconds_per_period AS float)))*100,2)
  399.                 END AS downtime
  400.             FROM
  401.                 (
  402.                     SELECT
  403.                         SUM(downtime) AS downtime
  404.                     FROM
  405.                         @downtimes_final_temp
  406.                 ) AS subquery
  407.         ) AS downtime_sum,
  408.         (
  409.             SELECT
  410.                 CASE WHEN subquery.downtime IS NULL OR subquery.downtime=0
  411.                     THEN 100.00
  412.                     ELSE ROUND((1-(subquery.downtime/CAST(@seconds_per_period AS float)))*100,2)
  413.                 END AS downtime
  414.             FROM
  415.                 (
  416.                     SELECT
  417.                         SUM(downtime) AS downtime
  418.                     FROM
  419.                         @latency_final_temp
  420.                 ) AS subquery
  421.         ) AS latency_sum,
  422.         (
  423.             SELECT
  424.                 CASE WHEN subquery.avg_latency IS NULL
  425.                     THEN 0
  426.                     ELSE subquery.avg_latency
  427.                 END AS avg_latency
  428.             FROM
  429.                 (
  430.                     SELECT
  431.                         AVG(latency) AS avg_latency
  432.                     FROM
  433.                         @pings_temp
  434.                     WHERE
  435.                         latency<>-1
  436.                 ) AS subquery
  437.         ) AS avg_latency
  438.     WHERE
  439.         connections.connection_id=@connection_Id;
  440.        
  441. --  #2
  442. --  All datapoints
  443.     SELECT
  444.         *
  445.     FROM
  446.         (
  447.             (
  448.                 SELECT
  449.                     datetime,
  450.                     latency
  451.                 FROM
  452.                     @pings_temp AS pings_temp
  453.                 WHERE
  454.                     row_num%@row_skip=0
  455.             )
  456.             UNION
  457.             (
  458.                 SELECT
  459.                     datetime,
  460.                     latency
  461.                 FROM
  462.                     @latency_temp
  463.             )
  464.             UNION
  465.             (
  466.                 SELECT
  467.                     datetime,
  468.                     latency
  469.                 FROM
  470.                     @downtimes_temp
  471.             )
  472.         ) AS subquery
  473.     ORDER BY
  474.         datetime ASC;
  475.        
  476. --  #3
  477. --  List of downtimes
  478.     SELECT
  479.         *
  480.     FROM
  481.         @downtimes_final_temp AS downtimes
  482.     WHERE
  483.         downtimes.count>=CONVERT(
  484.             INT,
  485.             dbo.GetConnectionOption(
  486.                 @connection_id,
  487.                 'downtime_ping_count'
  488.             )
  489.         );
  490.  
  491. --  #4
  492. --  List of high latency states
  493.     SELECT
  494.         *
  495.     FROM
  496.         @latency_final_temp as latency
  497.     WHERE
  498.         latency.count>=CONVERT(
  499.             INT,
  500.             dbo.GetConnectionOption(
  501.                 @connection_id,
  502.                 'downtime_ping_count'
  503.             )
  504.         );
  505.  
  506. --  End consistent state       
  507.     COMMIT TRANSACTION get_detail;
  508.        
  509. GO
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement