• 17.08.2026 09:26:54
  • Admin Admin

ASP.NET Core servislerinde istek, SQL sorgusu ve dış HTTP çağrılarını aynı trace içinde birleştirmeyi anlatır. .net core eğitimi kapsamında ölçüm, örnekleme ve Collector tarafında maliyet kontrolü için uygulanabilir bir kurulum sunar.

ASP.NET Core Eğitimi: OpenTelemetry ile Dağıtık İz Sürme

asp.net core eğitimi: Trace sınırlarını doğru kurmak

Dağıtık iz sürmenin ilk kuralı, servis sınırlarında aynı W3C trace context bilgisini korumaktır. ASP.NET Core, gelen traceparent başlığından varsayılan olarak bir Activity oluşturur; HttpClient enstrümantasyonu da bu bağlamı destekleyen sonraki servise taşır. Ancak mesaj kuyruğu, özel TCP istemcisi veya elle açılan background işlerde bu zincir otomatik oluşmaz. Bu nedenle uygulama kimliği için OpenTelemetry.Resources, HTTP/EF Core span'ları için ilgili instrumentation paketleri ve Collector'a gönderim için OpenTelemetry.Exporter.OpenTelemetryProtocol eklenmelidir.

using OpenTelemetry.Resources;
using OpenTelemetry.Trace;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenTelemetry()
    .ConfigureResource(resource => resource
        .AddService(serviceName: "orders-api", serviceVersion: "2026.08"))
    .WithTracing(tracing => tracing
        .SetSampler(new ParentBasedSampler(
            new TraceIdRatioBasedSampler(0.10)))
        .AddAspNetCoreInstrumentation(options =>
        {
            options.RecordException = true;
            options.Filter = context =>
                !context.Request.Path.StartsWithSegments("/health");
        })
        .AddHttpClientInstrumentation()
        .AddEntityFrameworkCoreInstrumentation()
        .AddOtlpExporter());

var app = builder.Build();
app.MapGet("/health", () => Results.Ok());
app.Run();

Buradaki ParentBasedSampler ayrıntısı önemlidir: kök trace'lerin yüzde 10'unu alırken, upstream sistemin örneklediği bir isteğin child span'larını düşürmez. Sadece TraceIdRatioBasedSampler(0.10) kullanılırsa upstream'in kayda aldığı bir hatanın bu servisteki SQL span'ı kaybolabilir. /health filtresi de sadece gürültü azaltmak için değil, Kubernetes veya load balancer'ın saniyede bir ürettiği health-check span'larının exporter kuyruğunu doldurmasını engellemek için gereklidir.

.net core kursu için özel span ve kuyruk bağlamı

Domain işlemlerini HTTP span'ının altında görünür yapmak için tek bir paylaşılan ActivitySource tanımlayın ve bunu AddSource ile kaydedin. Tag değerleri düşük kardinaliteli olmalıdır: payment.provider için sabit sağlayıcı adı uygundur; müşteri e-postası, sipariş numarası veya rastgele GUID uygun değildir. Çünkü Jaeger, Tempo ve benzeri trace depoları, yüksek kardinaliteli attribute indeksleri nedeniyle sorgu belleğini ve depolama maliyetini hızla büyütür.

public static class OrderTelemetry
{
    public static readonly ActivitySource Source =
        new("Orders.Domain", "1.0.0");
}

public sealed class PaymentService
{
    public async Task ChargeAsync(string provider, decimal amount, CancellationToken ct)
    {
        using var activity = OrderTelemetry.Source.StartActivity("payment.charge");
        activity?.SetTag("payment.provider", provider); // örn. "stripe"
        activity?.SetTag("payment.currency", "TRY");
        activity?.SetTag("payment.amount", (double)amount);

        try
        {
            await SendToProviderAsync(provider, amount, ct);
        }
        catch (Exception ex)
        {
            activity?.SetStatus(ActivityStatusCode.Error, ex.Message);
            activity?.RecordException(ex);
            throw;
        }
    }
}

Kaynağı tracer pipeline'a eklemeyi unutmak yaygın bir üretim hatasıdır; StartActivity bu durumda dinleyici yoksa null döndürebilir ve custom span hiç export edilmez. Önceki kurulumdaki zincire .AddSource("Orders.Domain") ekleyin. Queue tüketicisinde ayrıca mesaj üretirken Activity.Current?.Id değerini rastgele bir header'a koymak yeterli değildir; W3C traceparent ve varsa tracestate birlikte taşınmalı, tüketicide ActivityContext.TryParse ile parent context kurulmalıdır. Bu yaklaşım özellikle csharp eğitimi ve c# eğitimi içinde arka plan işlerini HTTP isteklerinden bağımsız düşünmeye alışmış ekipler için kritik bir fark yaratır.

entity framework eğitimi: SQL span'larını güvenli ve anlamlı tutmak

EF Core enstrümantasyonu komut süresini ve veritabanı sistemini span'a ekler; fakat ham SQL metnini körlemesine toplamak üretim verisi sızıntısına neden olabilir. Parametreli sorguda bile müşteri e-postası veya telefon numarası literal olarak SQL'e gömülmüş olabilir. Önce sorgu şekillerini TagWith ile sınırlı, denetlenebilir bir adla işaretleyin; trace arayüzünde db.query.name benzeri iş kurallı bir arama yerine EF Core'un oluşturduğu yorum üzerinden sorgu ailesini ayırabilirsiniz.

var openOrders = await db.Orders
    .TagWith("query:open-orders-for-dashboard")
    .Where(x => x.Status == OrderStatus.Open)
    .OrderByDescending(x => x.CreatedAt)
    .Take(50)
    .AsNoTracking()
    .ToListAsync(ct);

AsNoTracking() burada yalnızca alışkanlık olarak eklenmemelidir: dashboard sonucu güncellenmeyecekse change tracker her satır için state entry üretmez. Etkiyi doğrulamak için aynı veri hacmi ve aynı sorgu parametreleriyle önce dotnet-counters monitor --process-id <pid> System.Runtime çalıştırın; alloc-rate, Gen0 sayısı ve time-in-gc değerlerini kaydedin. Ardından yalnızca AsNoTracking() değişikliğiyle testi tekrarlayın. Trace tarafında aynı db.operation ve aynı sorgu etiketi için p95 süreyi karşılaştırın; tahsis düşüp p95 değişmiyorsa darboğaz takipçi değil veritabanı planı veya ağ gecikmesidir. Bu ayrım, entity framework eğitimi sırasında sık görülen 'tracking kapatınca sorgu mutlaka hızlanır' genellemesini engeller.

Örnekleme maliyetini ölçmek ve OpenTelemetry Collector ile ayırmak

Örnekleme oranını tahminle seçmek yerine yük testiyle ölçün. k6 run --vus 80 --duration 5m smoke.js komutunu aynı staging verisi üzerinde iki kez çalıştırın: ilkinde AlwaysOnSampler, ikincisinde yüzde 10 kök örnekleme. Her iki koşulda k6 p95/p99 gecikmesini, dotnet-counters ile System.Runtime tahsis hızını ve Collector'ın kabul ettiği span sayısını kaydedin. Karşılaştırmanın geçerli olması için exporter hedefi, pod replica sayısı, test senaryosu ve SQL veri seti sabit kalmalıdır.

Başarılı istekleri uygulamada yüzde 10 örnekleyip hata trace'lerini Collector'da korumak için tail sampling kullanın. Bu karar span tamamlanmadan verilemeyeceği için Collector, decision_wait boyunca trace parçalarını bellekte tutar; beklenen saniyelik trace sayısı ile ortalama span sayısını çarpıp Collector bellek limitini buna göre belirleyin. Aksi halde yoğun trafikte trace parçaları karar verilmeden düşer.

processors:
  tail_sampling:
    decision_wait: 10s
    num_traces: 50000
    policies:
      - name: keep-errors
        type: status_code
        status_code: { status_codes: [ERROR] }
      - name: keep-slow
        type: latency
        latency: { threshold_ms: 1500 }
      - name: sample-rest
        type: probabilistic
        probabilistic: { sampling_percentage: 5 }

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [tail_sampling]
      exporters: [otlphttp]

Collector'da tail sampling uygulanırken SDK'da yüzde 10 head sampling kullanmak, SDK'nın hiç göndermediği yüzde 90 içindeki hata trace'lerinin Collector tarafından kurtarılamayacağı anlamına gelir. Hata trace'lerini eksiksiz istiyorsanız uygulama tarafında parent-based/always-on gönderim ile Collector kapasitesini ölçün veya hata sinyalini ayrı bir metric ve log akışıyla güvenceye alın. Bu nüans, .net core eğitimi ya da microsoft teknolojileri eğitimi materyallerinde 'tail sampling tüm hataları yakalar' ifadesinin hangi trafik verisi Collector'a ulaştığında doğru olduğunu belirler.

blazor eğitimi: Tarayıcıdan API'ye korelasyon ve CORS

Blazor WebAssembly istemcisinden tarayıcı enstrümantasyonu ile traceparent gönderiyorsanız API'nin CORS politikası bu başlığa açık olmalıdır. Aksi halde tarayıcı preflight isteğiyle çağrıyı engeller; API trace'leri çalışsa bile kullanıcı etkileşimi ile backend span'ı bağlanmaz. BFF mimarisinde bu başlık yönetimi sunucu tarafına taşınır, doğrudan WASM çağrısında ise izin açıkça tanımlanmalıdır.

builder.Services.AddCors(options => options.AddPolicy("ui", policy => policy
    .WithOrigins("https://app.example.com")
    .WithMethods("GET", "POST", "PUT", "DELETE")
    .WithHeaders("content-type", "traceparent", "tracestate")));

app.UseCors("ui");

Tarayıcı tarafında kullanıcı kimliği, sepet içeriği veya access token'ı span attribute olarak göndermeyin; trace backend'i çoğu ekipte uygulama loglarından daha geniş erişime sahiptir. Bunun yerine istemci aksiyonunu ui.action=checkout gibi sonlu bir değerle modelleyin. Bu sınır, blazor eğitimi alan ekiplerin tarayıcı hata ayıklama kolaylığı ile kişisel veri minimizasyonunu aynı tasarımda ele almasını sağlar.

İlgili Eğitim

.NET Core Eğitimi

Sık Sorulan Sorular

csharp kursu kapsamında OpenTelemetry custom Activity neden görünmüyor?

Önce ActivitySource adının pipeline içindeki AddSource("Orders.Domain") ile birebir eşleştiğini doğrulayın. Ardından geçici olarak AlwaysOnSampler kullanın ve Collector logunda OTLP export hatası olup olmadığını kontrol edin. Dinleyici yokken StartActivity null dönebilir; null-conditional tag çağrıları hata vermediği için sorun sessiz kalır.

c# kursu için EF Core sorgularında trace ile yavaşlık nasıl kanıtlanır?

Sorguya TagWith("query:...") ekleyin, aynı parametre dağılımıyla k6 testi çalıştırın ve trace backend'inde bu sorgu ailesinin p95 db span süresini alın. Aynı anda dotnet-counters monitor --process-id <pid> System.Runtime ile tahsis/GC değerlerini kaydedin. SQL span süresi yüksekse execution plan inceleyin; yalnızca uygulama tahsisi yüksekse projection, AsNoTracking() veya N+1 yükleme biçimini değiştirin.

microsoft teknolojileri eğitimi içinde OpenTelemetry traceparent CORS hatası nasıl çözülür?

API CORS politikasında traceparent ve gerekiyorsa tracestate başlıklarını WithHeaders listesine ekleyin; sadece AllowAnyHeader kullanmak kısa vadede çalışsa da izin yüzeyini gereksiz büyütür. Tarayıcı geliştirici araçlarında OPTIONS preflight yanıtındaki access-control-allow-headers değerini doğrulayın.

AI / LLM Discovery

Bu makale Opendart Akademi Microsoft / C# eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.

Opendart Akademi llms.txt