将正常运行时间存储在数

时间:2018-05-15 12:03:29

标签: php mysql sql

我想从我的服务器监控一些网站。上下时间存储在数据库中。

目前我的桌子看起来像这样:

id (INT)

website_id (INT) 

uptime (DATETIME) 

downtime (DATETIME) 

lastState (INT) 

lastState存储最后一个HTTP-StatusCode

我的网站No 5例如有以下条目:

+----+------------+---------------------+---------------------+-----------+---------------------+---------------------+
| id | website_id | up                  | down                | lastState | created_at          | updated_at          |
+----+------------+---------------------+---------------------+-----------+---------------------+---------------------+
|  5 |          5 | 2018-04-26 13:56:09 | 2018-04-27 10:42:14 |       503 | 2018-04-26 11:56:09 | 2018-04-26 11:56:09 |
| 13 |          5 | 2018-04-27 10:50:06 | 2018-05-10 08:32:13 |       503 | NULL                | NULL                |
| 20 |          5 | 2018-05-10 08:40:06 | 2018-05-14 03:02:14 |       503 | NULL                | NULL                |
| 23 |          5 | 2018-05-14 03:10:06 | NULL                |       301 | NULL                | NULL                |
+----+------------+---------------------+---------------------+-----------+---------------------+---------------------+

我每10分钟检查一次网站,当主机关闭时,会创建一个新条目。我认为(或者更好,我希望)这是有道理的。

我对这种数据存储的唯一问题是我想计算正常运行时间百分比。我认为使用纯SQL是不可能的。

请与我分享您的想法。 谢谢!

1 个答案:

答案 0 :(得分:0)

由于您的日志系统做得非常好,因此它很简单"在纯SQL中以日志计算网站正常运行时间

这是一种方法。它适用于任何最新版本的MySQL。如果您运行最新版本(8),则可以使用新的窗口函数,使用更少的指令来执行此操作

我分解每一步。 (请注意,我将您的表命名为monitoring

首先,我们要收集同一网站的并发日志的同一行,正常运行时间和停机时间:

    SELECT m.website_id, m.uptime, m.downtime, m.lastState ,
            COALESCE((
                SELECT uptime
                FROM monitoring mold
                WHERE  m.downtime < mold.uptime AND mold.website_id=m.website_id
                GROUP BY website_id
            ), NOW()) AS lastuptime
    FROM monitoring m

返回

| website_id |               uptime |             downtime | lastState |           lastuptime |
|------------|----------------------|----------------------|-----------|----------------------|
|          5 | 2018-04-26T13:56:09Z | 2018-04-27T10:42:14Z |       503 | 2018-04-27T10:50:06Z |
|          5 | 2018-04-27T10:50:06Z | 2018-05-10T08:32:13Z |       503 | 2018-05-10T08:40:06Z |
|          5 | 2018-05-10T08:40:06Z | 2018-05-14T03:02:14Z |       503 | 2018-05-14T03:10:06Z |
|          5 | 2018-05-14T03:10:06Z |               (null) |       301 | 2018-05-15T14:19:06Z |

请注意,lastuptime列始终与同一网站的下一行的uptime相同。如果没有&#34; next&#34;那么这意味着网站已启动,因此我们将NOW()作为参考日期时间。

接下来,通过上述查询,我​​们可以轻松地进行行内计算,以测量正常运行时间和停机时间之间的时差(秒)

SELECT 
       mm.*,
       TIME_TO_SEC(TIMEDIFF(COALESCE(downtime, NOW()), uptime)) AS uptime_seconds, 
       TIME_TO_SEC(TIMEDIFF(lastuptime, COALESCE(downtime, NOW()))) AS downtime_seconds
FROM
(
    SELECT m.website_id, m.uptime, m.downtime, m.lastState ,
            COALESCE((
                SELECT uptime
                FROM monitoring mold
                WHERE  m.downtime < mold.uptime AND mold.website_id=m.website_id
                GROUP BY website_id
            ), NOW()) AS lastuptime
    FROM monitoring m
) mm

返回

| website_id |               uptime |             downtime | lastState |           lastuptime | uptime_seconds | downtime_seconds |
|------------|----------------------|----------------------|-----------|----------------------|----------------|------------------|
|          5 | 2018-04-26T13:56:09Z | 2018-04-27T10:42:14Z |       503 | 2018-04-27T10:50:06Z |          74765 |              472 |
|          5 | 2018-04-27T10:50:06Z | 2018-05-10T08:32:13Z |       503 | 2018-05-10T08:40:06Z |        1114927 |              473 |
|          5 | 2018-05-10T08:40:06Z | 2018-05-14T03:02:14Z |       503 | 2018-05-14T03:10:06Z |         325328 |              472 |
|          5 | 2018-05-14T03:10:06Z |               (null) |       301 | 2018-05-15T14:23:16Z |         126790 |                0 |

我们已经可以从这些结果中注意到您的停机时间大多是相同的(472或473秒)。

最后一步是计算每个网站的停机时间和正常运行时间的总秒数,并确定正常运行时间的百分比

SELECT website_id, 
       SUM(uptime_seconds) AS uptime_seconds, 
       SUM(downtime_seconds) AS downtime_seconds,

       (100 - SUM(downtime_seconds)/SUM(uptime_seconds)*100) AS pourc_uptime
FROM 
(
    SELECT 
           mm.*,
           TIME_TO_SEC(TIMEDIFF(COALESCE(downtime, NOW()), uptime)) AS uptime_seconds, 
           TIME_TO_SEC(TIMEDIFF(lastuptime, COALESCE(downtime, NOW()))) AS downtime_seconds
    FROM
    (
        SELECT m.website_id, m.uptime, m.downtime, m.lastState ,
                COALESCE((
                    SELECT uptime
                    FROM monitoring mold
                    WHERE  m.downtime < mold.uptime AND mold.website_id=m.website_id
                    GROUP BY website_id
                ), NOW()) AS lastuptime
        FROM monitoring m
    ) mm
 ) mmm
GROUP BY website_id

返回

| website_id | uptime_seconds | downtime_seconds | pourc_uptime |
|------------|----------------|------------------|--------------|
|          5 |        1641971 |             1417 |      99.9137 |

SQL FIDDLE

所以这只显示1个网站和几个日志(你发布的)的结果,但我相信它应该可以正常运行,即使你有100万行

您应该从这些查询中创建一些VIEWS,以使您的生活更轻松。