Kumpulan metrik kustom di .NET dan .NET Core

Azure Monitor Application Insights .NET dan .NET Core SDK memiliki dua metode berbeda untuk mengumpulkan metrik kustom: TrackMetric() dan GetMetric(). Perbedaan utama antara kedua metode ini adalah agregasi lokal. Metode ini TrackMetric() tidak memiliki pra-agregasi. Metode GetMetric() ini memiliki pra-agregasi. Kami menyarankan agar Anda menggunakan agregasi, jadi TrackMetric() bukan lagi metode yang disukai untuk mengumpulkan metrik kustom. Artikel ini memanah Anda menggunakan GetMetric() metode dan beberapa alasan di balik cara kerjanya.

Catatan

Dokumentasi berikut bergantung pada API klasik Application Insights. Rencana jangka panjang untuk Application Insights adalah mengumpulkan data menggunakan OpenTelemetry. Untuk informasi selengkapnya, lihat Mengaktifkan Azure Monitor OpenTelemetry untuk aplikasi .NET, Node.js, Python, dan Java.

API pra-agregasi vs. non-agregasi

Metode ini TrackMetric() mengirim telemetri mentah yang menunjukkan metrik. Tidak efisien untuk mengirim satu item telemetri untuk setiap nilai. Metode TrackMetric() ini juga tidak efisien dalam hal performa karena setiap TrackMetric(item) melalui alur SDK lengkap penginisialisasi telemetri dan prosesor.

Tidak seperti TrackMetric(), GetMetric() menangani pra-agregasi lokal untuk Anda kemudian hanya mengirimkan metrik ringkasan agregat pada interval tetap satu menit. Jika Anda perlu memantau beberapa metrik kustom dengan cermat pada tingkat kedua atau bahkan milidetik, Anda dapat melakukannya sambil hanya menimbulkan biaya penyimpanan dan lalu lintas jaringan hanya pemantauan setiap menit. Perilaku ini juga sangat mengurangi risiko pembatasan yang terjadi karena jumlah total item telemetri yang perlu dikirim untuk metrik yang diagregat jauh berkurang.

Dalam Application Insights, metrik kustom yang dikumpulkan melalui TrackMetric() dan GetMetric() tidak terpengaruh oleh pengambilan sampel. Pengambilan sampel metrik penting dapat menyebabkan skenario di mana pemberitahuan yang mungkin telah Anda buat di sekitar metrik tersebut bisa menjadi tidak dapat diandalkan. Dengan tidak pernah mengambil sampel metrik kustom, Anda umumnya dapat yakin bahwa ketika ambang pemberitahuan Anda dilanggar, pemberitahuan akan muncul. Karena metrik kustom tidak diambil sampelnya, ada beberapa potensi kekhawatiran.

Pelacakan tren dalam metrik setiap detik, atau pada interval yang lebih terperinci, dapat mengakibatkan:

  • Peningkatan biaya penyimpanan data. Ada biaya yang terkait dengan jumlah data yang Anda kirim ke Azure Monitor. Semakin banyak data yang Anda kirim, semakin besar biaya pemantauan secara keseluruhan.
  • Peningkatan lalu lintas jaringan atau overhead performa. Dalam beberapa skenario, overhead ini dapat memiliki biaya performa moneter dan aplikasi.
  • Risiko pembatasan penyerapan. Azure Monitor menghilangkan titik data ("pembatasan") saat aplikasi Anda mengirim tingkat telemetri yang tinggi dalam interval waktu singkat.

Pembatasan menjadi perhatian karena dapat menyebabkan peringatan yang terlewatkan. Kondisi untuk memicu pemberitahuan dapat terjadi secara lokal dan kemudian dihilangkan di titik akhir penyerapan karena terlalu banyak data yang dikirim. Kami tidak merekomendasikan penggunaan TrackMetric() untuk .NET dan .NET Core kecuali Anda telah menerapkan logika agregasi lokal Anda sendiri. Jika Anda mencoba melacak setiap instans peristiwa yang terjadi selama periode waktu tertentu, Anda mungkin menemukan bahwa itu TrackEvent() lebih cocok. Perlu diingat bahwa tidak seperti metrik kustom, peristiwa kustom tunduk pada pengambilan sampel. Anda masih dapat menggunakan TrackMetric() bahkan tanpa menulis pra-agregasi lokal Anda sendiri. Tetapi jika Anda melakukannya, waspadalah terhadap jebakan.

Singkatnya, kami merekomendasikan GetMetric() karena melakukan pra-agregasi, ia mengumpulkan nilai dari semua Track() panggilan, dan mengirim ringkasan/agregat sekali setiap menit. Metode ini GetMetric() dapat secara signifikan mengurangi biaya dan overhead performa dengan mengirim lebih sedikit titik data sambil tetap mengumpulkan semua informasi yang relevan.

Catatan

Hanya .NET dan .NET Core SDK yang memiliki GetMetric() metode . Jika Anda menggunakan Java, lihat Mengirim metrik kustom menggunakan mikrometer. Untuk JavaScript dan Node.js, Anda masih akan menggunakan TrackMetric(), tetapi perlu diingat peringatan yang diuraikan di bagian sebelumnya. Untuk Python, Anda dapat menggunakan OpenCensus.stats untuk mengirim metrik kustom, tetapi implementasi metriknya berbeda.

Mulai menggunakan GetMetric

Untuk contoh, kami akan menggunakan aplikasi layanan pekerja .NET Core 3.1 dasar. Jika Anda ingin mereplikasi lingkungan pengujian yang digunakan dengan contoh ini, ikuti langkah 1-6 di artikel Layanan pekerja pemantauan. Langkah-langkah ini menambahkan Application Insights ke templat proyek layanan pekerja dasar. Konsep berlaku untuk aplikasi umum apa pun di mana SDK dapat digunakan, termasuk aplikasi web dan aplikasi konsol.

Mengirim metrik

Ganti isi file worker.cs Anda dengan kode berikut:

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);
            }
        }
    }
}

Saat Menjalankan kode sampel, Anda akan melihat while perulangan berulang kali dijalankan tanpa telemetri yang dikirim di jendela output Visual Studio. Satu item telemetri dikirim oleh sekitar tanda 60 detik, yang dalam pengujian kami terlihat seperti:

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"}}}}

Item telemetri tunggal ini mewakili agregat 41 pengukuran metrik yang berbeda. Karena kami mengirim nilai yang sama berulang kali, kami memiliki simpangihan standar (stDev) dengan nilai maksimum (max) dan minimum (min) yang identik.0 Properti value mewakili jumlah semua nilai individual yang dikumpulkan.

Catatan

Metode GetMetric ini tidak mendukung pelacakan nilai terakhir (misalnya, gauge) atau melacak histogram atau distribusi.

Jika kita memeriksa sumber daya Application Insights dalam pengalaman Log (Analytics), item telemetri individual akan terlihat seperti cuplikan layar berikut.

Screenshot that shows the Log Analytics query view.

Catatan

Meskipun item telemetri mentah tidak berisi properti/bidang jumlah eksplisit setelah diserap, kami membuatnya untuk Anda. Dalam hal ini, properti value dan valueSum mewakili hal yang sama.

Anda juga dapat mengakses telemetri metrik kustom di bagian Metrik portal sebagai metrik berbasis log dan kustom. Cuplikan layar berikut adalah contoh metrik berbasis log.

Screenshot that shows the Metrics explorer view.

Referensi metrik cache untuk penggunaan throughput tinggi

Nilai metrik mungkin sering diamati dalam beberapa kasus. Misalnya, layanan throughput tinggi yang memproses 500 permintaan per detik mungkin ingin memancarkan 20 metrik telemetri untuk setiap permintaan. Hasilnya berarti melacak 10.000 nilai per detik. Dalam skenario throughput tinggi seperti itu, pengguna mungkin perlu membantu SDK dengan menghindari beberapa pencarian.

Misalnya, contoh sebelumnya melakukan pencarian untuk handel untuk metrik ComputersSold lalu melacak nilai yang diamati dari 42. Sebaliknya, handel mungkin di-cache untuk beberapa pemanggilan trek:

//...

        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);
            }
        }

Selain penembolokan handel metrik, contoh sebelumnya juga berkurang Task.Delay menjadi 50 milidetik sehingga perulangan akan lebih sering dijalankan. Hasilnya adalah 772 TrackValue() pemanggilan.

Metrik multidireksional

Contoh di bagian sebelumnya memperlihatkan metrik tanpa dimensi. Metrik juga bisa multidimensi. Saat ini kami mendukung hingga 10 dimensi.

Berikut contoh cara membuat metrik satu dimensi:

//...

        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);
            }
        }

Menjalankan kode sampel setidaknya selama 60 detik menghasilkan tiga item telemetri berbeda yang dikirim ke Azure. Setiap item mewakili agregasi salah satu dari tiga faktor bentuk. Seperti sebelumnya, Anda dapat memeriksa lebih lanjut dalam tampilan Log (Analitik).

Screenshot that shows the Log Analytics view of multidimensional metric.

Di penjelajah metrik:

Screenshot that shows Custom metrics.

Perhatikan bahwa Anda tidak dapat membagi metrik berdasarkan dimensi kustom baru Anda atau melihat dimensi kustom Anda dengan tampilan metrik.

Screenshot that shows splitting support.

Secara default, metrik multidampingan dalam penjelajah metrik tidak diaktifkan di sumber daya Application Insights.

Mengaktifkan metrik multidireksional

Untuk mengaktifkan metrik multidimensi untuk sumber daya Application Insights, pilih Penggunaan dan perkiraan biaya>Metrik>Kustom Aktifkan pemberitahuan pada dimensi>metrik kustom OK. Untuk informasi selengkapnya, lihat Dimensi metrik kustom dan pra-agregasi.

Setelah Anda membuat perubahan tersebut dan mengirim telemetri multidimensi baru, Anda dapat memilih Terapkan pemisahan.

Catatan

Hanya metrik yang baru dikirim setelah fitur dinyalakan di portal yang akan memiliki dimensi yang disimpan.

Screenshot that shows applying splitting.

Lihat agregasi metrik Anda untuk setiap FormFactor dimensi.

Screenshot that shows form factors.

Gunakan MetricIdentifier saat ada lebih dari tiga dimensi

Saat ini, 10 dimensi didukung. Lebih dari tiga dimensi memerlukan penggunaan 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");

Konfigurasi metrik kustom

Jika Anda ingin mengubah konfigurasi metrik, Anda harus membuat perubahan di tempat metrik diinisialisasi.

Nama dimensi khusus

Metrik tidak menggunakan konteks telemetri yang TelemetryClient digunakan untuk mengaksesnya. Menggunakan nama dimensi khusus yang tersedia sebagai konstanta di MetricDimensionNames kelas adalah solusi terbaik untuk batasan ini.

Agregat metrik yang dikirim oleh metrik berikut Special Operation Request Size tidakContext.Operation.Name akan diatur ke Special Operation. Metode TrackMetric() atau metode lain TrackXXX() akan diatur OperationName dengan benar ke 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);
                //...
            }
                   
        }

Dalam keadaan ini, gunakan nama dimensi khusus yang tercantum di MetricDimensionNames kelas untuk menentukan TelemetryContext nilai.

Misalnya, ketika agregat metrik yang dihasilkan dari pernyataan berikutnya dikirim ke titik akhir cloud Application Insights, bidang datanya Context.Operation.Name akan diatur ke Special Operation:

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

Nilai dimensi khusus ini akan disalin ke dalam TelemetryContext dan tidak akan digunakan sebagai dimensi normal . Jika Anda ingin juga menyimpan dimensi operasi untuk eksplorasi metrik normal, Anda perlu membuat dimensi terpisah untuk tujuan tersebut:

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

Pembatasan dimensi dan rangkaian waktu

Untuk mencegah subsistem telemetri tidak sengaja menggunakan sumber daya, Anda dapat mengontrol jumlah maksimum seri data per metrik. Batas default tidak lebih dari 1.000 total seri data per metrik, dan tidak lebih dari 100 nilai yang berbeda per dimensi.

Penting

Gunakan nilai kardinal rendah untuk dimensi guna menghindari pembatasan.

Dalam konteks pembatasan dimensi dan rangkaian waktu, kami menggunakan Metric.TrackValue(..) untuk memastikan bahwa batas diamati. Jika batas sudah tercapai, Metric.TrackValue(..) pengembalian False dan nilai tidak akan dilacak. Jika tidak, ia kembali True. Perilaku ini berguna jika data untuk metrik berasal dari input pengguna.

Konstruktor MetricConfiguration mengambil beberapa opsi tentang cara mengelola rangkaian yang berbeda dalam metrik masing-masing dan objek dari penerapan kelas IMetricSeriesConfiguration yang menentukan perilaku agregasi untuk setiap rangkaian masing-masing metrik:

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 adalah jumlah maksimum rangkaian waktu data yang dapat dimuat metrik. Ketika batas ini tercapai, panggilan ke TrackValue() yang biasanya akan menghasilkan pengembalian falseseri baru .
  • valuesPerDimensionLimit membatasi jumlah nilai yang berbeda per dimensi dengan cara sama.
  • restrictToUInt32Values menentukan apakah hanya nilai bilangan bulat non-negatif yang harus dilacak atau tidak.

Berikut contoh cara mengirim pesan untuk mengetahui apakah batas terlampaui:

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);
}

Langkah berikutnya