如何使用 SQL 测试 5 分钟间隔,给定 AWS Athena 中的 Windows 事件管理器事件时间戳
How to test for 5 minute intervals with SQL, given Windows Event Manager event timestamps in AWS Athena
我在 AWS 中使用 Athena 和 Windows 事件管理器日志来构造一些安全事件查询。其中之一是我想查询在 5 分钟内报告 3 次或更多失败登录尝试的机器。
时间戳列的格式如下:2019-03-25T19:18:10.7954381Z
我已经找到了具有该特定事件 ID 的机器:SELECT machinename,
COUNT(eventid)
FROM windows
WHERE eventid = 4625
GROUP BY machinename
HAVING COUNT(eventid = 4625) >= 3;
对于任何时间戳,它只是 returns 所有 eventid 大于或等于 3 的机器。
我的问题是:我将如何在 SQL 中实现逻辑来检查特定事件 ID 是否在 5 分钟的时间跨度内发生并带有那种时间戳,而不是只显示所有时间?
这是我第一次涉足SQL;任何帮助是极大的赞赏。谢谢!
编辑:
西奥有解决办法。发帖于此:
SELECT
FROM_UNIXTIME(
FLOOR(
TO_UNIXTIME(
DATE_PARSE(substr(timecreated, 1, 16), '%Y-%m-%dT%H:%i')
)/300
) * 300
) AS five_minute_window,
machine-name,
COUNT(event-id) AS event_count
FROM table
WHERE event-id = 4625
GROUP BY 1, machine-name
HAVING COUNT(event-id = 4625) >= 3;
我不得不去掉小数秒,因为有一些异常的时间戳不是这样格式化的(只有整秒)。
所以你想在 n 分钟四舍五入,对吗?我将 oracle 语法放在下面,但请注意所有数据库都具有相似的功能。方法是"round"或"truncate"那一分钟的数据。所以它是 10:43 - return 10:40。一旦你得到它,你就可以按那个分组
- oracle 中的 sysdate return 当前 date/time - 用于测试
- to_char 转换给定格式的日期或数字
- trunc(或round)用于截断数值运算
- to_date是把一个格式的字符串转成日期
select actual_date,
to_date(to_char(actual_date,'YYYYMMDDHH24') || min_trunc_5,'YYYYMMDDHH24MI') rouded_to_5_dt,
min_trunc_5
from
(
select sysdate actual_date,
ltrim(to_char(trunc(to_number(to_char(sysdate,'MI')/5))*5,'09')) min_trunc_5
from dual
) x
它return适合我
actual_date rounded_to_5_dt min_trunc_5
20190410084837 20190410084500 45
看看 48 是如何变成 45 的。现在,如果在任何日期进行这种类型的操作并以此为依据,我将对 5 分钟范围内的所有数据进行分组
在 Athena 中,您可以使用 DATE_TRUNC
函数将时间戳截断为整分钟、整小时等。不幸的是,它不支持单位的倍数,因此五分钟是不可能的。
我通常这样做:FROM_UNIXTIME(FLOOR(TO_UNIXTIME("timestamp")/300) * 300)
。它的作用是转换为 UNIX 时间戳,即自 1970 年以来的秒数,除以 300 以获得自 1970 年以来的五分钟间隔数,将其四舍五入为整数,然后再次乘以 300 以转换回秒数, 然后转换回时间戳。这适用于任何时间间隔,只需将 300 更改为 1800 以四舍五入为半小时等。
Athena 本身不支持您的时间戳格式,因此您需要对其进行解析,这是通过 DATE_PARSE
完成的——例如 DATE_PARSE("timestamp_column", '%Y-%m-%dT%H:%M:%S.%fZ')
.
完整示例可能如下所示:
SELECT
FROM_UNIXTIME(
FLOOR(
TO_UNIXTIME(
DATE_PARSE("timestamp_column", '%Y-%m-%dT%H:%M:%S.%fZ')
)/300
) * 300
) AS five_minute_window,
COUNT(*) AS event_count
FROM some_table
GROUP BY 1
这将为您提供每五分钟的行数 window。您可以添加 WHERE
以过滤特定行,并添加外部查询以查找包含许多事件的 windows 等
我在 AWS 中使用 Athena 和 Windows 事件管理器日志来构造一些安全事件查询。其中之一是我想查询在 5 分钟内报告 3 次或更多失败登录尝试的机器。
时间戳列的格式如下:2019-03-25T19:18:10.7954381Z
我已经找到了具有该特定事件 ID 的机器:SELECT machinename,
COUNT(eventid)
FROM windows
WHERE eventid = 4625
GROUP BY machinename
HAVING COUNT(eventid = 4625) >= 3;
对于任何时间戳,它只是 returns 所有 eventid 大于或等于 3 的机器。
我的问题是:我将如何在 SQL 中实现逻辑来检查特定事件 ID 是否在 5 分钟的时间跨度内发生并带有那种时间戳,而不是只显示所有时间?
这是我第一次涉足SQL;任何帮助是极大的赞赏。谢谢!
编辑: 西奥有解决办法。发帖于此:
SELECT
FROM_UNIXTIME(
FLOOR(
TO_UNIXTIME(
DATE_PARSE(substr(timecreated, 1, 16), '%Y-%m-%dT%H:%i')
)/300
) * 300
) AS five_minute_window,
machine-name,
COUNT(event-id) AS event_count
FROM table
WHERE event-id = 4625
GROUP BY 1, machine-name
HAVING COUNT(event-id = 4625) >= 3;
我不得不去掉小数秒,因为有一些异常的时间戳不是这样格式化的(只有整秒)。
所以你想在 n 分钟四舍五入,对吗?我将 oracle 语法放在下面,但请注意所有数据库都具有相似的功能。方法是"round"或"truncate"那一分钟的数据。所以它是 10:43 - return 10:40。一旦你得到它,你就可以按那个分组
- oracle 中的 sysdate return 当前 date/time - 用于测试
- to_char 转换给定格式的日期或数字
- trunc(或round)用于截断数值运算
- to_date是把一个格式的字符串转成日期
select actual_date,
to_date(to_char(actual_date,'YYYYMMDDHH24') || min_trunc_5,'YYYYMMDDHH24MI') rouded_to_5_dt,
min_trunc_5
from
(
select sysdate actual_date,
ltrim(to_char(trunc(to_number(to_char(sysdate,'MI')/5))*5,'09')) min_trunc_5
from dual
) x
它return适合我
actual_date rounded_to_5_dt min_trunc_5
20190410084837 20190410084500 45
看看 48 是如何变成 45 的。现在,如果在任何日期进行这种类型的操作并以此为依据,我将对 5 分钟范围内的所有数据进行分组
在 Athena 中,您可以使用 DATE_TRUNC
函数将时间戳截断为整分钟、整小时等。不幸的是,它不支持单位的倍数,因此五分钟是不可能的。
我通常这样做:FROM_UNIXTIME(FLOOR(TO_UNIXTIME("timestamp")/300) * 300)
。它的作用是转换为 UNIX 时间戳,即自 1970 年以来的秒数,除以 300 以获得自 1970 年以来的五分钟间隔数,将其四舍五入为整数,然后再次乘以 300 以转换回秒数, 然后转换回时间戳。这适用于任何时间间隔,只需将 300 更改为 1800 以四舍五入为半小时等。
Athena 本身不支持您的时间戳格式,因此您需要对其进行解析,这是通过 DATE_PARSE
完成的——例如 DATE_PARSE("timestamp_column", '%Y-%m-%dT%H:%M:%S.%fZ')
.
完整示例可能如下所示:
SELECT
FROM_UNIXTIME(
FLOOR(
TO_UNIXTIME(
DATE_PARSE("timestamp_column", '%Y-%m-%dT%H:%M:%S.%fZ')
)/300
) * 300
) AS five_minute_window,
COUNT(*) AS event_count
FROM some_table
GROUP BY 1
这将为您提供每五分钟的行数 window。您可以添加 WHERE
以过滤特定行,并添加外部查询以查找包含许多事件的 windows 等