Application Insightsのデータ転送量に気を付けよう

Application Insightsに大量のデータを流してしまい、Application Insightsだけで普段の4倍ぐらいの金額を課金してしまった者です。

## 概要

Application Insightsはデータ転送量について月5GBまでは無料ですが、**1日のデータ転送量は上限はデフォルトで100GBです。1日です。月ではないです。**
~~うっかりデータ流した人から金をぶん取る気があるとしか思えないような設定なので、~~気を付けましょう。
幸い、策を講じれば防げます。


## 対策


### Application Insightsのデータ転送量の上限を下げる

うっかりデータを送り過ぎてしまうのを防ぐには、ここを設定するのが根本対策になると思います。

https://docs.microsoft.com/ja-jp/azure/application-insights/app-insights-pricing#manage-the-maximum-daily-data-volume

小数を指定することができ、0.2なら1日0.2GBになります。(30日で6GB)
重要なテレメトリを集めているわけではないのであれば、最初は小さく初めて、アラートが鳴ったら増やしていけば良いでしょう。

具体的にはここです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/52527/9302ea7a-1a23-a292-d9ca-78b5c41376d8.png)


手でやるのは忘れそう＆面倒なのでテンプレート化したいところです。
テンプレートのドキュメントに無くて諦めそうになっていたら、以下のドキュメントにはしれっと出てきていました。

https://docs.microsoft.com/ja-jp/azure/application-insights/app-insights-powershell#create-an-azure-resource-manager-template

つまり、`microsoft.insights/components/CurrentBillingFeatures`というリソースで設定できます。

2019/03/05の時点で動いたテンプレートの抜粋を貼っておきます。しばしば忘れるので。

``` json
{
    "parameters":{
        "name": {
            "type": "string"
        },
        "location": {
            "type": "string",
            "defaultValue": "[resourceGroup().location]"
        },
    },
    "resources": [
        {
            "apiVersion": "2015-05-01",
            "name": "[parameters('name')]",
            "type": "Microsoft.Insights/components",
            "location": "[parameters('location')]",
            "properties": {
                "ApplicationId": "[parameters('name')]",
                "Request_Source": "IbizaWebAppExtensionCreate"
            }
        },
        {
            "name": "[concat(parameters('name'), '/BillingFeature')]",
            "type": "Microsoft.Insights/components/CurrentBillingFeatures",
            "location": "[parameters('location')]",
            "apiVersion": "2015-05-01",
            "dependsOn": [
                "[resourceId('microsoft.insights/components', parameters('name'))]"
            ],
            "properties": {
                "CurrentBillingFeatures": "Basic",
                "DataVolumeCap": {
                    "Cap": "0.2"
                }
            }
        }
    ]
}
```


### アプリケーション側でフィルタする

アプリケーション開発側で意識するとしたら、データをApplication Insightに流さないようにするということでしょう。

JavaでLogback等を使っている場合、[特定のAppenderに対してログレベルでフィルタをかける](https://logback.qos.ch/manual/filters_ja.html#thresholdFilter)こともできます。
なので、うっかりTraceレベルにしても、ApplicationInsightにはInfo,Warn,Error,Fatalだけ流す、といったことができるようになります。（そこの設定もミスするとダメですが。）

何らかの独自のテレメトリを送る場合は大量or大きいデータを送らないように気を付けましょう。


なお、サンプリング設定もできますが、これはそもそも大量にアクセスがあり大量に送ることが想定されている場合の設定だと思いますので、今回のようなうっかり大量データを送った場合に被害を軽減する用途には使えない気がします。


### Application Insightsの見える化

これはうっかりによる無駄な課金を防げるわけではないですが、どれぐらいログが送られているかを日常的に監視しておくことで検知できます。

ApplicationInsightsのメトリックエクスプローラの画面にあるグラフをダッシュボードにピン留めするだけです。
ダッシュボードはまだまだ使いづらいですが、私はたまたまこれを見て異常に気づけたので。


### 課金アラートを設定する（未検証）

これも防げるわけではないですが、検知する意味では設定を検討するに値すると思います。
プレビューなので、試していませんが、課金アラートがあります。以下の手順で出来るようです。

https://docs.microsoft.com/ja-jp/azure/billing/billing-set-up-alerts

前の月や見積から「月n万超えたら異常だよね」というのはあるはずなので、これで検知できます。



## 不明点

Application Insightsは後ろにLog Analyticsが居るのですが、データ転送量(データ インジェスト)と、月当たりのデータ保持で課金されます。データ保持については、最初の31日間は無料ですが、以降は月ごとに課金されます。

Log Analyticsはデータ保持の期間について30日～1年の間で変更できると明言されていますが、一方でApplication Insightsは90日保持すると明言されており、この値を変更できるかどうかは書かれていません。（多分無い。）

変更できない場合、恐らく1か月目で蓄えたデータが、2か月目、3か月目のデータ保持分の課金がされることになります。（実際にどうなるかまだ確認していない（したくない）のと、コミュニティで聞いても回答が無いので自信はないです。）

まだ確認していないですが、ApplicationInsights自体を削除して作りなおせばデータは消えるので、データ保持による翌月以降の課金は防げるのではないかと思います（これは試す予定）