Megosztás a következőn keresztül:


Példa: OpenTelemetria használata a Prometheus, a Grafana és a Jaeger használatával

Ez a példa a Prometheust használja a metrikák gyűjtéséhez, a Grafana irányítópult létrehozásához, a Jaeger pedig az elosztott nyomkövetés megjelenítéséhez.

1. A projekt létrehozása

Hozzon létre egy egyszerű webes API-projektet a ASP.NET Core Empty sablonnal a Visual Studióban vagy a következő .NET CLI-paranccsal:

dotnet new web

2. Metrikák és tevékenységdefiníciók hozzáadása

Az alábbi kód egy új metrikát (greetings.count) határoz meg az API meghívásának hányszori számához, valamint egy új tevékenységforráshoz (OtPrGrYa.Example).

// 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-végpont létrehozása

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

Feljegyzés

Az API-definíció nem használ semmit az OpenTelemetryre vonatkozóan. A .NET API-kat használja a megfigyelhetőség érdekében.

4. Hivatkozás az OpenTelemetry-csomagokra

A NuGet-Csomagkezelő vagy parancssor használatával vegye fel a következő NuGet-csomagokat:

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

Feljegyzés

Használja a legújabb verziókat, mivel az OTel API-k folyamatosan fejlődnek.

5. OpenTelemetria konfigurálása a megfelelő szolgáltatókkal

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

Ez a kód a ASP.NET Core rendszerállapotát használja a metrikák és tevékenységek lekéréséhez ASP.NET Core-ból. Emellett regisztrálja a Metrics metrikák és ActivitySource a nyomkövetés szolgáltatóit is.

A kód a Prometheus-exportőrt használja metrikákhoz, amelyek a végpont üzemeltetéséhez ASP.NET Core-t használják, ezért a következőket is hozzá kell adnia:

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

6. A projekt futtatása

Futtassa a projektet, majd nyissa meg az API-t a böngészőben vagy a curlben.

curl -k http://localhost:7275

Minden alkalommal, amikor a lapot kéri, az növeli a megszólítások számát. A metrikák végpontja ugyanazzal az alap URL-címmel érhető el, az elérési úttal /metricsegyütt.

6.1 Naplókimenet

A kódból származó naplózási utasítások kimenete a következő ILogger: . Alapértelmezés szerint a konzolszolgáltató engedélyezve van, így a kimenet a konzolra lesz irányítva.

A naplók .NET-ből való kimenő forgalmának több lehetősége is van:

  • stdout és stderr a kimenetet a tárolórendszerek, például a Kubernetes átirányítják a naplófájlokhoz.
  • Az ILoggerrel integrálható naplózási kódtárak használatával ezek közé tartozik a Serilog vagy az NLog.
  • Az alábbiakban további információkat talál az OTel naplózási szolgáltatóiról, például az OTLP-ről vagy az Azure Monitor-exportőrről.

6.2 A metrikák elérése

A metrikákat a végpont használatával érheti /metrics el.

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
...

A metrikák kimenete a metrikák pillanatképe a végpont kérésének időpontjában. Az eredmények Prometheus-kiállítási formátumban vannak megadva, amely emberi olvasásra alkalmas, de a Prometheus által jobban érthető. Ezt a témakört a következő szakasz ismerteti.

6.3 A nyomkövetés elérése

Ha megtekinti a kiszolgáló konzolját, a konzol nyomkövetési exportőrének kimenete jelenik meg, amely az információkat emberi módon olvasható formátumban adja ki. Ennek két tevékenységnek kell megjelennie, az egyik az egyéniből ActivitySource, a másik pedig a ASP.NET Core-ból:

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

Az első a létrehozott belső egyéni tevékenység. A másodikat a ASP.NET hozza létre a kéréshez, és tartalmazza a HTTP-kérés tulajdonságainak címkéivel. Látni fogja, hogy mindkettő ugyanazzal TraceIdrendelkezik, amely egyetlen tranzakciót azonosít, és egy elosztott rendszerben használható a tranzakcióban részt vevő összes szolgáltatás nyomkövetéseinek korrelációja. A rendszer HTTP-fejlécként továbbítja az azonosítókat. ASP.NET Core hozzárendel egy TraceId ha nincs jelen, amikor kérést kap. HttpClient alapértelmezés szerint tartalmazza a fejléceket a kimenő kéréseken. Minden tevékenység rendelkezik egy SpanId, az egyes tevékenységek kombinációjával TraceId és SpanId egyedi azonosításával. A Greeter tevékenység a HTTP-tevékenységhez lesz hozzárendelve a HTTP-tevékenységen keresztül ParentSpanId, amely a SpanId HTTP-tevékenységhez lesz leképezve.

Egy későbbi szakaszban ezeket az adatokat a Jaegerbe eteti az elosztott nyomkövetések vizualizációja érdekében.

7. Metrikák gyűjtése a Prometheus használatával

A Prometheus egy metrikák gyűjteménye, összesítése és idősoros adatbázisrendszere. Konfigurálja az egyes szolgáltatások metrikavégpontjaival, és rendszeresen lekaparja az értékeket, és tárolja őket az idősoros adatbázisban. Ezután szükség szerint elemezheti és feldolgozhatja őket.

A Prometheus formátumban közzétett metrikák adatai a folyamat metrikáinak időponthoz kötött pillanatképei. Minden alkalommal, amikor kérést küld a metrikák végpontjának, az aktuális értékeket fogja jelenteni. Bár a jelenlegi értékek érdekesek, a korábbi értékekhez képest értékesebbek lesznek, hogy láthassa a trendeket, és megállapítsa, hogy az értékek rendellenesek-e. A szolgáltatások gyakran a napi vagy világesemények, például az ünnepi vásárlások időszaka alapján emelkednek. Ha összehasonlítja az értékeket az előzménytrendekkel, észlelheti, hogy rendellenesek-e, vagy ha egy metrika idővel egyre rosszabbodik.

A folyamat nem tárolja a metrika-pillanatképek előzményeit. Ha ezt a képességet hozzáadja a folyamathoz, erőforrás-igényes lehet. Az elosztott rendszerekben általában több példánya is van az egyes csomópontoknak, ezért érdemes összegyűjteni a metrikákat az összestől, majd összesíteni és összevetni az előzményértékeiket.

7.1 A Prometheus telepítése és konfigurálása

Töltse le a Prometheust a platformhoz https://prometheus.io/download/ , és bontsa ki a letöltés tartalmát.

A http-végpont portszámának lekéréséhez tekintse meg a futó kiszolgáló kimenetének tetejét. Példa:

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

Módosítsa a Prometheus YAML konfigurációs fájlját a HTTP-kaparási végpont portjának megadásához, és állítson be alacsonyabb kaparási időközt. Példa:

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

Indítsa el a Prometheust, és nézze meg a port kimenetét, amelyen fut, általában a 9090-et:

>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

Nyissa meg ezt az URL-címet a böngészőben. A Prometheus felhasználói felületén most már le kell tudnia kérdezni a metrikákat. Az alábbi képen látható kiemelt gombbal nyissa meg a metrikaböngészőt, amely az összes elérhető metrikát megjeleníti.

Prometheus Metrics Explorer

Válassza ki a greetings_count metrikát az értékek grafikonjának megtekintéséhez.

Greetings_count grafikonja

8. Metrikák irányítópultjának létrehozása a Grafana használatával

A Grafana egy irányítópult-termék, amely a Prometheus vagy más adatforrások alapján hozhat létre irányítópultokat és riasztásokat.

Töltse le és telepítse a Grafana OSS-verzióját a platform utasításainak követéséből https://grafana.com/oss/grafana/ . A telepítés után a Grafana általában a 3000-s porton fut, ezért nyissa meg http://localhost:3000 a böngészőben. Be kell jelentkeznie; az alapértelmezett felhasználónév és jelszó egyaránt admin.

A hamburger menüben válassza ki a kapcsolatokat, majd írja be a szöveget prometheus a végpont típusának kiválasztásához. Új adatforrás hozzáadásához válassza a Prometheus-adatforrás létrehozása lehetőséget.

Grafana-kapcsolat a prometheushoz

A következő tulajdonságokat kell megadnia:

  • Prometheus-kiszolgáló URL-címe: http://localhost:9090/ a port módosítása a megfelelő módon

A konfiguráció ellenőrzéséhez válassza a Mentés &teszt lehetőséget.

Miután megkapta a sikeres üzenetet, konfigurálhat egy irányítópultot. Kattintson a sikeres üzenet előugró ablakában megjelenő irányítópult-hivatkozásra .

Válassza a Vizualizáció hozzáadása lehetőséget, majd válassza ki az imént adatforrásként hozzáadott Prometheus-adatforrást.

Meg kell jelennie az irányítópult-panel tervezőjének. A képernyő alsó felében definiálhatja a lekérdezést.

Grafana-lekérdezés greetings_count használatával

Válassza ki a greetings_count metrikát, majd válassza a Lekérdezések futtatása lehetőséget az eredmények megtekintéséhez.

A Grafana segítségével kifinomult irányítópultokat tervezhet, amelyek tetszőleges számú metrikát követnek nyomon.

A .NET minden metrikája további dimenziókkal rendelkezhet, amelyek kulcs-érték párok, amelyek az adatok particionálására használhatók. A ASP.NET metrikák mindegyike számos dimenzióval rendelkezik, amely a számlálóra alkalmazható. A számláló Microsoft.AspNetCore.Hosting például current-requests a következő dimenziókkal rendelkezik:

Attribútum Típus Leírás Példák Jelenlét
method string HTTP-kérési módszer. GET; POST; HEAD Mindig
scheme string A használt protokollt azonosító URI-séma. http; https Mindig
host string A kérést megkapó helyi HTTP-kiszolgáló neve. localhost Mindig
port int A kérést megkapó helyi HTTP-kiszolgáló portja. 8080 Ha nem alapértelmezés szerint van hozzáadva (http esetén 80, https esetén 443)

A Grafana gráfjai általában a dimenziók egyedi kombinációi alapján vannak particionálva. A dimenziók a Grafana-lekérdezésekben használhatók az adatok szűrésére vagy összesítésére. Ha például grafikont készít current_requests, akkor a dimenziók minden egyes kombinációja alapján particionált értékeket fog látni. Ha csak a gazdagép alapján szeretne szűrni, adjon hozzá egy műveletet Sum , és használja host címkeértékként.

Grafana current_requests gazdagép szerint

9. Elosztott nyomkövetés a Jaegerrel

A 6. lépésben láthatta, hogy az elosztott nyomkövetési információk elérhetővé válnak a konzolon. Ez az információ nyomon követi a tevékenységekkel kapcsolatos munkaegységeket. Egyes tevékenységeket a platform automatikusan hoz létre, például a ASP.NET a kérések kezelését, és a kódtárak és az alkalmazáskódok is létrehozhatnak tevékenységeket. Az üdvözlési példa tevékenységekkel Greeter rendelkezik. A tevékenységek a , SpanIdés ParentId a TraceIdcímkék használatával vannak korrelálva.

Az elosztott rendszerek minden egyes folyamata saját tevékenységadatokat hoz létre, és a metrikákhoz hasonlóan szüksége van egy olyan rendszerre, amely összegyűjti, tárolja és korrelálja a tevékenységeket, hogy képes legyen megjeleníteni az egyes tranzakciókhoz végzett munkát. A Jaeger egy nyílt forráskódú projekt, amely lehetővé teszi ezt a gyűjteményt és vizualizációt.

Töltse le a jaeger legújabb bináris terjesztési archívumát a platformról https://www.jaegertracing.io/download/.

Ezután bontsa ki a letöltést egy könnyen elérhető helyi helyre. Futtassa a jaeger-all-in-one(.exe) végrehajtható fájlt:

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

Tekintse át a konzol kimenetét, és keresse meg azt a portot, ahol az OTLP-forgalmat figyeli a gRPC-n keresztül. Példa:

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

Ez a kimenet azt jelzi, hogy figyel 0.0.0.0:4317, így ezt a portot konfigurálhatja célként az OTLP-exportőr számára.

Nyissa meg a AppSettings.json projekthez tartozó fájlt, és adja hozzá a következő sort, és szükség esetén módosítsa a portot.

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

Indítsa újra a köszöntőfolyamatot, hogy átvehesse a tulajdonságmódosítást, és megkezdhesse a nyomkövetési információk Jaegerhez való irányítását.

Most már látnia kell a Jaeger felhasználói felületét http://localhost:16686/ egy webböngészőből.

Jaeger-lekérdezés nyomkövetésekhez

A nyomkövetések listájának megtekintéséhez válassza OTel-Prometheus-grafana-Jaeger a Szolgáltatás legördülő listából. A nyomkövetés kiválasztásakor a tevékenységek gantt-diagramjának kell megjelennie a nyomkövetés részeként. Az egyes műveletekre kattintva további részletek láthatók a tevékenységről.

Jaeger-művelet részletei

Elosztott rendszerekben minden folyamatból szeretne nyomkövetéseket küldeni ugyanarra a Jaeger-telepítésre, hogy az korrelálhassa a rendszeren belüli tranzakciókat.

Egy kicsit érdekesebbé teheti az alkalmazást, ha HTTP-hívásokat indít magának.

  • HttpClient Gyár hozzáadása az alkalmazáshoz

    builder.Services.AddHttpClient();
    
  • Új végpont hozzáadása beágyazott üdvözléshívások indításához

    app.MapGet("/NestedGreeting", SendNestedGreeting);
    
  • Implementálja a végpontot, hogy HTTP-hívásokat hajtson végre, amelyek szintén nyomon követhetők. Ebben az esetben egy mesterséges hurokban hívja vissza magát (valójában csak a bemutató forgatókönyvekre alkalmazható).

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

Ez egy érdekesebb gráfot eredményez, amely piramis alakú a kérésekhez, mivel minden szint megvárja az előző hívás válaszát.

Jaeger beágyazott függőségi eredmények