# Seq för ASP.NET Logging - spårning med SerilogTracing

<datetime class="hidden">2024-08-31T11:20</datetime>

<!--category-- ASP.NET, Seq, Serilog -->
# Inleiding

I den tidigare delen visade jag er hur man [själv-hosting för Seq med ASP.NET Core ](/blog/selfhostingseq). Nu när vi har den installerad, 's tid att använda mer av den, ♫ ♫ 's egenskaper för att tillåta mer komplett logning, ♪ & ♫ spårning med hjälp av vår nya Seq instans ♫

[TOC]

# spårning

Att spåra är som att logga in, det ger dig en extra lager av information om vad som händer i din application. Det är särskilt användbart när du har ett distribuerat system och du behöver spåra en begäran genom flera tjänster.
På den här sidan använder jag den för att spåra problem snabbt, bara för att det är en hobbysida. Det betyder inte att jag ger upp mina professionella standarder.

## Att sätta upp Serilog

Att sätta upp spårning med Serilog är väldigt enkelt genom att använda [Serilog spårning](https://github.com/serilog-tracing/serilog-tracing) package. Först måste du installera packagerna:

Här lägger vi också till Konsolens och Seqs sock

```bash
dotnet add package SerilogTracing
dotnet add package SerilogTracing.Expressions
dotnet add package Serilog.Sinks.Console
dotnet add package Serilog.Sinks.Seq
```

Konsolen är alltid användbar för debugging och Seq är vad vi är här för.

```bash
  "Serilog": {
    "Enrich": ["FromLogContext", "WithThreadId", "WithThreadName", "WithProcessId", "WithProcessName", "FromLogContext"],
    "MinimumLevel": "Warning",
    "WriteTo": [
        {
          "Name": "Seq",
          "Args":
          {
            "serverUrl": "http://seq:5341",
            "apiKey": ""
          }
        },
      {
        "Name": "Console"
      },
      {
        "Name": "File",
        "Args": {
          "path": "logs/applog-.txt",
          "rollingInterval": "Day"
        }
      }

    ],
    "Properties": {
      "ApplicationName": "mostlylucid"
    }
  }
```

För att använda dessa rikare behöver du lägga till dem i din `Serilog` konfiguration i din `appsettings.json` file. Du behöver också installera alla separata förstärkare med Nuget

Det är en av de goda och dåliga sakerna med Serilog, att man installerar bara en bunt paket, men det betyder att man bara lägger till vad man behöver, inte bara ett monolitiskt paket.
Här är min

![Serilog förstärkare](serilogenrichers.png)

Med alla dessa bombinerade får jag en ganska bra log-output i Seq.

![Serilog Seq fel](serilogerror.png)

Här ser ni fel meddelandet, stapelspåret , trådens ID, processens id och processens namnM SK3 Det här är alla användbara informationer när du försöker hitta ett problem

En sak att notera är att I' har satt `  "MinimumLevel": "Warning",` i min `appsettings.json` file. Det betyder att endast varningar och förut kommer att registreras i Seq. Det är användbart för att hålla oljudet nere i dina loger

Men i Seq kan du också specifikera detta per Api Key; så att du kan ha `Information` ( eller om du är riktigt entusiastisk `Debug`) logging ställs här och begränsar vad Seq faktiskt fångar med API: s nyckeln

![Seq Api-key](apikey.png)

Nota: du har fortfarande app överhuvudtaget , du kan också göra detta mer dynamiskt så att du kan justera nivån på flyget [Seq-sänka ](https://github.com/datalust/serilog-sinks-seq)för mer information.

```json
{
    "Serilog":
    {
        "LevelSwitches": { "$controlSwitch": "Information" },
        "MinimumLevel": { "ControlledBy": "$controlSwitch" },
        "WriteTo":
        [{
            "Name": "Seq",
            "Args":
            {
                "serverUrl": "http://localhost:5341",
                "apiKey": "yeEZyL3SMcxEKUijBjN",
                "controlLevelSwitch": "$controlSwitch"
            }
        }]
    }
}
```

## spårning

Nu tillsätter vi spårning igen med Serilog.Tracing det.' är ganska enkelt, .. Vi har samma uppsättning som innan men vi tillsätter en ny sump för spårning.

```bash
dotnet add package SerilogTracing
dontet add package SerilogTracing.Expressions
dotnet add SerilogTracing.Instrumentation.AspNetCore
```

Vi lägger också till ett extra paket för att registrera mer detaljerad aspnets coreinformation.

### Konfigurera i `Program.cs`

Nu kan vi faktiskt börja använda spårning `Program.cs` file.

```csharp
    using var listener = new ActivityListenerConfiguration()
        .Instrument.HttpClientRequests().Instrument
        .AspNetCoreRequests()
        .TraceToSharedLogger();
```

Att spåra använder konceptet "'", Activities , och representerar en enhet av arbete .

I det här fallet lägger vi till extra spårning för HttpClient- och AspNetCore- begäran. Vi lägger också till `TraceToSharedLogger` som kommer att registrera aktiviteten på samma logger som resten av vår application.

## Att använda spårning i en tjänst

Nu har vi spårning som vi kan börja använda i vår app.

```csharp
    public async Task<PostListViewModel> GetPostsByCategory(string category, int page = 1, int pageSize = 10,
        string language = MarkdownBaseService.EnglishLanguage)
    {
        using var activity = Log.Logger.StartActivity("GetPostsByCategory {Category}, {Page}, {PageSize}, {Language}",
            new { category, page, pageSize, language });
        try
        {
            var count = await NoTrackingQuery()
                .Where(x => x.Categories.Any(c => c.Name == category) && x.LanguageEntity.Name == language)
                .CountAsync();
            var posts = await PostsQuery()
                .Where(x => x.Categories.Any(c => c.Name == category) && x.LanguageEntity.Name == language)
                .OrderByDescending(x => x.PublishedDate.DateTime)
                .Skip((page - 1) * pageSize)
                .Take(pageSize)
                .ToListAsync();

            var languages = await GetLanguagesForSlugs(posts.Select(x => x.Slug).ToList());
            var postListViewModel = new PostListViewModel
            {
                Page = page,
                PageSize = pageSize,
                TotalItems = count,
                Posts = posts.Select(x => x.ToListModel(
                    languages.FirstOrDefault(entry => entry.Key == x.Slug).Value.ToArray())).ToList()
            };
            activity.Complete();
            return postListViewModel;
        }
        catch (Exception e)
        {
            activity.Complete(LogEventLevel.Error, e);
        }

        return new PostListViewModel();
    }
```

De viktiga linjerna här är:

```csharp
  using var activity = Log.Logger.StartActivity("GetPostsByCategory {Category}, {Page}, {PageSize}, {Language}",
            new { category, page, pageSize, language });
```

Det här öppnar en ny 'aktivitet ' som är en arbetsenhet . det är användbart för att spåra ett begäran genom flera tjänster
Eftersom vi har det inpackat i ett användande uttalande så kommer detta att komplettera och avlägsna vid slutet av vår metod men det är "'" som är bäst att explicitt färdigställa det.

```csharp
            activity.Complete();
```

I vårt exception handlingsfält kompletterar vi också aktiviteten men med en felnivå och undantag.. Det är användbart för att spåra problem i din application.

## Genom att använda spår

Nu har vi alla den här konfigurationen och kan börja använda den.

![Http-spår](httptrace.png)

Det här visar dig översättningen av en enkel markerdown-post. Du kan se de flera stegen för en enda post och alla HttpClient- begäran och tidningar.

Nota Jag använder Postgres för min databank, Till skillnad från SQL-servern har npgsql-drivaren infödda support för spårning så att du kan få mycket användbara data från dina datauppsökningar som SQL: s ställda ut , timings etc. Dessa sparas som MSC3spansM SK4 till Seq och ser liek följandeMska5

```json
  "@t": "2024-08-31T15:23:31.0872838Z",
"@mt": "mostlylucid",
"@m": "mostlylucid",
"@i": "3c386a9a",
"@tr": "8f9be07e41f7121cbf2866c6cd886a90",
"@sp": "8d716c5f01ad07a0",
"@st": "2024-08-31T15:23:31.0706848Z",
"@ps": "622f1c86a8b33304",
"@sk": "Client",
"ActionId": "91f5105d-93fa-4e7f-9708-b1692e046a8a",
"ActionName": "Mostlylucid.Controllers.HomeController.Index (Mostlylucid)",
"ApplicationName": "mostlylucid",
"ConnectionId": "0HN69PVEQ9S7C",
"ProcessId": 30496,
"ProcessName": "Mostlylucid",
"RequestId": "0HN69PVEQ9S7C:00000015",
"RequestPath": "/",
"SourceContext": "Npgsql",
"ThreadId": 47,
"ThreadName": ".NET TP Worker",
"db.connection_id": 1565,
"db.connection_string": "Host=localhost;Database=mostlylucid;Port=5432;Username=postgres;Application Name=mostlylucid",
"db.name": "mostlylucid",
"db.statement": "SELECT t.\"Id\", t.\"ContentHash\", t.\"HtmlContent\", t.\"LanguageId\", t.\"Markdown\", t.\"PlainTextContent\", t.\"PublishedDate\", t.\"SearchVector\", t.\"Slug\", t.\"Title\", t.\"UpdatedDate\", t.\"WordCount\", t.\"Id0\", t0.\"BlogPostId\", t0.\"CategoryId\", t0.\"Id\", t0.\"Name\", t.\"Name\"\r\nFROM (\r\n    SELECT b.\"Id\", b.\"ContentHash\", b.\"HtmlContent\", b.\"LanguageId\", b.\"Markdown\", b.\"PlainTextContent\", b.\"PublishedDate\", b.\"SearchVector\", b.\"Slug\", b.\"Title\", b.\"UpdatedDate\", b.\"WordCount\", l.\"Id\" AS \"Id0\", l.\"Name\", b.\"PublishedDate\" AT TIME ZONE 'UTC' AS c\r\n    FROM mostlylucid.\"BlogPosts\" AS b\r\n    INNER JOIN mostlylucid.\"Languages\" AS l ON b.\"LanguageId\" = l.\"Id\"\r\n    WHERE l.\"Name\" = @__language_0\r\n    ORDER BY b.\"PublishedDate\" AT TIME ZONE 'UTC' DESC\r\n    LIMIT @__p_2 OFFSET @__p_1\r\n) AS t\r\nLEFT JOIN (\r\n    SELECT b0.\"BlogPostId\", b0.\"CategoryId\", c.\"Id\", c.\"Name\"\r\n    FROM mostlylucid.blogpostcategory AS b0\r\n    INNER JOIN mostlylucid.\"Categories\" AS c ON b0.\"CategoryId\" = c.\"Id\"\r\n) AS t0 ON t.\"Id\" = t0.\"BlogPostId\"\r\nORDER BY t.c DESC, t.\"Id\", t.\"Id0\", t0.\"BlogPostId\", t0.\"CategoryId\"",
"db.system": "postgresql",
"db.user": "postgres",
"net.peer.ip": "::1",
"net.peer.name": "localhost",
"net.transport": "ip_tcp",
"otel.status_code": "OK"
```

Man kan se att det här innefattar i stort sett allt som man behöver veta om queryn, SQL som gjordes , kopplingstråden och så vidare. Det här är alla användbara informationer när du försöker leta efter ett problem.

# I slutsats

I' har bara skarkat ut spårning här på ytan, , det är ' som är ett litet område med passionerade förespråkare... Förhoppningsvis har jag visat hur enkelt det är att få igång med enkelt spårande med Seq. | & | Serilog för ASP. ♫ . | NET Core-applikationer. ♪ . ♪ På så sätt kan jag få mycket av fördelarna med mer kraftfulla verktyg som Application Insights utan kostnaden för Azure.