4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

DevOps のための Azure Application Insights クエリ(Kustoクエリ言語 - KQL) その2

Posted at

DevOps のための Azure Application Insights クエリ(Kustoクエリ言語 - KQL) の続編です。

今回もrequestsテーブルからデータを抽出していきます。今回想定しているDevOpsシーンは、ログの特定のコラムの値を、重複なく羅列する場合です。例えば「いったいどの国からサービスへアクセスがあったのか?」といった疑問に答えたいような場合です。

リクエスト元のクライエントのジオ情報をざっくりみたい

リクエストがどの国の、どの地域の、どの町から来ているかを知りたいとします。まずはprojectで要らない情報を切り捨てましょう。

requests
| where timestamp > ago(24h)
| project client_CountryOrRegion, client_StateOrProvince, client_City 

image.png

国のリストを見たい

重複を排除して24時間でどの国からリクエストがあったかを調べます。

requests
| where timestamp > ago(24h)
| summarize count() by client_CountryOrRegion 
| project client_CountryOrRegion, count_ 

image.png

11か国ということでした。

国のリストだけでいいので、projectからcount_を取り除きます

requests
| where timestamp > ago(24h)
| summarize count() by client_CountryOrRegion 
| project client_CountryOrRegion

image.png

ところで、値は空のものがあります。データとしては無意味なので、それをwhereandオペレーターを使って条件をもうひとつ付け足して、とりのぞきます。

requests
| where timestamp > ago(24h) and not(isempty(client_CountryOrRegion)) 
| summarize count() by client_CountryOrRegion 
| project client_CountryOrRegion

image.png

isempt() 関数で空かどうかをしらべ、not()関数で否定して値を逆にします。

これで、求めていた結果が出ました。

国のリストをJSON配列に変換したい

テーブルの状態ではなく、JSON配列の方が都合が良かったとします。

requests
| where timestamp > ago(24h) and not(isempty(client_CountryOrRegion)) 
| summarize count() by client_CountryOrRegion 
| summarize makelist(client_CountryOrRegion)

image.png

再度summarizeしますが、今回はmakelist()関数を使ってJSON配列にしています。

count()関数を使わずに国のリストを得る

count() 関数を使うとパフォーマンスが遅い可能性が高いです。数を数えるということは、O(n)の時間計算量(time complexity)になります。データが多いほど遅くなってしまいます。そこでおそらくはO(1)時間計算量(コンスタントでデータの量に影響されない)になるany()関数を使って以下のように最適化してみます。(実測はしていませんが、論理的には早くなるはずです)

requests
| where timestamp > ago(24h) and not(isempty(client_CountryOrRegion)) 
| summarize any(client_CountryOrRegion) by client_CountryOrRegion 
| summarize makelist(client_CountryOrRegion)

image.png

any() 関数はグループ毎にレコードをひとつランダムに選んで、指定されたカラム、この場合はclient_CountryOrRegionを返します。any()関数のドキュメンテーションに記述されているとおり、どのレコードを選ぶかはランダムで、そのアルゴリズムも公開されていないので、結果は安定していません。

まとめ

ログ解析では時々、特定のカラムの別個の値をすべて知りたい状況が出来きます。例えば:

  • 先週サーバーが返した全ての Http ステータスの値
  • 全てのクライエントのブラウザの種類
  • アクセスがあった全ての国(地域、町)の名前

それらをキーとして、別のクエリに利用する場合などがよくあります。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?