﻿# 你必須瞭解 Azure Functions 內建的執行記錄如何對成本帶來衝擊

當你在建立 Function App 時也同時啟用了 Application Insights 的話，預設會啟用**內建的記錄機制**(built-in logging)，並且會把記錄儲存在 Azure Storage 儲存體帳戶的 Table 中。我們有個 Azure Function (v1) 應用程式，至今穩定運作了 4 年，但最近發現就算沒有什麼流量，儲存體的費用也很高。因為我們的網站最近已經沒有什麼流量，怎麼還會花這麼多錢呢？我分析了一下，發現光是 Table Storage 就佔用儲存體有 113 GiB 之多這才驚覺，原來是 Function App 搞的鬼，他們把所有監控的數據都自動儲存到指定的 Azure Storage 儲存體帳戶之中了！今天我就來說明如何有效率的刪除這些過時的紀錄，避免不必要的資源耗用。

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/abd22a7db441e3142319-208608276-9ed6bf1e-dda4-4fbd-8646-358bc3aa8f8c.png)

### Function App 的執行記錄都存在哪裡？

每個 Function App 都會有個相對應的 **Storage account** (儲存體帳戶)，而在應用程式設定中，預設有個 `AzureWebJobsDashboard` 參數，指向**儲存體帳戶**的連接字串。然而，這個參數最主要的目的，就是寫入 Function App 的所有執行紀錄，但內容沒啥營養，就是時間而已：

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/ce81d931355e7954c5e3-208602498-267d43fc-7c09-4ea4-af07-b084bc7ec34f.png)

但每個 Function 每次執行都會記錄一筆，所以很容易累積到非常多。更重要的是，他不會自動清除，只會自動累積，並且一個月就會建立一個 Table 起來，其命名規則為 `AzureWebJobsHostLogs` + `YYYY` + `MM`，範例如下：

```
AzureWebJobsHostLogs202212
```

你要是不知道有這個表格的存在，你的荷包就會在不經意之中漸漸的變小，就像[煮蛙效應](https://zh.wikipedia.org/zh-tw/%E7%85%AE%E8%9B%99%E6%95%88%E6%87%89)一樣，一開始沒感覺，等有感覺的時候，都不知道已經浪費多少錢了！

我查了一下，我們在 2018 年 11 月的時候，當月就累積了有 3,050,671 筆紀錄，而且每個月都在增加！

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/175181f9d7c2e377a481-208601872-47d6f3c1-a7c7-4a4f-8d8b-c089eb5fdc40.png)

我剛剛也統計了一下 2022 年 8 月的紀錄，當月也有 3,823,679 筆紀錄，實在太驚人了，我真的沒意識到這些記錄會累積！

![image](https://stwillblogassets.blob.core.windows.net/files/images/external/user-images.githubusercontent.com/483e5b4c6171e215dd3e-208608541-32e105c9-a85e-4b46-a1c9-a3549bde1153.png)

### 如何清除過期的紀錄

因為我是最近才發現這些占空間的東西，所以累積了好幾十個表格要刪除，因此我寫了一支簡單的 PowerShell 腳本，方便我快速刪除這些資料：

1.  先列出所有儲存體**表格**
    
    ```powershell
    $json = az storage table list --account-name 'mystor' -o json --only-show-errors
    ```
    
    > 其中 `mystor` 是我的儲存體帳戶名稱。
    
2.  篩選出想要刪除的**表格**清單
    
    ```powershell
    $json |
    ConvertFrom-Json |
    where { -not ($_.name -like 'AzureWebJobsHostLogs202212') }
    ```
    
    > 以上範例僅保留當月的紀錄。
    
3.  透過 `az storage table delete` 刪除表格
    
    ```powershell
    $json |
    ConvertFrom-Json |
    where { -not ($_.name -like 'AzureWebJobsHostLogs202212') }
    foreach {
        echo "az storage table delete --name $($_.name) --account-name mystor -o json --only-show-errors"
        az storage table delete --name $($_.name) --account-name 'mystor' -o json --only-show-errors
    }
    ```
    
    > 以上範例僅保留當月的紀錄。
    
    如果你只想刪除 `2020` 之前的紀錄，可以這樣執行：
    
    ```powershell
    $json |
    ConvertFrom-Json |
    where { $_.name -like 'AzureWebJobsHostLogs201*' }
    foreach {
        echo "az storage table delete --name $($_.name) --account-name mystor -o json --only-show-errors"
        az storage table delete --name $($_.name) --account-name 'mystor' -o json --only-show-errors
    }
    ```
    

### 如何停用執行記錄

像是測試環境，只要網站上線後，其實不太需要再記錄這些資訊，因此你大可關閉記錄功能。你只要從 Function App 的「應用程式設定」中刪除 `AzureWebJobsDashboard` 這個設定，日後就不會寫入 Log 了！

如果你的 Function App 有使用到 Blob Trigger 觸發器，那你可能會有個 `AzureWebJobsStorage` 應用程式設定，這個設定通常與 `AzureWebJobsDashboard` 是相同的，但有些開發人員非常有可能會直接參考 `AzureWebJobsDashboard` 這個應用程式設定來取得 Storage account 的連接字串，雖然這種狀況比較少見，但還是要特別注意一下，建議確認後再刪除這個 `AzureWebJobsDashboard` 應用程式設定。

### 相關連結

-   [Configure monitoring for Azure Functions | Microsoft Learn](https://learn.microsoft.com/en-us/azure/azure-functions/configure-monitoring?tabs=v2&WT.mc_id=DT-MVP-4015686#disable-built-in-logging)
-   [App settings reference for Azure Functions | Microsoft Learn](https://learn.microsoft.com/en-us/azure/azure-functions/functions-app-settings?WT.mc_id=DT-MVP-4015686#azurewebjobsdashboard)
