6

我有一个包含 playerId 值的日志文件,一些播放器在文件中有多个条目。无论他们在日志文件中是否有 1 个或多个条目,我都想获得唯一玩家的确切不同计数。

使用下面的查询它扫描 497 条记录并找到 346 个唯一行(346 是我想要的数字)查询:

fields @timestamp, @message
| sort @timestamp desc
| filter @message like /(playerId)/ 
| parse @message "\"playerId\": \"*\"" as playerId
| stats count(playerId) as CT by playerId

497 条记录 346 行

如果我将查询更改为使用 count_distinct ,我会得到我想要的。下面的例子:

fields @timestamp, @message
| sort @timestamp desc
| filter @message like /(playerId)/ 
| parse @message "\"playerId\": \"*\"" as playerId
| stats count_distinct(playerId) as CT 

带有 count_distinct 函数

然而,count_distinct 的问题在于,随着查询扩展到更大的时间范围/更多记录,条目的数量会达到数千甚至数万。由于 Insights count_distinct 行为的性质,当数字变为近似值时,这会带来一个问题......

“返回该字段的唯一值的数量。如果该字段具有非常高的基数(包含许多唯一值),则 count_distinct 返回的值只是一个近似值。”。

文档:https ://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html

这是不可接受的,因为我需要确切的数字。稍微处理一下查询,并坚持使用 count(),而不是 count_distinct() 我相信这是答案,但是我无法得出一个数字......不起作用的例子......任何想法?

例 1:

fields @timestamp, @message
| sort @timestamp desc
| filter @message like /(playerId)/ 
| parse @message "\"playerId\": \"*\"" as playerId
| stats count(playerId) as CT by playerId
| stats count(*) 

我们无法理解查询。

为了清楚起见,我正在寻找要在显示数字的单行中返回的确切计数。

4

1 回答 1

3

如果我们引入一个硬编码为“1”的虚拟字段怎么办?这个想法是检索它的最小值,以便它保持为“1”,即使同样playerId发生不止一次。然后我们对这个字段求和。

日志条目可能如下所示:

[1]"playerId": "1b45b168-00ed-42fe-a977-a8553440fe1a"

询问:

fields @timestamp, @message
| sort @timestamp desc
| filter @message like /(playerId)/ 
| parse @message "[*]\"playerId\": \"*\"" as dummyValue, playerId
| stats sum(min(dummyValue)) by playerId as CT 

使用的参考资料:

于 2020-02-23T20:46:59.843 回答