【Azure】これ知ってた? 「Log Analytics」「Kusto」のログクエリ時のテクニック:Tech TIPS
Azureの各種サービスが出力するログを「Log Analytics」を分析するには、「Kusto」という言語でクエリを記述する必要がある。Azure App Service/Front Doorを主な対象として、筆者がよく使っているKustoのクエリ時のテクニックを紹介しよう。
対象:Azure Log Analytics、Kusto(KQL)、Azure Front Door、Azure App Service
「Azure Log Analytics」「Kusto」でのログ分析が難しい!?
Azureの各サービスが出力するログを分析する場合、「Azure Log Analytics」サービスなら簡単にセットアップできて便利だ。
ただLog Analyticsでは、「Kusto」(KQL: Kusto Query Language)と呼ばれる言語で分析時のフィルタや出力内容などを指定する必要がある。構造はSQL言語によく似ているとはいえ、望み通りの統計などを得るには、それなりにKustoの関数や演算子を使いこなす必要がある。Microsoft Learnのレファレンスなどを参照しつつ、試行錯誤を繰り返すこともよくあるのではないだろうか。
本Tech TIPSでは、そのような時に役立つ、Kustoのちょっとしたクエリのテクニックを紹介したい。ログの主な対象はAzure App ServiceとAzure Front Doorとする。
クエリ文字列をパラメータごとに分割して出力するには
Azure App ServiceでもAzure Front Doorでも、HTTPリクエストに含まれるクエリ文字列(クエリストリング)は特にパースされることなく、テーブル列の1つに格納されている。
これをクエリ文字列に含まれるパラメータごとに分割して見やすくするには、「parse_urlquery()」「parse_url()」関数を利用する。これらの関数の引数にクエリ文字列またはURLを指定して得られる戻り値に対し、「Query Parameters」というキーを指定すると、各クエリパラメータ名をキーとした値(動的なオブジェクト)が返される。
AppServiceHTTPLogs
| extend query = parse_urlquery(CsUriQuery)["Query Parameters"]
| extend tag = query["tag"], lat = query["lat"], lon = query["lon"]
AzureDiagnostics
| extend query = parse_url(requestUri_s)["Query Parameters"]
| extend tag = query["tag"], lat = query["lat"], lon = query["lon"]
上記のクエリの場合、「tag」「lat」「lon」という計算列が新たに設けられ、そこに同名のクエリパラメータの値が格納される。「project」演算子を指定しない場合、テーブル列に加えてこれらの計算列も出力(表示)される。
「summarize」でクエリパラメータの出現数の統計を取る際の注意点
前述のクエリで、パラメータごとに出現数の統計を取りたい、ということもよくあるだろう。
その場合、「summarize」演算子の引数に前述のパラメータ値を格納した計算列を指定することになる。その際、単に指定するとエラーになってしまうので、「tostring()」関数で計算列の値(動的なオブジェクト)を文字列に変換してからsummarizeの引数に指定する必要がある。
AppServiceHTTPLogs
| extend query = parse_urlquery(CsUriQuery)["Query Parameters"]
| extend tag = query["tag"], lat = query["lat"], lon = query["lon"]
| summarize RequestCount = count() by tostring(tag)
微妙に異なる複数のテーブル列名に要注意
Log Analyticsで同じ意味なのに、名前が異なる複数のテーブル列に出くわしたことはないだろうか。
筆者はAzure Front Doorで過去に、クライアントIPアドレス(HTTPリクエストなどの送信元のIPアドレス)のテーブル列として「clientIP_s」「clientIp_s」(「p」が大文字と小文字)の2種類を目撃したことがある。同様に「errorInfo_s」「ErrorInfo_s」というテーブル列もあった。これらはカテゴリによって別々のテーブル列名が割り当てられていた。
このような状況で同じクエリの記述を使い回そうとすると、カテゴリによって列名が異なるせいでエラーになる。かといって、カテゴリごとに列名を正しく書き直すのは面倒だ。
このような場合、以下のように複数の列名を「extend」で別の計算列にまとめるという手がある。「iif()」は、第1引数が真なら第2引数を、偽なら第3引数を返す関数で、「isempty()」は引数が空文字列なら真を返す関数だ。
Copyright© Digital Advantage Corp. All Rights Reserved.