# När man loggar in i ASP

<!--category-- Logging,Serilog,ASP.NET,C# -->
<datetime class="hidden">2024-10-27T17:00</datetime>

# Inleiding

Att logga in är en viktig del av applikationer men jag ser ofta det missförstått / missbrukat i ASP.NET-applikationerM SK2 Det här är en del uppsats och en del manifest om hur man effektivt loggar in på ASP

Det här är inte en komplett vägledning till att logga in.

I huvuden måste det vara användbart att mäta data, oavsett om det är data från ' medan du utvecklar eller registrerar data i produktion. Det borde vara bruikbart för dig.

[TOC]

# Problemet

Alltför ofta ses skogning som "'", bara när det finns undantag, ' och ".". Jag tror att det missförstås vad skogningen borde vara.

**Lågningar är inte bara till exempel**

I allmänhet skulle du kunna köra en viktig del av din applikation lokalt. `log.LogInformation` är din vän.

# Lösningen

## Att logga framgångsrikt

Under de 30 år som jag har skrivit koden, har jag sett några exempel på bra odling och många fler exempel på dålig odling.

Principer för bra odling:

1. Att logga in i utveckling borde ge tillräckligt med information om hur din application kör för att förstå vad som händer när
2. Att logga in i produktion borde ge dig en super snabb och lätt mekanism för att förstå hur din applikation misslyckas.
3. Väldigt mycket skogning i produktion är negativt; det kan sakta ned din applikation och göra det svårare att hitta de viktiga sakerna

Kom ihåg; att logga gör att din applikationspresterande bara minskar.; du borde logga in vad du behöver för att diagnostisera ett problem, men inte längre i produktionen.

## Typer av att logga in på ASP.NET

### Serilog mot Microsoft.Extensioner.Låg

I ASP.NET har du redan ett inbyggt logsystem `Microsoft.Extensions.Logging`. Det här är ett bra logsystem , men det ' är inte lika flexibelt som Serilog

### BootStrap-logning

Det här är loggingen som händer när en applikation startar upp.., det är det första som händer, , och det är den första som du ska se när du kör din applikation.

Till exempel i Serilog kan du göra detta:

```csharp
Log.Logger = new LoggerConfiguration()
             .WriteTo.Console()
             .WriteTo.File("logs/boot-*.txt", rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7)
             .CreateBootstrapLogger();
```

*NOTA: Det här är begränsat eftersom du inte har tillgång till konfigurationen på den här punkten så till exempel för att använda AppInsights behöver du `#if RELEASE` block för att sätta den lämpliga nyckeln .*

Vad detta gör är att du får data om alla uppstartproblem i din application.

Du' vill också byta upp din startmetod ( i den här appen Jag använder den nya `Program.cs` metod) i ett försök/ fånga och journalera alla undantag som händer där

```csharp
try
 {
        ..all your startup code
 }
catch (Exception ex)
{
    if(args.Contains("migrate"))
    {
        Log.Information("Migration complete");
        return;
    }
    Log.Fatal(ex, "Application terminated unexpectedly");
}
finally
{
    Log.CloseAndFlush();
}
```

Protokollet .CloseAndFlush () är viktigt eftersom det säkerställer att alla protokoll är skrivna på disken | ( | din app kraschar så att den annars kommer att gå ut innan den gör detta

Här kan jag också upptäcka om appen kör i en migrationsmodi och om det gör så,loggar jag den och ut

`Log.Fatal` är den svåraste lognivån.
*Alla undantag är olyckliga* - du borde använda `Log.Error` för de där ( om de inte betyder APP | ( | inte begäran |) | kan inte fortsätta förbi den punkten |

## Protokollnivåer

I ASP.NET | ( | och |. | NET Mer allmänt | МSK3 | har du ett antal lognivåer

1. `Log.Fatal` - Det här är den svåraste lognivån
2. `Log.Error` - Det här används när en undantag händer som betyder att APP ( inte applikationen ) kan inte fortsätta förbi den punkten
3. `Log.Warning` - Det här används när något händer som är något som inte är ett fel, men som du borde vara medveten om. *inte helt rätt* men inte ett fel).
4. `Log.Information` - Detta används för generell information om vad som händer i din application
5. `Log.Debug` - Detta används för informationen att ' är bara användbart när du ♫ ' ♫ driver din applikation ♫ ♫ det ♫ МSK4 ♫ överallt i utvecklingen men borde stängas av i produktionen

För produktionen har I'd generellt sett att skogsmarkeringen `Log.Fatal`, `Log.Error` och `Log.Warning` bara.

## Runtime Logging

I motsats till att startalogg så är detta loggen som händer när din application körs.

Till exempel för att använda dessa i Serilog så gör du detta'd

```json
  "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örstärker

Som du kommer att se, är jag en stor fan av Serilog. Det är en stor logningsbibliotek som är väldigt flexibelt. En av sakerna jag gillar med den är att kunna förstärka dina loger med mer information. Detta kan vara väldigt användbart när man diagnostiserar problem i din application.
I det föregående exemplet kan ni se att I'm förstärker mina log med thread ID, threadnamenM SK2 processid och process namnMSC3 Det här kan vara väldigt användbart för att diagnostisera problem i din application

Jag ställde också in logeringen för att gå till flera 'sinks' (utgångarM SK3 i det här fallet skickar jag den till konsolen, , till en file och till Seq.

Att ha flera källor är praktiskt i fall ett misslyckas.

Jag ställde också ApplicationName egenskapen i logerna; det kan vara användbart om du har flera applikationer som registrerar sig på samma tjänst | ( | vilket man ofta gör för fördelade applikationar |; | tillsammans med en korrelationsidentifikation för att länka logerna till varandra i ett enda begäran

Till exempel om du har ett JS-frontend och ett .NET-backend så kan du sätta ihop korrelationsidentifikationen i det första slutet och skicka den till det andra slutet.

Det finns en bra omfattning av hur man kan göra det här.

## Strukturerad Logging

Strukturerad loging är ett sätt att loga som gör det lättare att söka och filtrera dina loger. I Serilog kan man göra detta genom att använda `Log.Information("This is a log message with {Property1} and {Property2}", property1, property2);` syntax. Det gör det lättare att söka efter dziennikar med en specifik egenskap

## Kontextuell Logging

Med Serilog kan du också använda `LogContext.PushProperty` att lägga till egenskaper i dina loger som bara är relevanta för ett visst område. Det kan vara väldigt användbart för att diagnostisera problem i din application

## Serilog-uppsättning

Serilog är superflexibelt i att det tillåter dig att konfigurera den i kod såväl som genom config.
Till exempel för att använda konfigurationen ovanför så gör du detta

```csharp
builder.Host.UseSerilog((context, services, configuration) =>
{
    configuration
        .MinimumLevel.Warning()
        .Enrich.FromLogContext()
        .Enrich.WithThreadId()
        .Enrich.WithThreadName()
        .Enrich.WithProcessId()
        .Enrich.WithProcessName()
        .WriteTo.Seq("http://seq:5341", apiKey: "")
        .WriteTo.Console()
        .WriteTo.File("logs/applog-.txt", rollingInterval: RollingInterval.Day)
        .Enrich.WithProperty("ApplicationName", "mostlylucid");
});

```

Det här är samma konfiguration som förut, men i kod.

# Exceptionsfilter

I ASP kan man använda Exception Filter för att fånga och registrera undantag.
Hursomhelst det' inte ersätter Protokollering på metodnivån ; så borde du fortfarande logga på metod nivån så att du kan se vad som händer i din application i detalj ; Exception-filtern visar bara vad som sker när hela applikationen har lämnats av och det kan ofta vara väldigt förvirrande att räkna ut vad som hände.

Detta ändrades i ASP.NET Core 8 och därM SK2 är en TON du kan göra med dessa [nya egenskaper](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-8.0).

Bug igen samma principer appliceras; du borde logga in på metodnivå så att du kan se vad som händer i din application i detalj

# DON'T LOG Allt i förväg

Logging borde vara lämpligt för miljön; i utvecklingen logar du allt så att du kan se vad som händer vid varje punkt i din applikation men i tester behöver du mindre logning M SK1 kanske log information här ) och i produktionen behöver du ännu mindre (Varning och ovanför).

Det är ansträngande att registrera allt i produktionen men det är inte bra.' är en dålig idé, . Du borde registrera allt du behöver för att diagnostisera ett problem, men inte längre.

För en väldigt "'" aktiv app som du just vann, behöver du inte att spela in data på lång sikt. ; så har du en bra bild av vad som händer i appn under de senaste dagarna med logs.

## Att be om inlogning

Ett vanligt problem jag ser i produktionen är att registrera misslyckade begäran. *du tänker fixa*, är det möjligt att detta är viktigt eftersom det kan indikera en bruten länk i din application

Hursomhelst som jag tidigare nämnde dessa är bättre hanterade i koden de faktiskt händer i ( i fallet av 401); så kan det vara så att dessa också måste registreras som `Warning` eller `Error` i koden som faktiskt genererar 401.

För att sätta upp begäran om inlogning i Serilog kan man göra detta:

```csharp
app.UseSerilogRequestLogging();
```

Det här gör att alla begäran registreras i din applikation.; det är ett bra sätt att se vad som händer i din application på hög nivå, men återigen borde du vara försiktig med vad du registrerar och hur länge du behåller dessa uppgifter för.

För Anwendungsinsikter vill du kanske fortfarande logga in med informationnivån eftersom det ger dig den fina användarfärdigenskapen; detta är ett bra sätt att se hur användarna använder din application och kan vara väldigt användbart för att diagnostisera problem ; men återigen så tar dessa snabbt upp kostnaderna så du bör vara försiktig om vad du logar och hur länge du behåller dessa loggar för.

# I slutsats

Så det är ett snabbt sätt att logga in i ASP, ., NET-applikationer och .. Mycket av det är en reaktion på överlägsna, avundsjuka, meningslösa protokoll som jag ser i många produktionsapplikationer
I utvecklingen vill du se *hur appen körs*; i produktion du vill se *hur appen misslyckas*.
Logging är alltför ofta ett värdelöst ♫ , ♫ dyrt del av applikationsutveckling ♫. ♫ Som med allt i mjukvaruutveckling så bör loging fokusera på användaren ♫