Aracılığıyla paylaş


Örnek: Prometheus, Grafana ve Jaeger ile OpenTelemetry kullanma

Bu örnekte ölçüm koleksiyonu için Prometheus, pano oluşturmak için Grafana ve dağıtılmış izlemeyi göstermek için Jaeger kullanılır.

1. Projeyi oluşturma

Visual Studio'da ASP.NET Core Empty şablonunu veya aşağıdaki .NET CLI komutunu kullanarak basit bir web API'si projesi oluşturun:

dotnet new web

2. Ölçüm ve etkinlik tanımları ekleme

Aşağıdaki kod, API'nin çağrılma sayısı için yeni bir ölçüm (greetings.count) ve yeni bir etkinlik kaynağı (OtPrGrYa.Example) tanımlar.

// Custom metrics for the application
var greeterMeter = new Meter("OtPrGrYa.Example", "1.0.0");
var countGreetings = greeterMeter.CreateCounter<int>("greetings.count", description: "Counts the number of greetings");

// Custom ActivitySource for the application
var greeterActivitySource = new ActivitySource("OtPrGrJa.Example");

3. API uç noktası oluşturma

app.MapGet("/", SendGreeting);
async Task<string> SendGreeting(ILogger<Program> logger)
{
    // Create a new Activity scoped to the method
    using var activity = greeterActivitySource.StartActivity("GreeterActivity");

    // Log a message
    logger.LogInformation("Sending greeting");

    // Increment the custom counter
    countGreetings.Add(1);

    // Add a tag to the Activity
    activity?.SetTag("greeting", "Hello World!");

    return "Hello World!";
}

Not

API tanımı OpenTelemetry'ye özgü bir şey kullanmaz. Gözlemlenebilirlik için .NET API'lerini kullanır.

4. OpenTelemetry paketlerine başvurun

Aşağıdaki NuGet paketlerini eklemek için NuGet Paket Yöneticisi veya komut satırını kullanın:

<ItemGroup>
    <PackageReference Include="OpenTelemetry.Exporter.Console" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Exporter.Prometheus.AspNetCore" Version="1.9.0-beta.2" />
    <PackageReference Include="OpenTelemetry.Exporter.Zipkin" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Extensions.Hosting" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" Version="1.9.0" />
    <PackageReference Include="OpenTelemetry.Instrumentation.Http" Version="1.9.0" />
</ItemGroup>

Not

OTel API'leri sürekli geliştikçe en son sürümleri kullanın.

5. OpenTelemetry'yi doğru sağlayıcılarla yapılandırın

var tracingOtlpEndpoint = builder.Configuration["OTLP_ENDPOINT_URL"];
var otel = builder.Services.AddOpenTelemetry();

// Configure OpenTelemetry Resources with the application name
otel.ConfigureResource(resource => resource
    .AddService(serviceName: builder.Environment.ApplicationName));

// Add Metrics for ASP.NET Core and our custom metrics and export to Prometheus
otel.WithMetrics(metrics => metrics
    // Metrics provider from OpenTelemetry
    .AddAspNetCoreInstrumentation()
    .AddMeter(greeterMeter.Name)
    // Metrics provides by ASP.NET Core in .NET 8
    .AddMeter("Microsoft.AspNetCore.Hosting")
    .AddMeter("Microsoft.AspNetCore.Server.Kestrel")
    // Metrics provided by System.Net libraries
    .AddMeter("System.Net.Http")
    .AddMeter("System.Net.NameResolution")
    .AddPrometheusExporter());

// Add Tracing for ASP.NET Core and our custom ActivitySource and export to Jaeger
otel.WithTracing(tracing =>
{
    tracing.AddAspNetCoreInstrumentation();
    tracing.AddHttpClientInstrumentation();
    tracing.AddSource(greeterActivitySource.Name);
    if (tracingOtlpEndpoint != null)
    {
        tracing.AddOtlpExporter(otlpOptions =>
         {
             otlpOptions.Endpoint = new Uri(tracingOtlpEndpoint);
         });
    }
    else
    {
        tracing.AddConsoleExporter();
    }
});

Bu kod, ASP.NET Core'dan ölçümleri ve etkinlikleri almak için ASP.NET Core izlemesini kullanır. Ayrıca ve sağlayıcılarını Metrics ActivitySource sırasıyla ölçümler ve izleme için kaydeder.

Kod, uç noktayı barındırmak için ASP.NET Core kullanan Ölçümler için Prometheus dışarı aktarmayı kullanır, bu nedenle şunları da eklemeniz gerekir:

// Configure the Prometheus scraping endpoint
app.MapPrometheusScrapingEndpoint();

6. Projeyi çalıştırma

Projeyi çalıştırın ve ardından tarayıcı veya curl ile API'ye erişin.

curl -k http://localhost:7275

Sayfayı her istediğinizde, yapılan karşılama sayısı artacaktır. yolu /metricsile aynı temel URL'yi kullanarak ölçüm uç noktasına erişebilirsiniz.

6.1 Günlük çıkışı

Koddaki günlük deyimleri kullanılarak ILoggerçıkıştır. Varsayılan olarak, çıktının konsola yönlendirilmesi için Konsol Sağlayıcısı etkinleştirilir.

Günlüklerin .NET'ten nasıl çıkarılacağına ilişkin birkaç seçenek vardır:

  • stdoutve stderr çıkışı Kubernetes gibi kapsayıcı sistemleri tarafından günlük dosyalarına yönlendirilir.
  • Bunlar, ILogger ile tümleştirilecek günlük kitaplıklarını kullanarak Serilog veya NLog içerir.
  • OtLP veya Azure İzleyici dışarıyı vereni gibi OTel için günlüğe kaydetme sağlayıcılarının kullanılması aşağıda daha ayrıntılı olarak gösterilmiştir.

6.2 Ölçümlere erişme

Uç noktayı kullanarak /metrics ölçümlere erişebilirsiniz.

curl -k https://localhost:7275/
Hello World!

curl -k https://localhost:7275/metrics
# TYPE greetings_count counter
# HELP greetings_count Counts the number of greetings
greetings_count 1 1686894204856

# TYPE current_connections gauge
# HELP current_connections Number of connections that are currently active on the server.
current_connections{endpoint="127.0.0.1:7275"} 1 1686894204856
current_connections{endpoint="[::1]:7275"} 0 1686894204856
current_connections{endpoint="[::1]:5212"} 1 1686894204856
...

Ölçüm çıkışı, uç nokta istenildiğinde ölçümlerin anlık görüntüsüdür. Sonuçlar, insan tarafından okunabilir ancak Prometheus tarafından daha iyi anlaşılabilen Prometheus edat biçiminde sağlanır. Bu konu bir sonraki aşamada ele alınmıştır.

6.3 İzlemeye erişme

Sunucunun konsoluna bakarsanız, bilgileri okunabilir bir biçimde veren konsol izlemesini veren çıktıyı görürsünüz. Bu, biri özel ActivitySourceve diğeri de ASP.NET Core'dan iki etkinlik göstermelidir:

Activity.TraceId:            2e00dd5e258d33fe691b965607b91d18
Activity.SpanId:             3b7a891f55b97f1a
Activity.TraceFlags:         Recorded
Activity.ParentSpanId:       645071fd0011faac
Activity.ActivitySourceName: OtPrGrYa.Example
Activity.DisplayName:        GreeterActivity
Activity.Kind:               Internal
Activity.StartTime:          2023-06-16T04:50:26.7675469Z
Activity.Duration:           00:00:00.0023974
Activity.Tags:
    greeting: Hello World!
Resource associated with Activity:
    service.name: OTel-Prometheus-Grafana-Jaeger
    service.instance.id: e1afb619-bc32-48d8-b71f-ee196dc2a76a
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.5.0

Activity.TraceId:            2e00dd5e258d33fe691b965607b91d18
Activity.SpanId:             645071fd0011faac
Activity.TraceFlags:         Recorded
Activity.ActivitySourceName: Microsoft.AspNetCore
Activity.DisplayName:        /
Activity.Kind:               Server
Activity.StartTime:          2023-06-16T04:50:26.7672615Z
Activity.Duration:           00:00:00.0121259
Activity.Tags:
    net.host.name: localhost
    net.host.port: 7275
    http.method: GET
    http.scheme: https
    http.target: /
    http.url: https://localhost:7275/
    http.flavor: 1.1
    http.user_agent: curl/8.0.1
    http.status_code: 200
Resource associated with Activity:
    service.name: OTel-Prometheus-Grafana-Jaeger
    service.instance.id: e1afb619-bc32-48d8-b71f-ee196dc2a76a
    telemetry.sdk.name: opentelemetry
    telemetry.sdk.language: dotnet
    telemetry.sdk.version: 1.5.0

Birincisi, oluşturduğunuz iç özel etkinliktir. İkincisi, istek için ASP.NET tarafından oluşturulur ve HTTP isteği özellikleri için etiketler içerir. Her ikisinin de tek bir işlemi tanımlayan aynı TraceIdöğesine sahip olduğunu ve dağıtılmış bir sistemde bir işlemde yer alan her hizmetten gelen izlemeleri ilişkilendirmek için kullanılabileceğini göreceksiniz. Kimlikler HTTP üst bilgileri olarak iletilir. ASP.NET Core, istek aldığında hiçbiri yoksa bir atar TraceId . HttpClient , giden isteklerde varsayılan olarak üst bilgileri içerir. Her etkinliğin, her etkinliği benzersiz olarak tanımlayan ve SpanId birleşimi TraceId olan bir SpanIddeğeri vardır. Etkinliğin Greeter üst öğesi, http etkinliğininkiyle ParentSpanIdeşlenen SpanId aracılığıyla HTTP etkinliğine yönlendirilir.

Sonraki bir aşamada, dağıtılmış izlemeleri görselleştirmek için bu verileri Jaeger'a aktaracaksınız.

7. Prometheus ile ölçüm toplama

Prometheus bir ölçüm koleksiyonu, toplama ve zaman serisi veritabanı sistemidir. Bunu her hizmetin ölçüm uç noktalarıyla yapılandırdığınızda, değerleri düzenli aralıklarla kazır ve zaman serisi veritabanında depolar. Daha sonra bunları gerektiği gibi çözümleyebilir ve işleyebilirsiniz.

Prometheus biçiminde kullanıma sunulan ölçüm verileri, işlemin ölçümlerinin belirli bir noktaya anlık görüntüsüdür. Ölçüm uç noktasına her istek yapıldığında geçerli değerleri bildirir. Geçerli değerler ilgi çekici olsa da, eğilimleri görmek ve değerlerin anormal olup olmadığını algılamak için geçmiş değerlerle karşılaştırıldığında daha değerli hale gelirler. Genellikle hizmetler, tatil alışverişleri gibi günün saatlerine veya dünya etkinliklerine göre kullanım artışları gösterir. Değerleri geçmiş eğilimlerle karşılaştırarak, bunların anormal olup olmadığını veya bir ölçümün zaman içinde yavaş yavaş kötüleşmesi durumunu algılayabilirsiniz.

İşlem, bu ölçüm anlık görüntülerinin geçmişini depolamaz. Bu özelliğin işleme eklenmesi yoğun kaynak kullanımlı olabilir. Ayrıca, dağıtılmış bir sistemde genellikle her düğümün birden çok örneğine sahip olursunuz, bu nedenle tüm ölçümlerden ölçümleri toplamak ve ardından bunların geçmiş değerleriyle karşılaştırmak istersiniz.

7.1 Prometheus'u yükleme ve yapılandırma

Platformunuz için Prometheus'ı indirin https://prometheus.io/download/ ve indirmenin içeriğini ayıklayın.

Http uç noktasının bağlantı noktası numarasını almak için çalışan sunucunuzun çıktısının en üstüne bakın. Örneğin:

info: Microsoft.Hosting.Lifetime[14]
      Now listening on: https://localhost:7275
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5212

HTTP kazıma uç noktanızın bağlantı noktasını belirtmek ve daha düşük bir kazıma aralığı ayarlamak için Prometheus YAML yapılandırma dosyasını değiştirin. Örneğin:

  scrape_configs:
  # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
  - job_name: "prometheus"

    # metrics_path defaults to '/metrics'
    # scheme defaults to 'http'.

    scrape_interval: 1s # poll very quickly for a more responsive demo
    static_configs:
      - targets: ["localhost:5212"]

Prometheus'ı başlatın ve üzerinde çalıştığı bağlantı noktasının çıkışını (genellikle 9090) arayın:

>prometheus.exe
...
ts=2023-06-16T05:29:02.789Z caller=web.go:562 level=info component=web msg="Start listening for connections" address=0.0.0.0:9090

Bu URL'yi tarayıcınızda açın. Prometheus kullanıcı arabiriminde artık ölçümlerinizi sorgulayabilmeniz gerekir. Kullanılabilir tüm ölçümleri gösteren ölçüm gezginini açmak için aşağıdaki görüntüde vurgulanan düğmeyi kullanın.

Prometheus Ölçüm Gezgini

Değerlerin greetings_count grafiğini görmek için ölçümü seçin.

greetings_count grafiği

8. Ölçüm panosu oluşturmak için Grafana kullanın

Grafana, Prometheus veya diğer veri kaynaklarını temel alan panolar ve uyarılar oluşturabilen bir pano oluşturma ürünüdür.

Platformunuzun yönergelerini izleyerek Grafana'nın https://grafana.com/oss/grafana/ OSS sürümünü indirin ve yükleyin. Grafana yüklendikten sonra genellikle 3000 numaralı bağlantı noktasında çalıştırılır, bu nedenle tarayıcınızda açın http://localhost:3000 . Oturum açmanız gerekir; varsayılan kullanıcı adı ve parola her ikisi de adminolur.

Hamburger menüsünden bağlantıları seçin ve ardından uç nokta türünüzü seçmek için metni prometheus girin. Yeni bir veri kaynağı eklemek için Prometheus veri kaynağı oluştur'u seçin.

Prometheus ile Grafana bağlantısı

Aşağıdaki özellikleri ayarlamanız gerekir:

  • Prometheus sunucusu URL'si: http://localhost:9090/ bağlantı noktasını uygun şekilde değiştirme

Yapılandırmayı doğrulamak için Kaydet ve Test'i seçin.

Başarılı iletisi aldıktan sonra bir pano yapılandırabilirsiniz. Başarı iletisi için açılan pencerede gösterilen pano oluşturma bağlantısına tıklayın.

Görselleştirme Ekle'yi seçin ve ardından veri kaynağı olarak yeni eklediğiniz Prometheus veri kaynağını seçin.

Pano paneli tasarımcısı görünmelidir. Ekranın alt yarısında sorguyu tanımlayabilirsiniz.

greetings_count kullanarak Grafana sorgusu

greetings_count Ölçümleri seçin ve ardından sonuçları görmek için Sorguları Çalıştır'ı seçin.

Grafana ile istediğiniz sayıda ölçümü izleyecek gelişmiş panolar tasarlayabilirsiniz.

.NET'teki her ölçüm, verileri bölümlendirmek için kullanılabilecek anahtar-değer çiftleri olan ek boyutlara sahip olabilir. ASP.NET ölçümlerinin tümü sayaç için geçerli olan bir dizi boyuta sahiptir. Örneğin, sayacı Microsoft.AspNetCore.Hosting aşağıdaki current-requests boyutlara sahiptir:

Öznitelik Type Açıklama Örnekler İletişim durumu
method string HTTP isteği yöntemi. GET; POST; HEAD Her zaman
scheme string Kullanılan protokolü tanımlayan URI düzeni. http; https Her zaman
host string İsteği alan yerel HTTP sunucusunun adı. localhost Her zaman
port int İsteği alan yerel HTTP sunucusunun bağlantı noktası. 8080 Varsayılan değilse eklenir (http için 80 veya https için 443)

Grafana'daki grafikler genellikle her benzersiz boyut bileşimine göre bölümlenir. Boyutlar Grafana sorgularında verileri filtrelemek veya toplamak için kullanılabilir. Örneğin, grafiğini çizerseniz current_requests, değerlerin her boyut bileşimine göre bölümlendiğini görürsünüz. Yalnızca konağa göre filtrelemek için bir işlemi Sum ekleyin ve etiket değeri olarak kullanın host .

Ev sahibine göre Grafana current_requests

9. Jaeger ile dağıtılmış izleme

6. adımda, dağıtılmış izleme bilgilerinin konsola açık olduğunu gördünüz. Bu bilgiler, etkinliklerle çalışma birimlerini izler. Bir isteğin işlenmesini temsil eden ASP.NET gibi bazı etkinlikler platform tarafından otomatik olarak oluşturulur ve kitaplıklar ve uygulama kodu da etkinlikler oluşturabilir. Selamlama örneği bir Greeter etkinlik içerir. Etkinlikler , SpanIdve ParentId etiketleri kullanılarak TraceIdilişkilendirilir.

Dağıtılmış sistemdeki her işlem kendi etkinlik bilgileri akışını oluşturur ve ölçümler gibi, her işlem için yapılan işi görselleştirmek için etkinlikleri toplamak, depolamak ve ilişkilendirmek için bir sisteme ihtiyacınız vardır. Jaeger, bu koleksiyonu ve görselleştirmeyi etkinleştirmeye yönelik açık kaynak bir projedir.

Platformunuz için Jaeger'ın en son ikili dağıtım arşivini adresinden https://www.jaegertracing.io/download/indirin.

Ardından indirmeyi kolayca erişebileceğiniz yerel bir konuma ayıklayın. jaeger-all-in-one(.exe) yürütülebilir dosyasını çalıştırın:

./jaeger-all-in-one --collector.otlp.enabled

gRPC aracılığıyla OTLP trafiğini dinlediği bağlantı noktasını bulmak için konsol çıkışına bakın. Örneğin:

{"level":"info","ts":1686963686.3854616,"caller":"otlpreceiver@v0.78.2/otlp.go:83","msg":"Starting GRPC server","endpoint":"0.0.0.0:4317"}

Bu çıkış, 0.0.0.0:4317üzerinde dinlediğini bildirir, böylece bu bağlantı noktasını OTLP dışarı aktarıcınızın hedefi olarak yapılandırabilirsiniz.

AppSettings.json Projemizin dosyasını açın ve varsa bağlantı noktasını değiştirerek aşağıdaki satırı ekleyin.

"OTLP_ENDPOINT_URL" :  "http://localhost:4317/"

Özellik değişikliğini alabilmesi ve izleme bilgilerini Jaeger'a yönlendirmeye başlayabilmesi için karşılama işlemini yeniden başlatın.

Artık Jaeger kullanıcı arabirimini http://localhost:16686/ bir web tarayıcısından görebilmeniz gerekir.

İzlemeler için Jaeger sorgusu

İzlemelerin listesini görmek için Hizmet açılan listesinden öğesini seçinOTel-Prometheus-grafana-Jaeger. İzleme seçildiğinde, bu izlemenin bir parçası olarak etkinliklerin gantt grafiği gösterilmelidir. İşlemlerin her birine tıklanması, etkinlik hakkında daha fazla ayrıntı gösterir.

Jaeger İşlem Ayrıntıları

Dağıtılmış bir sistemde, tüm işlemlerden izlemeleri aynı Jaeger yüklemesine göndermek istiyorsunuz, böylece işlemlerle sistem arasında bağıntı kurmasını sağlayabilirsiniz.

Uygulamanızın kendisine HTTP çağrıları yapmasını sağlayarak biraz daha ilginç hale getirebilirsiniz.

  • Uygulamaya fabrika HttpClient ekleme

    builder.Services.AddHttpClient();
    
  • İç içe tebrik çağrıları yapmak için yeni bir uç nokta ekleme

    app.MapGet("/NestedGreeting", SendNestedGreeting);
    
  • Uç noktayı uygulayarak aynı zamanda izleyebileceğiniz HTTP çağrıları yapmalarını sağlayın. Bu durumda yapay bir döngüde (yalnızca tanıtım senaryoları için geçerlidir) kendisine geri çağrır.

    async Task SendNestedGreeting(int nestlevel, ILogger<Program> logger, HttpContext context, IHttpClientFactory clientFactory)
    {
        // Create a new Activity scoped to the method
        using var activity = greeterActivitySource.StartActivity("GreeterActivity");
    
        if (nestlevel <= 5)
        {
            // Log a message
            logger.LogInformation("Sending greeting, level {nestlevel}", nestlevel);
    
            // Increment the custom counter
            countGreetings.Add(1);
    
            // Add a tag to the Activity
            activity?.SetTag("nest-level", nestlevel);
    
            await context.Response.WriteAsync($"Nested Greeting, level: {nestlevel}\r\n");
    
            if (nestlevel > 0)
            {
                var request = context.Request;
                var url = new Uri($"{request.Scheme}://{request.Host}{request.Path}?nestlevel={nestlevel - 1}");
    
                // Makes an http call passing the activity information as http headers
                var nestedResult = await clientFactory.CreateClient().GetStringAsync(url);
                await context.Response.WriteAsync(nestedResult);
            }
        }
        else
        {
            // Log a message
            logger.LogError("Greeting nest level {nestlevel} too high", nestlevel);
            await context.Response.WriteAsync("Nest level too high, max is 5");
        }
    }
    

Her düzey önceki çağrının yanıtını beklediğinden istekler için piramit şeklinde daha ilginç bir grafik elde edilir.

Jaeger iç içe bağımlılık sonuçları