Chciałbym przechwycić wyjątki i zalogować je w pliku dziennika systemu Windows. Jak mogę otworzyć i zapisać w dzienniku systemu Windows?Zapisywanie wyjątków do pliku dziennika systemu Windows
Odpowiedz
Możesz użyć funkcji System.Diagnostics.EventLog.WriteEntry, aby wpisywać wpisy do dziennika zdarzeń.
System.Diagnostics.EventLog.WriteEntry("MyEventSource", exception.StackTrace,
System.Diagnostics.EventLogEntryType.Warning);
Aby odczytać dzienniki zdarzeń, można użyć funkcji System.Diagnostics.EventLog.GetEventLogs.
//here's how you get the event logs
var eventLogs = System.Diagnostics.EventLog.GetEventLogs();
foreach(var eventLog in eventLogs)
{
//here's how you get the event log entries
foreach(var logEntry in eventLog.Entries)
{
//do something with the entry
}
}
Oto prosta odpowiedź na piśmie do dziennika zdarzeń: http://support.microsoft.com/kb/307024
Lepszym rozwiązaniem jest użyć czegoś jak log4net, który zajmie to za Ciebie.
System Windows używa dziennika zdarzeń do śledzenia aktywności. Można użyć klasy System.Diagnostics.Trace
:
var traceSwitch = new TraceSwitch("MySwitch", "");
var exception = new Exception("Exception message");
if (traceSwitch.TraceError)
{
Trace.TraceError(exception);
}
i można użyć app.config pouczać rejestratora gdzie napisać:
<system.diagnostics>
<switches>
<add name="MySwitch" value="Verbose" />
</switches>
<trace autoflush="true">
<listeners>
<add name="EventLogger"
type="System.Diagnostics.EventLogTraceListener"
initializeData="NameOfYourApplication" />
</listeners>
</trace>
</system.diagnostics>
Można również rozważyć użycie Enterprise Library. Początkowo wygląda na skomplikowaną, ale godzina lub dwie gra się opłacą. Konfiguracja jest przechowywana w app.config, dzięki czemu możesz ją zmienić bez rekompilacji - może to być bardzo przydatne, gdy masz ten sam kod na serwerze testowym i na żywo z różnymi konfiguracjami. Możesz zrobić całkiem dużo bez mnóstwa kodu.
Jedną dobrą rzeczą jest to, że można zdefiniować zasady wyjątków, aby wyjątki były automatycznie rejestrowane. Oto niektóre kodu można użyć (używam EntLib 4.1):
try
{
//This would be where your exception might be thrown. I'm doing it on
//purpose so you can see it work
throw new ArgumentNullException("param1");
}
catch (Exception ex)
{
if (ExceptionPolicy.HandleException(ex, "ExPol1")) throw;
}
Linia w bloku catch będzie przekaż wyjątek JEŻELI ExPol1 definiuje go. Jeśli ExPol1 jest skonfigurowany do ponownego rzucania, wyjątek ExceptionPolicy.HandleException zwróci wartość true. Jeśli nie, zwraca wartość false.
Definiujesz resztę w config. XML wygląda dość okropnie (nie zawsze), ale tworzysz go za pomocą edytora konfiguracji Biblioteki korporacyjnej. Po prostu dostarczam go dla kompletności.
W sekcji loggingConfiguration plik ten definiuje
- dziennik: Plik dziennika tekst toczenia (można użyć wbudowanego w dziennikach zdarzeń Windows, tabel SQL, email, Msmq i inne) z
- do formatowania tekstu, które reguluje, w jaki sposób parametry są zapisywane w dzienniku (czasami skonfigurować to napisać wszystko do jednej linii, inne czasy rozłożone wielu),
- jednej kategorii „Ogólne”
- Source Special które pułapki wszelkie błędy w config/entlib i repo rts je również. Zdecydowanie radzę to zrobić.
W sekcji exceptionHandling definiuje
- jednolitej polityki: "ExPo1", która obsługuje typ ArgumentNullExceptions i określa postHandlingAction None (to znaczy nie rethrow).
- handler, który loguje się do kategorii Ogólne (zdefiniowany powyżej)
Nie rób tego w tym przykładzie, ale można również zastąpić wyjątek z wykorzystaniem innego rodzaju polityki.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
<section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<loggingConfiguration name="Logging Application Block" tracingEnabled="true"
defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
<listeners>
<add fileName="rolling.log" footer="" formatter="Text Formatter"
header="" rollFileExistsBehavior="Overwrite" rollInterval="None"
rollSizeKB="500" timeStampPattern="yyyy-MM-dd" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
traceOutputOptions="None" filter="All" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Rolling Flat File Trace Listener" />
</listeners>
<formatters>
<add template="Timestamp: {timestamp}; Message: {message}; Category: {category}; Priority: {priority}; EventId: {eventid}; Severity: {severity}; Title:{title}; Machine: {machine}; Application Domain: {appDomain}; Process Id: {processId}; Process Name: {processName}; Win32 Thread Id: {win32ThreadId}; Thread Name: {threadName}; 
 Extended Properties: {dictionary({key} - {value})}"
type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Text Formatter" />
</formatters>
<categorySources>
<add switchValue="All" name="General">
<listeners>
<add name="Rolling Flat File Trace Listener" />
</listeners>
</add>
</categorySources>
<specialSources>
<allEvents switchValue="All" name="All Events" />
<notProcessed switchValue="All" name="Unprocessed Category" />
<errors switchValue="All" name="Logging Errors & Warnings">
<listeners>
<add name="Rolling Flat File Trace Listener" />
</listeners>
</errors>
</specialSources>
</loggingConfiguration>
<exceptionHandling>
<exceptionPolicies>
<add name="ExPol1">
<exceptionTypes>
<add type="System.ArgumentNullException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
postHandlingAction="None" name="ArgumentNullException">
<exceptionHandlers>
<add logCategory="General" eventId="100" severity="Error" title="Enterprise Library Exception Handling"
formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
priority="0" useDefaultLogger="false" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
name="Logging Handler" />
</exceptionHandlers>
</add>
</exceptionTypes>
</add>
</exceptionPolicies>
</exceptionHandling>
</configuration>
Te artykuły wyjaśnić, jak do automatycznego logowania niedotykane wyjątki, które mogą wystąpić:
VB.NET: http://visualbasic.about.com/od/usingvbnet/a/logging.htm
C#: Where to write the functions of ApplicationEvents.vb when converting project to C#
Czy to nie jest trochę niegrzeczny do -1 coś bez wytłumaczenia? Co zrobiłem źle? – serialhobbyist