Gå til indholdet

Introduktion til log

I denne sektion vil der blive gennemgået betydningen af log i C#, hvorfor det er vigtigt, hvordan det kan implementeres, og de mest benyttede pakker og metoder til at arbejde med log.

Hvorfor logge

Logging er en vigtig del af softwareudvikling og har flere formål:

  • Fejlfinding: Logging gør det lettere at finde og diagnosticere fejl og problemer i koden under udvikling og vedligeholdelse.
  • Overvågning: Logging giver indsigt i, hvordan applikationen fungerer, og kan bruges til at identificere ydeevne- eller ressourceproblemer.
  • Sikkerhed: Logging kan hjælpe med at spore og analysere sikkerhedshændelser og potentielle angreb.
Information til undervisere

Viden om log generelt er nødvendigt - al professionel udvikling benytter log. Kursisten skal kende til både log levels og targets/sinks, og selv prøve det. På denne side er der et par repos med eksempler men måske skulle i sammen kigge på En udvidet konsol applikation som indeholder et eksempel på brug af Serilog. Husk at give besked (footer) hvis noget mod forventning ikke virker. Pakker bliver opdateret og det kan nogle gange slå et eller andet i stykker.

Brug af System.Diagnostics

Der er flere måder at implementere logging i C# applikationer.

En simpel måde er at bruge System.Diagnostics.Trace og System.Diagnostics.Debug klasserne, som er en del af .NET framework:

using System.Diagnostics;

// Skriver en logbesked til Trace
Trace.WriteLine("Dette er en trace besked.");

// Skriver en logbesked til Debug (kun i debug mode)
Debug.WriteLine("Dette er en debug besked.");

Forskellen mellem Trace og Debug

Trace og Debug er begge klasser i System.Diagnostics-navnerummet og bruges til at logge information i C# applikationer. Forskellen mellem de to ligger i deres formål og anvendelsesområde:

  • Trace: Trace klassen er designet til at logge information både i udviklings- og produktionsmiljøer. Det betyder, at Trace logbeskeder vil blive genereret og logget uanset om applikationen kører i Debug- eller Release-mode.
  • Debug: Debug klassen er beregnet til at logge information kun i udviklingsmiljøet. Debug logbeskeder vil kun blive genereret og logget, når applikationen kører i Debug-mode.

For at se Trace og Debug logbeskeder i Visual Studio skal Output-vinduet åbnes. Dette kan gøres ved at vælge “View” > “Output” i menuen, eller ved at trykke “Ctrl + Alt + O”. I Output-vinduet skal der vælges “Debug” i rullemenuen for at se logbeskederne.

Helt simpel fil-log

Du skal ikke selv kode et log-system – for det første er det ret komplekst at gøre rigtigt, og for det andet er det gjort mange gange. Du kan eventuelt benytte (open source) systemer som Serilog, NLog eller Log4Net, men hvis du gerne vil have en smule log, kan du eventuelt tage udgangspunkt i følgende metode – men du må ikke bruge den i produktion:

using System;

namespace Demo
{
    class Program
    {
        static void Main(string[] args)
        {

            Log("Test #1");
            Log("Test #2");

        }

                        // Simpel log-metode der skriver til en fil.
        // Metoden tilføjer tid og fjernet eventuelle linjeskift i tekst
        static void Log(string tekst) {
            System.IO.File.AppendAllText(
                @"c:\temp\log.txt",
                $"{DateTime.Now:dd-MM-yy HH:mm:ss:ffff} " +
                $"{tekst.Replace("\r\n", "")} \r\n");
                        }
    }
}

Koden vil skabe en log-fil i c:\temp (som skal eksistere) kaldet log.txt med følgende indhold:

13-01-20 16:43:37:5347 Test #1 
13-01-20 16:43:37:5620 Test #2

Med denne simple log-metode vil en typisk try/catch struktur se således ud:

try
{
    Console.WriteLine("Indtast tal");
    string talTekst = Console.ReadLine();
    int resultat = LægEnTil(talTekst);
    Console.WriteLine($"Resultatet er {resultat}");
}
catch (Exception ex)
{
    // ex.ToString() vil returnere al info til en streng
    Log(ex.ToString());     
    Console.WriteLine($"Ups - følgende fejl er opstået: {ex.Message}");
}

Nu vil fejl blive fanget, der udskrives en besked til brugeren, og fejlen bliver gemt i en log-fil til eventuelt senere gennemsyn.

Warning

Brug altid et gennemtestet Log-system til log - ikke din egen kode.

Professionel logning

Der er flere populære tredjeparts logging biblioteker, der tilbyder mere avancerede funktioner og bedre logningsmekanismer. Nogle af de mest populære logging biblioteker inkluderer:

Disse biblioteker tilbyder forskellige funktioner og konfigurationsmuligheder, så det anbefales at undersøge, hvilken løsning der passer bedst til applikationens behov.

Forskellige log targets

Når der logges gennem de store NuGet pakker i en C# applikation, kan logbeskederne sendes til forskellige mål eller destinationskilder. Her er nogle af de mest almindelige log targets:

  • Filer: Logbeskeder kan skrives til tekstfiler, så de er lette at gennemgå og analysere. Dette er en almindelig metode, der bruges i mange applikationer.
  • Databaser: Logbeskeder kan gemmes i databaser for at gøre det nemmere at søge, filtrere og analysere logdata.
  • Event Log: Windows Event Log er en centraliseret logningsmekanisme, der gør det muligt at overvåge og analysere systemhændelser og applikationshændelser.
  • ElasticSearch: ElasticSearch er en søgemaskine med fuld tekst, der er baseret på Apache Lucene. Det er en meget populær løsning til at indeksere og søge i store mængder logdata. Der er nuget-pakker som Serilog.Sinks.Elasticsearch og NLog.Targets.ElasticSearch til at logge direkte til ElasticSearch.
  • Application Insights: Application Insights er en tjeneste fra Microsoft Azure, der giver overvågning og diagnostik for applikationer. Det er integreret med Visual Studio og kan bruges til at logge og analysere logdata fra C# applikationer. Se Microsoft.ApplicationInsights for at komme i gang.
  • Seq: Seq er en centraliseret logserver, der er designet specifikt til strukturerede logs. Det gør det nemt at søge, analysere og visualisere logdata ved hjælp af et webbaseret grænseflade. Serilog har en NuGet-pakke Serilog.Sinks.Seq for at logge direkte til en Seq server.
  • Email: I nogle tilfælde kan logbeskeder sendes via e-mail, især når der opstår kritiske fejl eller alarmer.

Professionelle applikationer benytter ofte en kombination af disse log targets for at opnå den bedste balance mellem ydeevne og analysekapacitet. Valget af log targets afhænger af applikationens krav og mål.

Log niveauer

Log niveauer er en vigtig del af logningsstrategien i en C# applikation. De hjælper med at kontrollere, hvilken type information der logges, og gør det nemmere at filtrere og analysere logdata. De mest almindelige log niveauer er:

  • Trace: Dette niveau bruges til at logge meget detaljerede og diagnostiske oplysninger, der kan være nyttige ved fejlfinding og analyse. Trace logbeskeder er normalt for omfattende til at blive brugt i en produktionsmiljø.
  • Debug: Dette niveau bruges til at logge oplysninger, der hjælper udviklere med at fejlfinde og forstå, hvad der sker inde i applikationen. Debug logbeskeder er typisk kun aktiveret i udviklingsmiljøet.
  • Information: Dette niveau bruges til at logge generelle oplysninger om, hvad applikationen gør. Disse logbeskeder er ofte aktiveret både i udviklings- og produktionsmiljøer og kan hjælpe med at forstå applikationsforløbet og opdage eventuelle problemer.
  • Warning: Dette niveau bruges til at logge potentielle problemer eller situationer, der kan kræve opmærksomhed, men ikke nødvendigvis betragtes som fejl. Warning logbeskeder er vigtige for at overvåge applikationens sundhed og ydeevne.
  • Error: Dette niveau bruges til at logge fejl og problemer, der forhindrer korrekt funktion af applikationen. Error logbeskeder er vigtige for at finde og rette fejl i applikationen.
  • Critical/Fatal: Dette niveau bruges til at logge alvorlige fejl og problemer, der kan forårsage, at applikationen går ned eller bliver utilgængelig. Critical logbeskeder skal håndteres hurtigt for at undgå tab af data eller yderligere problemer.

Ved at bruge disse log niveauer kan applikationen logge de nødvendige oplysninger, samtidig med at mængden af logdata holdes på et håndterbart niveau. Log niveauer kan også tilpasses, så de passer til applikationens specifikke krav og mål.

Log rotation og opbevaring

Log rotation er en vigtig praksis for at opretholde en sund applikation og forhindre, at logfiler eller tabeller bliver for store og besværlige at administrere. Log rotation indebærer at opdele logfiler i mindre, tidsbegrænsede segmenter og muligvis arkivere eller slette gamle logfiler. Flere logrammer og biblioteker, som NLog og Serilog, understøtter log rotation ud af boksen.

Log opbevaring er en anden vigtig overvejelse, når man arbejder med logfiler. At bestemme, hvor længe logdata skal opbevares, afhænger af virksomhedens politikker, juridiske krav og ressourcer. Overvej om der er behov for arkivering af logdata og hvordan dette kan gøres effektivt.

Log analyse og overvågning

Når logdata er opsamlet, er det vigtigt at analysere og overvåge det for at identificere problemer, fejl og ydeevne flaskehalse. Log analyse værktøjer som ElasticSearch, Application Insights og Seq, der er nævnt tidligere, kan hjælpe med at analysere logdata og give indsigt i applikationens sundhed. Overvej at opsætte alarmer og notifikationer baseret på bestemte logniveauer eller hændelser for at sikre, at teamet bliver informeret om kritiske problemer.

Centraliseret logning

I større applikationer eller applikationer, der kører i distribuerede miljøer, kan det være nyttigt at centralisere logdata. Centraliseret logning gør det nemmere at søge og analysere logdata på tværs af flere tjenester eller servere. Flere log targets, som ElasticSearch, Seq og Application Insights, understøtter centraliseret logning.

Overvejelserne om logning i C# applikationer strækker sig ud over de grundlæggende koncepter og teknikker, der er beskrevet i denne sektion. Men at forstå betydningen af logning og hvordan man arbejder med forskellige logrammer, logniveauer og log targets vil hjælpe med at opbygge mere robuste og vedligeholdelige applikationer.

Eksempler

Se Udvidet konsol applikation for et eksempel på en konsol applikation med log, samt devcronberg/SerilogConsoleDemo for en (.NET 6) demo af Serilog.