web-dev-qa-db-ja.com

CloudWatch Insightsクエリ-カウントから単一のカウントを取得する方法

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 records 346 rows

代わりにcount_distinctを使用するようにクエリを変更すると、必要なものが正確に得られます。以下の例:

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

with count_distinct function

ただし、count_distinctの問題は、クエリがより大きなタイムフレーム/より多くのレコードに拡大すると、エントリの数が数千、数万になることです。 Insightsのcount_distinct動作の性質により、数値が近似値になるため、これには問題があります...

「フィールドの一意の値の数を返します。フィールドのカーディナリティが非常に高い(多くの一意の値が含まれている)場合、count_distinctから返される値は概算です。」.

ドキュメント: https://docs.aws.Amazon.com/AmazonCloudWatch/latest/logs/CWL_QuerySyntax.html

正確な数が必要なので、これは受け入れられません。クエリを少し遊んで、count_distinct()ではなくcount()を使用する答えは正しいと思いますが、1つの数値に到達できませんでした...機能しない例...考え?

例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(*) 

クエリを理解できません。

明確にするために、数値を示す単一の行で返される正確な数を探しています。

2
ElasticThoughts

「1」にハードコードされたダミーフィールドを導入するとどうなるでしょうか。アイデアは、同じplayerIdが複数回発生しても「1」のままになるように最小値を取得することです。そして、このフィールドを合計します。

ログエントリは次のようになります。

[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 

使用される参照:

0
Marc Lopez