つまづいた...
前回の投稿では、発報されたログアラートの対象ログを取得する方法について書きました。
今回は、つまづいたポイントを紹介します。
(1) ログクエリが不正?
検証ログアラートルール
前回の投稿の下図のログアラートルールを使います。
[ディメンションで分割する] の [リソース ID 列] で _ResourceId
を指定し、 Computer
と RenderedDescription
で分割します。
現象
仮想マシンで以下のようなイベントログを出力しました。
そして、発報されたアラートの「アラート詳細」の [Filtered search results] の [View query results] リンクをクリックすると、下図のようにログクエリが失敗してしまいました。
「うまくパースできなかった」と言っているようですね...
Query could not be parsed at 'C' on line [11,114]
Token: C
Line: 11
Position: 114
原因
前回の投稿では、「[Filtered search results] では、ログクエリにディメンション分割で指定されたカラムの値で絞り込む条件 (赤枠の部分) が追加される」と説明しました。追加される条件は、ディメンション分割で指定されたカラムを文字列に変換し、それらのカラムの値を文字列リテラルで示し、等しいかと問い合わせています。
エラーとなっているのは、文字列リテラルの「ディメンション分割で指定されたカラムの値」に不正な文字 (エンコードが必要な文字) が含まれているためです。よって、この部分について対処する必要があります。
| where
tostring(Computer) == 'vm-202301' and
tostring(RenderedDescription) == 'No files exist in '
C : \temp''
対処
このエラーを対処するのに、アラートルールの「ログクエリ」と「ディメンション分割」を改修します。
文字列リテラルの「ディメンション分割で指定されたカラムの値」は、シングルクォーテーションで囲まれています。以下のドキュメントを参考に対処方法を考えます。
アラートルールのログクエリ
まず、ログクエリを以下のように改修しました。
ディメンション分割で指定されたカラム RenderedDescription
に不正な文字が含まれているので、このカラム値に対して置換を施し、ディメンション分割で指定するためのカラムを別途設けることにしました。
Event
| where EventLog == "Application"
| where EventLevel == 1 or EventLevel == 2
| extend dimension_RenderedDescription =
replace_string(replace_regex(RenderedDescription, '[\'\t\n\r]', ''), '\\', '/')
| project
TimeGenerated,
Computer,
RenderedDescription,
dimension_RenderedDescription,
EventLog,
EventLevel,
EventID,
_ResourceId
(繰り返しになりますが)「ディメンション分割で指定されたカラムの値」は文字列リテラルで示されます。そのため、そのまま文字列リテラルで示されても問題ない値 にしなければなりません。
前述のドキュメントの「文字列リテラル」を参考に、以下の文字を別の文字に置換することにしました。
置換前の文字 | 置換後の文字 |
---|---|
シングルクォーテーション (\' ) |
空文字 ('' ) |
タブ (\t ) |
空文字 ('' ) |
改行 newline (\n ) |
空文字 ('' ) |
戻り return (\r ) |
空文字 ('' ) |
バックスラッシュ (\\ ) |
スラッシュ (/ ) |
| extend dimension_RenderedDescription =
replace_string(replace_regex(RenderedDescription, '[\'\t\n\r]', ''), '\\', '/')
そして、クエリの実行結果に別途設けた dimension_RenderedDescription
を追加します。
| project
TimeGenerated,
Computer,
RenderedDescription,
dimension_RenderedDescription,
EventLog,
EventLevel,
EventID,
_ResourceId
アラートルールのディメンション分割
次に、ディメンション分割で指定していたカラム RenderedDescription
を先ほどのログクエリで別途設けた dimension_RenderedDescription
に変更しました。
確認
ログクエリの実行結果を取得することができました。
エラーが発生していた部分は、以下のように改善されていました。
| where
tostring(Computer) == 'vm-202301' and
tostring(dimension_RenderedDescription) == 'No files exist in C:/temp'
(2) テーブルがない?
検証ログアラートルール
下図のログアラートルールを使います。
ターゲットリソースは、Log Analytics ワークスペースを指定しています。
AppTraces テーブルに対するログクエリを用意し、[ディメンションで分割する] の [リソース ID 列] で _ResourceId
を指定します。
現象
発報されたアラートの「アラート詳細」の [Filtered search results] の [View query results] リンクをクリックすると、下図のようにログクエリが失敗してしまいました。
「AppTraces という名前のテーブルが見当たらない」と言っているようですね...
'where' operator: Failed to resolve table or column expression named 'AppTraces'
原因
前回の投稿で、「[ディメンションで分割する] の [リソース ID 列] で _ResourceId
を指定すると、Azure リソースのログに対して直接クエリを実行することができる」と説明しました。
_ResourceId
が Application Insights リソースだと、アラート時の「影響を受けるリソース」もその Application Insights リソースとなり、その Application Insights リソースからクエリを実行することとなります。
ログは Log Analytics ワークスペースへ保存されているものの、Log Analytics ワークスペースでも、Application Insights リソースでも同じログを確認することができますが、それぞれのテーブル名やカラム名が異なるため、Log Analytics ワークスペースで成功しているクエリでも Application Insights リソースではそのクエリは失敗してしまいます。
- テーブル構造
Application Insights と Log Analytics ワークスペースでは、以下のようにテーブルが異なっています。
※各テーブルの説明は、上記のドキュメントをご参照ください。
Application Insights のテーブル |
Log Analytics ワークスペース のテーブル |
---|---|
availabilityResults | AppAvailabilityResults |
browserTimings | AppBrowserTimings |
dependencies | AppDependencies |
customEvents | AppEvents |
customMetrics | AppMetrics |
pageViews | AppPageViews |
performanceCounters | AppPerformanceCounters |
requests | AppRequests |
exceptions | AppExceptions |
traces | AppTraces |
対処
このエラーを対処するのに、アラートルールを改修します。対処方法は以下のいずれかで行います。
- [ターゲットスコープ] を「Application Insights」リソースを指定し、[ログクエリ] を Application Insights リソースから実行するのに適したものに変更する。 (テーブルを「AppTraces」→「traces」に変更するなど)
- [ディメンションで分割する] の [リソース ID 列] で「分割しない」を選択する。
ふたつ目のほうが影響が小さい (変更も少ない) ようなので、そちらの方法で対処しました。
確認
ログクエリの実行結果を取得することができました。
まとめ
REST API で不具合が発生したら Azure ポータルで確認する術があるので、このようにトラブルシューティングすると良いですね。
早く改善してくれるとなお良いですけどね。