共用方式為


.NET 和 .NET Core 中的自訂計量集合

Azure 監視器 Application Insights .NET 和 .NET Core SDK 有兩種不同方法可收集自訂計量:TrackMetric()GetMetric()。 這兩種方法之間的主要差異是本機彙總。 TrackMetric() 方法缺少預先彙總。 GetMetric() 方法有預先彙總。 建議使用彙總,因此 TrackMetric() 不再是收集自訂計量的慣用方法。 此文章將逐步引導您使用 GetMetric() 方法,以及其運作方式背後的一些原理。

警告

我們建議為新應用程式或客戶提供 Azure 監視器 Application InsightsAzure 監視器 OpenTelemetry 散發版本。 Azure 監視器 OpenTelemetry 散發版本提供與 Application Insights SDK 類似的功能和體驗。 您可以使用適用於 .NETNode.jsPython 的移轉指南,從 Application Insights SDK 移轉,但我們仍在努力新增更多功能以提供回溯相容性。

預先彙總與非預先彙總 API

TrackMetric() 方法會傳送代表計量的原始遙測。 針對每個值傳送單一遙測項目的效率不佳。 TrackMetric() 方法在效能方面的效率也不佳,因為每個 TrackMetric(item) 都要經過遙測初始設定式和處理器的完整 SDK 管線。

不同於 TrackMetric()GetMetric() 會為您處理本機預先彙總,然後只以一分鐘的固定間隔提交彙總的摘要計量。 如果您需要以秒或甚至毫秒層級密切監視某些自訂計量,您可以執行此動作,同時僅會產生每分鐘只監視一次的儲存體和網路流量成本。 此行為也可大幅降低發生節流的風險,因為需要針對彙總計量傳送的遙測項目總數會大幅降低。

在 Application Insights 中,透過 TrackMetric()GetMetric() 收集的自訂計量不會受到取樣影響。 針對重要計量進行取樣,可能導致警示您圍繞那些計量所建置的案例變得不可靠。 由於絕對不會針對您的自訂計量進行取樣,因此,您通常能夠確信當警示閾值有缺口時,就會引發警示。 因為不會針對自訂計量進行取樣,所以有一些潛在的疑慮。

逐秒追蹤計量中的趨勢,或使用更精細的間隔,可能會導致:

  • 增加資料儲存體成本。 傳送至 Azure 監視器的資料量會產生相關聯的成本。 您傳送的資料越多,整體監視成本就越高。
  • 增加網路流量或效能額外負荷。 在某些情況下,此額外負荷可能同時帶來費用與應用程式效能成本。
  • 擷取節流的風險。 您的應用程式在短時間內傳送高比率的遙測時,Azure 監視器就會捨棄 (「節流」) 資料點。

節流可能會導致警示闕漏,是一項顧慮。 觸發警示的條件可能會在本地發生,但隨後在擷取端點上可能因傳送的資料過多而遭到卸除。 除非您實作了自己的本機彙總邏輯,否則不建議對 .NET 和 .NET Core 使用 TrackMetric()。 如果您嘗試追蹤每個會在指定時段發生事件的執行個體,則可能發現 TrackEvent() 更適合。 請記住,與自訂計量不同,自訂事件需要進行取樣。 即使您未撰寫自己的本機預先彙總,仍然可以使用 TrackMetric()。 但是,如果您這麼做,請注意其缺陷。

總而言之,建議使用 GetMetric(),因為它會執行預先彙總,所以會累積來自全部 Track() 呼叫的值,且每分鐘傳送摘要/彙總一次。 GetMetric() 方法可透過傳送較少資料點,同時仍能收集全部相關資訊,大幅降低成本和效能額外負荷。

注意

只有 .NET 和 .NET Core SDK 具有 GetMetric() 方法。 如果您使用 Java,請參閱使用 Micrometer 傳送自訂計量。 針對 JavaScript 和 Node.js,您仍可使用 TrackMetric(),但請記住上一節概述的注意事項。 針對 Python,您可以使用 OpenCensus.stats 來傳送自訂計量,但計量實作不同。

開始使用 GetMetric

在我們的範例中,將使用基本的 .NET Core 3.1 背景工作服務應用程式。 如果您想要複寫用於這些範例的測試環境,請遵循監視背景工作角色服務一文的步驟 1-6。 這些步驟會將 Application Insights 新增至基本背景工作角色服務專案範本。 這些概念適用於任何可使用 SDK 的一般應用程式,包括 Web 應用程式和主控台應用程式。

傳送計量

以下列程式碼取代 worker.cs 檔案的內容:

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.ApplicationInsights;

namespace WorkerService3
{
    public class Worker : BackgroundService
    {
        private readonly ILogger<Worker> _logger;
        private TelemetryClient _telemetryClient;

        public Worker(ILogger<Worker> logger, TelemetryClient tc)
        {
            _logger = logger;
            _telemetryClient = tc;
        }

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {   // The following line demonstrates usages of GetMetric API.
            // Here "computersSold", a custom metric name, is being tracked with a value of 42 every second.
            while (!stoppingToken.IsCancellationRequested)
            {
                _telemetryClient.GetMetric("ComputersSold").TrackValue(42);

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(1000, stoppingToken);
            }
        }
    }
}

執行範例程式碼時,您會看到 while 迴圈重複執行,且 Visual Studio 輸出視窗中不會傳送任何遙測。 單一遙測項目會在 60 秒左右傳送,在我們的測試中顯示如下:

Application Insights Telemetry: {"name":"Microsoft.ApplicationInsights.Dev.00000000-0000-0000-0000-000000000000.Metric", "time":"2019-12-28T00:54:19.0000000Z",
"ikey":"00000000-0000-0000-0000-000000000000",
"tags":{"ai.application.ver":"1.0.0.0",
"ai.cloud.roleInstance":"Test-Computer-Name",
"ai.internal.sdkVersion":"m-agg2c:2.12.0-21496",
"ai.internal.nodeName":"Test-Computer-Name"},
"data":{"baseType":"MetricData",
"baseData":{"ver":2,"metrics":[{"name":"ComputersSold",
"kind":"Aggregation",
"value":1722,
"count":41,
"min":42,
"max":42,
"stdDev":0}],
"properties":{"_MS.AggregationIntervalMs":"42000",
"DeveloperMode":"true"}}}}

此單一遙測項目代表 41 個相異公制度量單位的彙總。 由於我們反覆傳送相同值,因此,我們的「標準差 (stDev))」為 0,且最大值 (max) 和最小值 (min) 的值完全相同。 value 屬性代表已彙總的全部個別值總和。

注意

GetMetric 不支援追蹤最後一個值 (例如,gauge) 或追蹤長條圖或分佈。

如果我們檢查 [記錄 (分析)] 體驗中的 Application Insights 資源,個別遙測項目下列螢幕擷取畫面所示。

螢幕擷取畫面:顯示 Log Analytics 查詢檢視。

注意

儘管原始遙測項目並未在內嵌後包含明確的總和屬性/欄位,但我們會為您建立一個。 在此情況下,valuevalueSum 屬性都代表同一個項目。

您也可以在入口網站的 [計量] 區段中存取自訂計量遙測,做為記錄型和自訂計量。 下列螢幕擷取畫面是記錄型計量的範例。

螢幕擷取畫面:顯示計量瀏覽器檢視。

適用於高輸送量用途的快取計量參考

在某些情況下,可能會經常觀察到計量值。 例如,處理每秒 500 個要求的高輸送量服務,可能想要針對每個要求發出 20 個遙測計量。 此結果表示每秒會追蹤 10,000 個值。 在這類高輸送量案例中,使用者可能需要避免某些查閱來協助 SDK。

例如,上述範例對計量 ComputersSold 執行控制代碼的查閱,然後追蹤觀察到的值 42。 相反地,可能會快取多個追蹤叫用的控制代碼:

//...

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is where the cache is stored to handle faster lookup
            Metric computersSold = _telemetryClient.GetMetric("ComputersSold");
            while (!stoppingToken.IsCancellationRequested)
            {

                computersSold.TrackValue(42);

                computersSold.TrackValue(142);

                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(50, stoppingToken);
            }
        }

除了快取計量控制代碼之外,上述範例也將 Task.Delay 縮減為 50 毫秒,讓迴圈執行頻率更高。 結果產生 772 次 TrackValue() 叫用。

多維度計量

上一節的範例顯示零維度計量。 計量也可以是多維度的。 目前最多支援 10 個維度。

以下是如何建立一維計量的範例:

//...

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            // This is an example of a metric with a single dimension.
            // FormFactor is the name of the dimension.
            Metric computersSold= _telemetryClient.GetMetric("ComputersSold", "FormFactor");

            while (!stoppingToken.IsCancellationRequested)
            {
                // The number of arguments (dimension values)
                // must match the number of dimensions specified while GetMetric.
                // Laptop, Tablet, etc are values for the dimension "FormFactor"
                computersSold.TrackValue(42, "Laptop");
                computersSold.TrackValue(20, "Tablet");
                computersSold.TrackValue(126, "Desktop");


                _logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
                await Task.Delay(50, stoppingToken);
            }
        }

執行範例程式碼至少 60 秒會導致三個不同的遙測項目傳送至 Azure。 每個項目都代表三種尺寸之一的彙總。 和之前一樣,您可以在 [記錄 (分析)] 檢視中進一步檢查。

螢幕擷取畫面:多維度計量的 Log Analytics 檢視。

在計量瀏覽器中:

螢幕擷取畫面:顯示自訂計量。

請注意,您無法依新的自訂維度分割計量,或使用計量檢視來檢視自訂維度。

螢幕擷取畫面:顯示分割支援。

根據預設,不會在 Application Insights 資源中開啟計量瀏覽器中的多維度計量。

啟用多維度計量

若要為 Application Insights 資源啟用多維度計量,請選取 [使用量和估計成本]>[自訂計量]>[啟用自訂計量維度的警示]>[確定]。 如需詳細資訊,請參閱自訂計量維度和預先彙總

在您進行該變更並傳送新的多維度遙測之後,您可以選取 [套用分割]

注意

只有在入口網站中開啟該功能之後新傳送的計量才會儲存維度。

螢幕擷取畫面:顯示套用分割。

檢視每個 FormFactor 維度的計量彙總。

螢幕擷取畫面:顯示表單因素。

在有三個以上的維度時使用 MetricIdentifier

目前支援 10 個維度。 超過 3 個維度需要使用 MetricIdentifier

// Add "using Microsoft.ApplicationInsights.Metrics;" to use MetricIdentifier
// MetricIdentifier id = new MetricIdentifier("[metricNamespace]","[metricId],"[dim1]","[dim2]","[dim3]","[dim4]","[dim5]");
MetricIdentifier id = new MetricIdentifier("CustomMetricNamespace","ComputerSold", "FormFactor", "GraphicsCard", "MemorySpeed", "BatteryCapacity", "StorageCapacity");
Metric computersSold  = _telemetryClient.GetMetric(id);
computersSold.TrackValue(110,"Laptop", "Nvidia", "DDR4", "39Wh", "1TB");

自訂計量設定

如果您想要更改計量設定,就必須在計量進行初始化的位置執行更改。

特殊維度名稱

計量不會使用用來存取這些計量的 TelemetryClient 之中的遙測內容。 使用 MetricDimensionNames 類別中做為常數的特殊維度名稱是這項限制的最佳因應措施。

下列 Special Operation Request Size 計量所傳送的計量 總不會Context.Operation.Name 設定為 Special OperationTrackMetric() 方法或其他任何 TrackXXX() 方法會將 OperationName 正確設定為 Special Operation

        //...
        TelemetryClient specialClient;
        private static int GetCurrentRequestSize()
        {
            // Do stuff
            return 1100;
        }
        int requestSize = GetCurrentRequestSize()

        protected override async Task ExecuteAsync(CancellationToken stoppingToken)
        {
            while (!stoppingToken.IsCancellationRequested)
            {
                //...
                specialClient.Context.Operation.Name = "Special Operation";
                specialClient.GetMetric("Special Operation Request Size").TrackValue(requestSize);
                //...
            }
                   
        }

在此情況下,請使用 MetricDimensionNames 類別中所列的特殊維度名稱來指定 TelemetryContext 值。

例如,在將下一個陳述式所產生的計量彙總傳送到 Application Insights 雲端端點時,其中的 Context.Operation.Name 資料欄位將設定為 Special Operation

_telemetryClient.GetMetric("Request Size", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation");

此特殊維度的值將複製到 TelemetryContext,而且不會當做「正常」維度使用。 如果您想要讓作業維度保持正常計量探索,則必須基於該目的建立個別維度:

_telemetryClient.GetMetric("Request Size", "Operation Name", MetricDimensionNames.TelemetryContext.Operation.Name).TrackValue(requestSize, "Special Operation", "Special Operation");

維度和時間序列上限

若要防止遙測子系統意外使用您的資源,您可以控制每個計量的資料數列數目上限。 預設限制為每個計量不超過 1000 個資料數列總數,而且每個維度不超過 100 個不同值。

重要

請對維度使用低基數值,以避免節流。

在維度和時間序列上限的內容中,我們使用 Metric.TrackValue(..) 來確保會觀察到限制。 如果已達到限制,Metric.TrackValue(..) 將傳回 False 且不會追蹤值。 否則會傳回 True。 如果計量的資料源自使用者輸入,此行為將有其效用。

MetricConfiguration 建構函式採用一些選項,說明如何在個別計量內管理不同數列,以及實作 IMetricSeriesConfiguration 的類別物件,以指定計量每個個別數列的彙總行為:

var metConfig = new MetricConfiguration(seriesCountLimit: 100, valuesPerDimensionLimit:2,
                new MetricSeriesConfigurationForMeasurement(restrictToUInt32Values: false));

Metric computersSold = _telemetryClient.GetMetric("ComputersSold", "Dimension1", "Dimension2", metConfig);

// Start tracking.
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value1");
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value2");

// The following call gives 3rd unique value for dimension2, which is above the limit of 2.
computersSold.TrackValue(100, "Dim1Value1", "Dim2Value3");
// The above call does not track the metric, and returns false.
  • seriesCountLimit 是計量可包含的資料時間序列數目上限。 達到此限制時,對 TrackValue() 的呼叫通常會導致新序列傳回 false
  • valuesPerDimensionLimit 會以類似方式來限制每個維度的相異值數目。
  • restrictToUInt32Values 會判斷是否應該追蹤非負整數值。

以下範例說明如何傳送訊息,以了解是否已超過上限限制:

if (! computersSold.TrackValue(100, "Dim1Value1", "Dim2Value3"))
{
// Add "using Microsoft.ApplicationInsights.DataContract;" to use SeverityLevel.Error
_telemetryClient.TrackTrace("Metric value not tracked as value of one of the dimension exceeded the cap. Revisit the dimensions to ensure they are within the limits",
SeverityLevel.Error);
}

下一步