SQL:检测周期性日志(每 30 秒)何时丢失
SQL: detect when a recurring log (every 30s) is missing
我们有一个 SQL 作业,每 30 秒运行一次,我们记录每一步(SQL Server 2012)
有时,没有任何原因,也没有任何 "job failed" 消息,作业停止甚至挂起(我们想要分析的行为)。
我们想要实现的是查询日志 table 并检测记录何时丢失(不会每 30 秒发生一次)。
例如:
CREATION_DATE MESSAGE
2015-09-17 07:49:38.053 11 : **Fin**
2015-09-17 07:49:02.377 11 : **Fin**
2015-09-17 07:48:32.100 11 : **Fin**
2015-09-17 07:48:01.940 11 : **Fin**
2015-09-17 07:47:32.100 11 : **Fin**
2015-09-17 07:47:01.967 11 : **Fin**
2015-09-17 07:46:31.663 11 : **Fin**
2015-09-17 07:46:01.803 11 : **Fin**
2015-09-17 07:45:31.663 11 : **Fin**
2015-09-17 07:45:02.060 11 : **Fin**
2015-09-17 07:44:31.843 11 : **Fin**
2015-09-17 07:44:01.970 11 : **Fin**
2015-09-17 07:43:22.397 11 : **Fin** <= MUST BE DETECTED (23 minutes between events)
2015-09-17 07:20:01.767 11 : **Fin** <= MUST BE DETECTED (3 minutes between events)
2015-09-17 07:17:01.743 11 : **Fin**
2015-09-17 07:16:31.777 11 : **Fin**
2015-09-17 07:16:01.690 11 : **Fin**
2015-09-17 07:15:31.733 11 : **Fin**
2015-09-17 07:15:01.807 11 : **Fin**
2015-09-17 07:14:31.683 11 : **Fin**
2015-09-17 07:14:01.793 11 : **Fin**
2015-09-17 07:13:31.853 11 : **Fin**
2015-09-17 07:13:01.840 11 : **Fin**
我希望我的问题很清楚。
这会显示所有超过 30 秒的周期
select A.CREATION_DATE as Start, min(N.CREATION_DATE) as Finish
from logTable A
left join logTable N on A.CREATION_DATE < N.CREATION_DATE
group by A.CREATION_DATE
having datediff(second, A.CREATION_DATE, min(N.CREATION_DATE)) > 30
这是我的 "dirty" 解决方案,同时试图使 Luis 的解决方案起作用(看起来比我的更好)
SELECT TOP 1000 [PROCEDURE_NAME]
,[CREATION_DATE]
,[MESSAGE]
,
DATEDIFF(SECOND,
(SELECT top 1 [CREATION_DATE]
FROM [mactac].[mactac].[ERROR_LOG] f
WHERE f.[CREATION_DATE]<c.[CREATION_DATE]
AND [PROCEDURE_NAME] like '%downl%'
AND [MESSAGE] LIKE '11 : **Fin**'
order by [CREATION_DATE] desc)
,c.[CREATION_DATE]) as DIFF
FROM [mactac].[mactac].[ERROR_LOG] as c
WHERE [PROCEDURE_NAME] like '%downl%'
AND [MESSAGE] LIKE '11 : **Fin**'
order by [CREATION_DATE] desc
此解决方案显示所有记录和经过的时间:-D
但是....我还没想好如何添加:
AND DIFF > 35
Invalid column name 'DIFF'.
为了过滤更长时间
使用 CTE 使这变得非常简单。
with ordered_logs (creation_date, rnk) as
(
select creation_date, row_number() over (order by creation_date)
from your_log_table
)
select first.creation_date, second.creation_date, datediff(ss, first.creation_date, second.creation_date) as SecondsDifference
from ordered_logs first
inner join ordered_logs second on (first.rnk + 1) = second.rnk
where datediff(ss, first.creation_date, second.creation_date) > 30
这将按创建日期对所有记录进行排序,然后将较早的记录与下一个记录(按时间)连接起来。然后它只是检查创建时间的差异是否超过 30 秒。
我们有一个 SQL 作业,每 30 秒运行一次,我们记录每一步(SQL Server 2012)
有时,没有任何原因,也没有任何 "job failed" 消息,作业停止甚至挂起(我们想要分析的行为)。
我们想要实现的是查询日志 table 并检测记录何时丢失(不会每 30 秒发生一次)。
例如:
CREATION_DATE MESSAGE
2015-09-17 07:49:38.053 11 : **Fin**
2015-09-17 07:49:02.377 11 : **Fin**
2015-09-17 07:48:32.100 11 : **Fin**
2015-09-17 07:48:01.940 11 : **Fin**
2015-09-17 07:47:32.100 11 : **Fin**
2015-09-17 07:47:01.967 11 : **Fin**
2015-09-17 07:46:31.663 11 : **Fin**
2015-09-17 07:46:01.803 11 : **Fin**
2015-09-17 07:45:31.663 11 : **Fin**
2015-09-17 07:45:02.060 11 : **Fin**
2015-09-17 07:44:31.843 11 : **Fin**
2015-09-17 07:44:01.970 11 : **Fin**
2015-09-17 07:43:22.397 11 : **Fin** <= MUST BE DETECTED (23 minutes between events)
2015-09-17 07:20:01.767 11 : **Fin** <= MUST BE DETECTED (3 minutes between events)
2015-09-17 07:17:01.743 11 : **Fin**
2015-09-17 07:16:31.777 11 : **Fin**
2015-09-17 07:16:01.690 11 : **Fin**
2015-09-17 07:15:31.733 11 : **Fin**
2015-09-17 07:15:01.807 11 : **Fin**
2015-09-17 07:14:31.683 11 : **Fin**
2015-09-17 07:14:01.793 11 : **Fin**
2015-09-17 07:13:31.853 11 : **Fin**
2015-09-17 07:13:01.840 11 : **Fin**
我希望我的问题很清楚。
这会显示所有超过 30 秒的周期
select A.CREATION_DATE as Start, min(N.CREATION_DATE) as Finish
from logTable A
left join logTable N on A.CREATION_DATE < N.CREATION_DATE
group by A.CREATION_DATE
having datediff(second, A.CREATION_DATE, min(N.CREATION_DATE)) > 30
这是我的 "dirty" 解决方案,同时试图使 Luis 的解决方案起作用(看起来比我的更好)
SELECT TOP 1000 [PROCEDURE_NAME]
,[CREATION_DATE]
,[MESSAGE]
,
DATEDIFF(SECOND,
(SELECT top 1 [CREATION_DATE]
FROM [mactac].[mactac].[ERROR_LOG] f
WHERE f.[CREATION_DATE]<c.[CREATION_DATE]
AND [PROCEDURE_NAME] like '%downl%'
AND [MESSAGE] LIKE '11 : **Fin**'
order by [CREATION_DATE] desc)
,c.[CREATION_DATE]) as DIFF
FROM [mactac].[mactac].[ERROR_LOG] as c
WHERE [PROCEDURE_NAME] like '%downl%'
AND [MESSAGE] LIKE '11 : **Fin**'
order by [CREATION_DATE] desc
此解决方案显示所有记录和经过的时间:-D 但是....我还没想好如何添加:
AND DIFF > 35
Invalid column name 'DIFF'.
为了过滤更长时间
使用 CTE 使这变得非常简单。
with ordered_logs (creation_date, rnk) as
(
select creation_date, row_number() over (order by creation_date)
from your_log_table
)
select first.creation_date, second.creation_date, datediff(ss, first.creation_date, second.creation_date) as SecondsDifference
from ordered_logs first
inner join ordered_logs second on (first.rnk + 1) = second.rnk
where datediff(ss, first.creation_date, second.creation_date) > 30
这将按创建日期对所有记录进行排序,然后将较早的记录与下一个记录(按时间)连接起来。然后它只是检查创建时间的差异是否超过 30 秒。