Logging og sporing i .NET-programmer
Etter hvert som du fortsetter å utvikle programmet og det blir mer komplisert, bør du bruke flere feilsøkingsdiagnoser i programmet.
Sporing er en måte for deg å overvåke kjøringen av programmet mens det kjører. Du kan legge til sporings- og feilsøkingsinstrumenter i .NET-programmet når du utvikler det. Du kan bruke instrumenteringen mens du utvikler programmet og etter at du har distribuert det.
Denne enkle teknikken er overraskende kraftig. Du kan bruke den i situasjoner der du trenger mer enn et feilsøkingsprogram:
- Problemer som oppstår over lange perioder, kan være vanskelige å feilsøke med et tradisjonelt feilsøkingsprogram. Logger tillater detaljert post-mortem gjennomgang som strekker seg over lange perioder. Feilsøkingsprogrammene er derimot begrenset til sanntidsanalyse.
- Programmer med flere tråder og distribuerte programmer er ofte vanskelige å feilsøke. Ved å legge ved et feilsøkingsprogram har en tendens til å endre virkemåte. Du kan analysere detaljerte logger etter behov for å forstå komplekse systemer.
- Problemer i distribuerte programmer kan oppstå fra en kompleks interaksjon mellom mange komponenter. Det er kanskje ikke rimelig å koble et feilsøkingsprogram til alle deler av systemet.
- Mange tjenester bør ikke stoppes. Ved å legge ved et feilsøkingsprogram forårsaker ofte tidsavbruddsfeil.
- Problemer er ikke alltid forutsett. Logging og sporing er utformet for lave kostnader, slik at programmer alltid kan registreres i tilfelle det oppstår et problem.
Skrive informasjon til utdatavinduer
Frem til nå har vi brukt konsollen til å vise informasjon til programbrukeren. Det finnes andre typer programmer bygget med .NET som har brukergrensesnitt, for eksempel mobil-, nett- og skrivebordsapper, og det finnes ingen synlig konsoll. I disse programmene logger System.Console meldinger «bak kulissene». Disse meldingene kan vises i et utdatavindu i Visual Studio eller Visual Studio Code. De kan også være utdata til en systemlogg, for eksempel Androids logcat. Derfor bør du ta stor hensyn når du bruker System.Console.WriteLine i et program som ikke er konsoll.
Her kan du bruke System.Diagnostics.Debug og System.Diagnostics.Trace i tillegg til System.Console. Både Debug og Trace er en del av System.Diagnostics og vil bare skrive til logger når en passende lytter er vedlagt.
Valget av hvilken utskriftsstil-API som skal brukes, er opp til deg. De viktigste forskjellene er:
-
System.Console
- Alltid aktivert og skriver alltid til konsollen.
- Nyttig for informasjon som kunden kanskje trenger å se i utgivelsen.
- Fordi det er den enkleste tilnærmingen, brukes den ofte til midlertidig feilsøking av ad hoc. Denne feilsøkingskoden sjekkes ofte aldri inn i kildekontrollen.
-
System.Diagnostics.Trace
- Aktiveres bare når
TRACEer definert. - Skriver til vedlagte lyttere, som standard, DefaultTraceListener.
- Bruk denne API-en når du oppretter logger som skal aktiveres i de fleste bygg.
- Aktiveres bare når
-
System.Diagnostics.Debug
- Aktiveres bare når
DEBUGer definert (i feilsøkingsmodus). - Skriver til et vedlagt feilsøkingsprogram.
- Bruk denne API-en når du oppretter logger som bare aktiveres i feilsøkingsbygg.
- Aktiveres bare når
Console.WriteLine("This message is readable by the end user.");
Trace.WriteLine("This is a trace message when tracing the app.");
Debug.WriteLine("This is a debug message just for developers.");
Når du utformer sporings- og feilsøkingsstrategien, bør du tenke på hvordan du vil at utdataene skal se ut. Flere skrivesetninger fylt med ikke-relatert informasjon oppretter en logg som er vanskelig å lese. På den annen side kan det å bruke WriteLine til å plassere relaterte setninger på separate linjer gjøre det vanskelig å skille mellom hvilken informasjon som hører sammen. Generelt sett kan du bruke flere skriveutsagn når du vil kombinere informasjon fra flere kilder for å opprette én enkelt informativ melding. Bruk WriteLine-setningen når du vil opprette én enkelt fullstendig melding.
Debug.Write("Debug - ");
Debug.WriteLine("This is a full line.");
Debug.WriteLine("This is another full line.");
Denne utdataene er fra den foregående loggingen med Debug:
Debug - This is a full line.
This is another full line.
Definer TRACE- og DEBUG-konstanter
Når et program kjører under feilsøking, defineres DEBUG konstant som standard. Du kan kontrollere dette ved å legge til en DefineConstants oppføring i prosjektfilen i en egenskapsgruppe. Her er et eksempel på hvordan du slår på TRACE for både Debug og Release konfigurasjoner i tillegg til DEBUG for Debug konfigurasjoner.
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
Når du bruker Trace når du ikke er knyttet til feilsøkingsprogrammet, må du konfigurere en sporingslytting, for eksempel dotnet-trace-.
Betinget sporing
I tillegg til enkle Write- og WriteLine metoder, er det også mulighet til å legge til betingelser med WriteIf og WriteLineIf. Som et eksempel kontrollerer følgende logikk om antallet er null og skriver deretter en feilsøkingsmelding:
if(count == 0)
{
Debug.WriteLine("The count is 0 and this may cause an exception.");
}
Du kan skrive om dette i én enkelt kodelinje:
Debug.WriteLineIf(count == 0, "The count is 0 and this may cause an exception.");
Du kan også bruke disse betingelsene med Trace og med flagg som du definerer i programmet:
bool errorFlag = false;
System.Diagnostics.Trace.WriteIf(errorFlag, "Error in AppendData procedure.");
System.Diagnostics.Debug.WriteIf(errorFlag, "Transaction abandoned.");
System.Diagnostics.Trace.Write("Invalid value for data request");
Kontroller at det finnes visse betingelser
En deklarasjon, eller Assert setning, tester en betingelse som du angir som et argument for Assert-setningen. Hvis betingelsen evalueres til true, skjer det ingen handling. Hvis betingelsen evalueres til false, mislykkes deklarasjonen. Hvis du kjører med et feilsøkingsbygg, går programmet inn i pausemodus.
Du kan bruke Assert metoden fra enten Debug eller Trace, som er i System.Diagnostics navneområdet.
Debug klassemetoder ikke er inkludert i en versjon av programmet, slik at de ikke øker størrelsen eller reduserer hastigheten på utgivelseskoden.
Bruk System.Diagnostics.Debug.Assert metoden fritt til å teste betingelser som skal gjelde hvis koden er riktig. Anta for eksempel at du har skrevet en heltallsdelingsfunksjon. Etter matematikkreglene kan divisoren aldri være null. Du kan teste denne betingelsen ved hjelp av en deklarasjon:
int IntegerDivide(int dividend, int divisor)
{
Debug.Assert(divisor != 0, $"{nameof(divisor)} is 0 and will cause an exception.");
return dividend / divisor;
}
Når du kjører denne koden under feilsøkingsprogrammet, evalueres deklarasjonssetningen. Sammenligningen gjøres imidlertid ikke i versjonsversjonen, så det er ingen ekstra kostnader.
Notat
Når du bruker System.Diagnostics.Debug.Assert, må du kontrollere at en kode i Assert ikke endrer resultatene av programmet hvis Deklarer fjernes. Ellers kan det hende at du utilsiktet introduserer en feil som bare vises i versjonen av programmet. Vær spesielt forsiktig med deklarasjoner som inneholder funksjons- eller prosedyrekall.
Bruk av Debug og Trace fra System.Diagnostics navneområdet er en flott måte å gi ekstra kontekst på når du kjører og feilsøker programmet.