Azure VMのメモリ使用量などのアラート設定（Telegraf+Azure Monitor編）

前回の「[Azure VMのメモリ使用量などのアラート設定（LogAnalytics編）](https://qiita.com/fukasawah/items/9445fa3055af6ae9f434)」の続きになります。

サポートに「ゲストOS診断だとグラフは描けてもアラート設定は出来ない、LogAnalyticsでやってみたけどもう少しどうにかなりませんか？」と雑に問い合わせたところ、TelegrafをAzure Monitorと連携するドキュメントとSS付きで設定例まで教えてもらいました。サポートの中の人、ありがとうございます。

以下、ドキュメントです。ここの通りやればよいでしょう。

https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/collect-custom-metrics-linux-telegraf

以下は、そのアラート設定ができるかどうかの確認です。

### telegraf?

TelegrafはInfluxdata社製のメトリック収集エージェント。
今回はtelegrafの出力先をAzure Monitorにすることで実現している（[Azure Monitorのカスタムメトリック](https://docs.microsoft.com/ja-jp/azure/azure-monitor/platform/metrics-custom-overview)という機能を利用している）

### やりたいこと

VMのメモリ使用率とディスク使用率についてアラートを設定したい
（ゲストOS診断でメトリックは取れてグラフを書いたりすることは出来るが、アラート設定ができないため）


### 前提

- あらかじめVMを用意しておく
- **システム割り当てのマネージドID(system-assigned managed identity)を有効にしておく**

マネージドIDが必須です。詳しい手順は以下から。

https://docs.microsoft.com/ja-jp/azure/active-directory/managed-identities-azure-resources/qs-configure-portal-windows-vm#enable-system-assigned-managed-identity-on-an-existing-vm


### セットアップ

telegrafをダウンロードしてサービスとして裏で動かすだけです。最新版のダウンロードは公式から。

https://portal.influxdata.com/downloads/

Linux(RHEL系)はこんな感じ。

``` bash
# Telegrafの導入
sudo yum install -y https://dl.influxdata.com/telegraf/releases/telegraf-1.11.2-1.x86_64.rpm

# 設定ファイルを書き換え: cpu,memory,diskのメトリックをazure_monitorに連携する設定を書き出す
telegraf --input-filter cpu:mem:disk --output-filter azure_monitor config | sudo tee /etc/telegraf/telegraf.conf 

# 自動起動設定 & 起動
sudo systemctl enable telegraf 
sudo systemctl start telegraf 
```

これだけ。ID/Pass等は要らない。マネージドIDによってVMの情報を勝手に拾ってその情報で連携する。


Azureのドキュメントに無かったWindows 10にも入れた。一応Powershellでコピペで入るようにしている。5.1.17763.503以降なら動くはず。。

``` PowerShell
$url = "https://dl.influxdata.com/telegraf/releases/telegraf-1.11.2_windows_amd64.zip"

$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, "telegraf.zip")

Expand-Archive "telegraf.zip" -DestinationPath .\

$telegrafHome = "C:\Program Files\Telegraf"
$configPath = "$telegrafHome\telegraf.conf"

MKDIR "$telegrafHome"
Copy-Item -Path ".\telegraf\*" -Destination "$telegrafHome" -Recurse

& "$telegrafHome\telegraf.exe" --input-filter cpu:mem:disk --output-filter azure_monitor config > $configPath

# Remove BOM
$config = Get-Content $configPath
$utf8NoBomEncoding = New-Object "System.Text.UTF8Encoding" -ArgumentList @($false)
[System.IO.File]::WriteAllLines($configPath, $config, $utf8NoBomEncoding)

& "$telegrafHome\telegraf.exe" --service install

Start-Service -InputObject telegraf
```

基本的な流れは一緒だけど、AgentなのでWindowsのサービスとして登録する必要があります。
telegrafは親切にコマンドを用意してくれていて`"telegraf.exe" --service install` で行える。後はサービスを起動するだけですが。

詳しくはtelegrafのWindowsサービスに関するドキュメントがあります。複数のtelegrafをサービスとして動かしたい場合等は読みましょう。

https://github.com/influxdata/telegraf/blob/master/docs/WINDOWS_SERVICE.md


ちなみに、telegrafはデフォルトで10秒周期でメトリックを送り、空き容量など要らないかもしれないメトリックも取ります。


### 確認

Agentを有効にして3分後ぐらいにVirtualMachineブレードのメトリックでグラフで見てみます。メトリック名前空間に`telegraf/mem`等が追加されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/8c26fbe4-c7b5-eea8-06df-b56294e168fd.png)

最後に今回のメインのアラート設定です。詳しい手順は前回とだいたい同じなので省略して、見え方の部分だけ紹介します。

収集したメトリックはちゃんと「VirtualMachine」の「メトリック」の「Telegraf/mem」として見えます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/e019dc42-276b-f76f-f0cd-b240ebb1c22d.png)

ただ注意として、アラートは1VMづつ設定する必要があるようです。このように複数VMを対象にするとアラート設定はできませんでした。（OSの違いのせいかもしれない？）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/52527/9d978431-d591-91c0-5827-f7f258691e1f.png)


### LogAnalyticsと比べた時の主観

アラート設定で複数指定が出来ない点、増減したときに対応が必要なのがネックな感じ。ここが気になる場合はLogAnalyticsに集めたほうがよいかもしれない。

- 〇 管理するリソースが減る（LogAnalytics不要）
- △ 導入にゲストOS上の操作が必須だが、スクリプト実行で自動化できる
- △ 課金の単位が不明瞭で無料枠が少なく上限設定ができない点が心配。（扱うデータが小さい単位なので課金事故リスクは低そう）
- ×1 VM、1メトリック毎にアラート設定が必要。

### トラブルシューティング

遭遇したメモ。

うまく動かない場合はログ（Linuxなら`/var/log/messages`）で何が起きているか確認する。
WindowsのServiceはログがどこに出るかは分かっていない。が`telegraf`とオプション無しで実行すると、そのままフォアグラウンドで動いてログが標準出力される。

```
Jul 16 03:17:00 vm-fukasawah-mem-2 telegraf: 2019-07-16T03:17:00Z E! [agent] Error writing to output [azure_monitor]: unable to fetch authentication credentials: azure.BearerAuthorizer#WithAuthorization: Failed to refresh the Token for request to https://japaneast.monitoring.azure.com/subscriptions/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/resourceGroups/XXXXXXXXXXXXX/providers/Microsoft.Compute/virtualMachines/vm-fukasawah-mem-2/metrics: StatusCode=400 -- Original Error: adal: Refresh request failed. Status Code = '400'. Response body: {"error":"invalid_request","error_description":"Identity not found"}
```

システム割り当てIDが有効になっていないので有効化してエージェントを再起動。


```
Jul 16 03:24:00 vm-fukasawah-mem-2 telegraf: 2019-07-16T03:24:00Z E! [agent] Error writing to output [azure_monitor]: failed to write batch: [400] 400 Bad Request
```

システム割り当てIDを有効にした後に再起動していない場合は再起動。




<!--
無料枠でどれぐらい使える？

貧乏性なので無料枠でどれぐらい使えるか試算してみます。

Agent自体は無料で、Azure Monitorへのリクエストで課金が行われます。正確には[Azure Monitorのカスタムメトリックとメトリッククエリ](https://azure.microsoft.com/ja-jp/pricing/details/monitor/)の課金です。（2019/12/01までは無料らしい）

無料枠が150MB/月というと、お遊びならともかくお仕事で使ったらあっという間に使い切りそうです。
（ただ、メトリックという比較的小さい単位のデータしか扱わないので、LogAnalyticsやApplicationInsightsと違って無茶苦茶な課金事故にはならないと思います。）

LogAnalyticsは「データ転送量」となっていましたが、Azure Monitorは「データポイント」という単位となっています。ラベル名を除いてデータポイントの数でみているものとして試算してみます。

[料金表](https://azure.microsoft.com/ja-jp/pricing/details/monitor/)の情報から**1データポイント辺り8byte**らしいです。無料枠の150MBならば、**19,660,800 個**のデータポイントが得られます。
これを10秒に1回収集すると1日8640回になります。1か月が30日とすると**259,200回/月**。つまり、150MBで**約75個/月**のメトリックが取れます。
あとは「1VMから得るメトリックの個数」で割ると「VMの台数」となるはずです。
例えばディスク使用率とメモリ使用率で**2個**を集めるとすると、**約37VM分**のメトリックを無料枠で集めることが出来ます。細かく言えば1VMあたり約5MB/月ぐらいかかるという感じでしょうか。

約37VM分と聞くとあまり余裕がない気がしますね。メトリックを絞ったり収集間隔をもう少し空けたりした方がよさそうです。

実はtelegrafはcpu:mem:diskと絞っていても、細かいメトリックを色々送っています。その様子は`telegraf --test` で見てみることができます。freeやavailable等は要りませんね・・・

```
"C:\Program Files\Telegraf\telegraf.exe" --test
2019-07-16T04:26:01Z I! Starting Telegraf 1.11.2
2019-07-16T04:26:01Z I! Using config file: C:\Program Files\Telegraf\telegraf.conf
> cpu,cpu=cpu0,host=fukasawah-win usage_guest=0,usage_guest_nice=0,usage_idle=90.9090909090909,usage_iowait=0,usage_irq=0,usage_nice=0,usage_softirq=0,usage_steal=0,usage_system=3.0303030303030303,usage_user=6.0606060606060606 1563251162000000000
> cpu,cpu=cpu-total,host=fukasawah-win usage_guest=0,usage_guest_nice=0,usage_idle=90.9090909090909,usage_iowait=0,usage_irq=0,usage_nice=0,usage_softirq=0,usage_steal=0,usage_system=3.0303030303030303,usage_user=6.0606060606060606 1563251162000000000
> disk,device=C:,fstype=NTFS,host=fukasawah-win,mode=unknown,path=\C: free=122906443776i,inodes_free=0i,inodes_total=0i,inodes_used=0i,total=135838822400i,used=12932378624i,used_percent=9.520384817470266 1563251162000000000
> disk,device=D:,fstype=NTFS,host=fukasawah-win,mode=unknown,path=\D: free=2037813248i,inodes_free=0i,inodes_total=0i,inodes_used=0i,total=4293849088i,used=2256035840i,used_percent=52.541106912791435 1563251162000000000
> mem,host=fukasawah-win active=0i,available=60096512i,available_percent=5.5993802212732176,buffered=0i,cached=0i,commit_limit=0i,committed_as=0i,dirty=0i,free=0i,high_free=0i,high_total=0i,huge_page_size=0i,huge_pages_free=0i,huge_pages_total=0i,inactive=0i,low_free=0i,low_total=0i,mapped=0i,page_tables=0i,shared=0i,slab=0i,swap_cached=0i,swap_free=0i,swap_total=0i,total=1073270784i,used=1013174272i,used_percent=94.40061977872678,vmalloc_chunk=0i,vmalloc_total=0i,vmalloc_used=0i,wired=0i,write_back=0i,write_back_tmp=0i 1563251162000000000
```

これらを調整したい場合はtelegrafの設定ファイルを変更します。
例えば、telegrafの設定で、30秒に1回送る、Percentのみを取りこむとする場合はこんな感じに。

``` toml
[agent]
  ## Default data collection interval for all inputs
  interval = "30s" # 修正

# Read metrics about cpu usage
[[inputs.cpu]]
  ## Whether to report per-cpu stats or not
  percpu = true
  ## Whether to report total system cpu stats or not
  totalcpu = true
  ## If true, collect raw CPU time metrics.
  collect_cpu_time = false
  ## If true, compute and report the sum of all non-idle CPU states.
  report_active = false

  fieldpass = ["*_percent"] # 追加

# Read metrics about disk usage by mount point
[[inputs.disk]]
  ## By default stats will be gathered for all mount points.
  ## Set mount_points will restrict the stats to only the specified mount points.
  # mount_points = ["/"]

  ## Ignore mount points by filesystem type.
  ignore_fs = ["tmpfs", "devtmpfs", "devfs", "iso9660", "overlay", "aufs", "squashfs"]

  fieldpass = ["*_percent"] # 追加


# Read metrics about memory usage
[[inputs.mem]]
  # no configuration

  fieldpass = ["*_percent"] # 追加
```


ただ、ケチりすぎて本質を見失うのも良くありません。ちゃんと費用対効果を見て決めると良いでしょう（保身）

-->