Ontwikkel een C# Applicatie voor Geavanceerde Logging en Foutafhandeling
description
Met deze prompt kan de gebruiker een robuuste C# applicatie ontwikkelen die fouten effectief afhandelt en gedetailleerde loggegevens bijhoudt. Dit helpt bij het verbeteren van de onderhoudbaarheid en het opsporen van problemen tijdens productie, wat beter is dan basis logging of foutafhandeling omdat het meer controle en inzicht biedt.
prompt
Help me een C# applicatie te ontwerpen die geavanceerde logging en foutafhandeling implementeert. Beschrijf hoe ik verschillende logniveaus kan gebruiken, uitzonderingen effectief kan afvange ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Natuurlijk! Hier is een uitgebreide gids en voorbeeldcode voor een C# applicatie die geavanceerde logging en foutafhandeling implementeert, inclusief verschillende logniveaus, exception handling en logformattering.
**1. Logniveaus gebruiken**
Gebruik een gestructureerd loggingsysteem zoals `Microsoft.Extensions.Logging` of een externe library zoals Serilog. Hier laat ik een voorbeeld met Serilog zien, omdat het flexibel is en gemakkelijk te gebruiken.
**2. Exception afvangen**
Gebruik try-catch blokken om uitzonderingen af te vangen en gedetailleerde foutinformatie te loggen.
**3. Loggegevens formatteren en opslaan**
Configureer Serilog om logs te formatteren en op te slaan in bijvoorbeeld een bestand, met timestamps en logniveau.
---
### Stap 1: Installeer Serilog via NuGet
Gebruik de NuGet package manager:
```
Install-Package Serilog
Install-Package Serilog.Sinks.File
```
### Stap 2: Configuratie van Serilog
```csharp
using Serilog;
class Program
{
static void Main(string[] args)
{
// Configureer Serilog
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug() // Minimum logniveau
.WriteTo.Console() // Log naar console
.WriteTo.File("logfile.txt", outputTemplate: "[{Timestamp:HH:mm:ss} {Level}] {Message}{NewLine}{Exception}")
.CreateLogger();
try
{
Log.Information("Applicatie gestart");
ProcessFiles();
}
catch (Exception ex)
{
Log.Fatal(ex, "Onverwachte fout opgetreden");
}
finally
{
Log.CloseAndFlush();
}
}
static void ProcessFiles()
{
string[] bestanden = { "file1.txt", "file2.txt", "nonexistent.txt" };
foreach (var bestand in bestanden)
{
try
{
Log.Debug("Bezig met het verwerken van bestand {Bestand}", bestand);
LeesEnSchrijfBestand(bestand);
Log.Information("Succesvol verwerkt bestand {Bestand}", bestand);
}
catch (FileNotFoundException ex)
{
Log.Warning(ex, "Bestand {Bestand} niet gevonden", bestand);
}
catch (IOException ex)
{
Log.Error(ex, "I/O fout bij verwerking van {Bestand}", bestand);
}
catch (Exception ex)
{
Log.Error(ex, "Onverwachte fout bij verwerking van {Bestand}", bestand);
}
}
}
static void LeesEnSchrijfBestand(string bestandsnaam)
{
// Simuleer lezen en schrijven
if (bestandsnaam == "nonexistent.txt")
{
throw new FileNotFoundException("Bestand niet gevonden", bestandsnaam);
}
else if (bestandsnaam == "file2.txt")
{
throw new IOException("Fout bij lezen of schrijven");
}
else
{
// Simuleer succesvolle verwerking
Log.Debug("Bestand {Bestand} gelezen en geschreven", bestandsnaam);
}
}
}
```
---
### Samenvatting
- **Logniveaus**: Gebruik `Debug`, `Information`, `Warning`, `Error`, `Fatal` afhankelijk van de ernst.
- **Uitzonderingen**: Vang specifieke uitzonderingen zoals `FileNotFoundException` en `IOException` en log ze met het juiste niveau.
- **Formattering**: Gebruik `outputTemplate` om logs overzichtelijk te maken, inclusief tijdstempel en logniveau.
- **Opslag**: Logs worden opgeslagen in een tekstbestand en ook weergegeven in de console.
Door deze aanpak krijg je een robuuste applicatie met gedetailleerde logging en goede foutafhandeling, wat het debuggen en onderhouden aanzienlijk vereenvoudigt.
provider: deepseek
model: deepseek-chat
Hier is een uitgebreide implementatie voor geavanceerde logging in C#:
## 1. LogLevel Enum en Logger Configuratie
```csharp
using System;
using System.IO;
using NLog;
using NLog.Config;
using NLog.Targets;
public enum LogLevel
{
Debug,
Info,
Warning,
Error,
Critical
}
public static class LoggerConfig
{
public static void ConfigureLogger()
{
var config = new LoggingConfiguration();
// File target
var fileTarget = new FileTarget
{
Name = "file",
FileName = "${basedir}/logs/app.log",
Layout = "${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=ToString}"
};
// Console target
var consoleTarget = new ConsoleTarget
{
Name = "console",
Layout = "${date:format=HH\\:mm\\:ss} | ${level} | ${message}"
};
config.AddTarget(fileTarget);
config.AddTarget(consoleTarget);
config.AddRuleForAllLevels(fileTarget);
config.AddRuleForOneLevel(NLog.LogLevel.Error, consoleTarget);
LogManager.Configuration = config;
}
}
```
## 2. Bestandsverwerker met Geavanceerde Logging
```csharp
using System;
using System.IO;
using NLog;
public class BestandsVerwerker
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public void VerwerkBestand(string bronPad, string doelPad)
{
try
{
logger.Info($"Beginnen met verwerken van bestand: {bronPad}");
if (!File.Exists(bronPad))
{
logger.Warn($"Bronbestand niet gevonden: {bronPad}");
throw new FileNotFoundException($"Bestand niet gevonden: {bronPad}");
}
// Simuleer complexe verwerking
VerwerkBestandInhoud(bronPad, doelPad);
logger.Info($"Bestand succesvol verwerkt naar: {doelPad}");
}
catch (IOException ex)
{
logger.Error(ex, $"IO-fout bij verwerken bestand {bronPad}");
throw new BestandVerwerkingsException("IO-operatie mislukt", ex);
}
catch (UnauthorizedAccessException ex)
{
logger.Error(ex, $"Toegangsrechten fout voor bestand {bronPad}");
throw new BestandVerwerkingsException("Geen toegangsrechten", ex);
}
catch (Exception ex)
{
logger.Fatal(ex, $"Onverwachte fout bij verwerken bestand {bronPad}");
throw;
}
}
private void VerwerkBestandInhoud(string bronPad, string doelPad)
{
logger.Debug($"Lezen van bestand: {bronPad}");
using (var reader = new StreamReader(bronPad))
using (var writer = new StreamWriter(doelPad))
{
string regel;
int regelNummer = 0;
while ((regel = reader.ReadLine()) != null)
{
regelNummer++;
try
{
var verwerkteRegel = VerwerkRegel(regel, regelNummer);
writer.WriteLine(verwerkteRegel);
if (regelNummer % 100 == 0)
{
logger.Debug($"Verwerkt {regelNummer} regels");
}
}
catch (RegelVerwerkingsException ex)
{
logger.Warn(ex, $"Fout in regel {regelNummer}: {regel}");
// Doorgaan met volgende regel
}
}
logger.Info($"Totaal verwerkte regels: {regelNummer}");
}
}
private string VerwerkRegel(string regel, int regelNummer)
{
if (string.IsNullOrEmpty(regel))
{
logger.Debug($"Lege regel gevonden op positie {regelNummer}");
return string.Empty;
}
if (regel.Length > 1000)
{
logger.Warn($"Zeer lange regel ({regel.Length} chars) op positie {regelNummer}");
}
// Simuleer complexe verwerkingslogica
return regel.ToUpper();
}
}
```
## 3. Custom Exceptions en Exception Handler
```csharp
using System;
public class BestandVerwerkingsException : Exception
{
public string BestandPad { get; }
public BestandVerwerkingsException(string message, Exception innerException = null)
: base(message, innerException) {}
public BestandVerwerkingsException(string message, string bestandPad, Exception innerException = null)
: base(message, innerException)
{
BestandPad = bestandPad;
}
}
public class RegelVerwerkingsException : Exception
{
public int RegelNummer { get; }
public RegelVerwerkingsException(string message, int regelNummer, Exception innerException = null)
: base(message, innerException)
{
RegelNummer = regelNummer;
}
}
public static class ExceptionHandler
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
public static void HandleException(Exception ex, string context = "")
{
switch (ex)
{
case BestandVerwerkingsException bestandEx:
logger.Error(bestandEx, $"Bestandsverwerkingsfout: {context}");
break;
case RegelVerwerkingsException regelEx:
logger.Warn(regelEx, $"Regelverwerkingswaarschuwing: {context}");
break;
case IOException ioEx:
logger.Error(ioEx, $"IO-fout: {context}");
break;
default:
logger.Fatal(ex, $"Onverwachte fout: {context}");
break;
}
}
}
```
## 4. Hoofdapplicatie en Gebruik
```csharp
using System;
using NLog;
class Program
{
private static readonly Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
try
{
// Configureer logger
LoggerConfig.ConfigureLogger();
logger.Info("Applicatie gestart");
var verwerker = new BestandsVerwerker();
// Voorbeeldgebruik
verwerker.VerwerkBestand("input.txt", "output.txt");
logger.Info("Applicatie succesvol voltooid");
}
catch (Exception ex)
{
ExceptionHandler.HandleException(ex, "Hoofdapplicatie");
Console.WriteLine($"Er is een fout opgetreden: {ex.Message}");
}
finally
{
LogManager.Shutdown();
}
}
}
```
## 5. NLog.config (aanvullend configuratiebestand)
```xml
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<targets>
<target name="logfile" xsi:type="File"
fileName="${basedir}/logs/${shortdate}.log"
layout="${longdate} | ${level:uppercase=true} | ${logger} | ${message} ${exception:format=ToString}" />
<target name="errorfile" xsi:type="File"
fileName="${basedir}/logs/errors-${shortdate}.log"
layout="${longdate} | ${level} | ${logger} | ${message} ${exception:format=ToString}"
maxArchiveFiles="7" />
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="logfile" />
<logger name="*" minlevel="Error" writeTo="errorfile" />
</rules>
</nlog>
```
## Belangrijke kenmerken:
1. **Meerdere logniveaus**: Debug, Info, Warning, Error, Critical
2. **Gestructureerde exceptie-afhandeling**: Specifieke catch-blokken voor verschillende fouttypes
3. **Contextuele logging**: Bestandspaden, regelnummers en specifieke context
4. **Performance monitoring**: Logging van verwerkingsvoortgang
5. **Flexibele configuratie**: Aparte logbestanden voor errors en debug-informatie
6. **Custom exceptions**: Specifieke excepties voor domeingerelateerde fouten
Voeg NLog toe via NuGet: `Install-Package NLog`