SQL Server – Listowanie dzienników zdarzeń Windows (CLR)
Posted by C3PO w dniu 9 Lipiec 2010
Jeden z czytelników mojego bloga (Michał, pozdrawiam) napisał mi w mailu, że chciałby mieć funkcję w SQL Server dzięki której mógłby przeglądać dzienniki zdarzeń Windows. Co prawda w Management Studio można przeglądać dzienniki zdarzeń Windows razem z logiem samego SQL Servera. Ale jeżeli ktoś chce działać kodem T-SQL lub móc z jakichś powodów przerzucać dane z dzienników zdarzeń do tabel w bazach danych, przydałaby się funkcja, która umożliwi dostęp do wybranego dziennika na wybranej maszynie.
Kod takiej funkcji może wyglądać tak:
using System;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Collections;
using System.Diagnostics;
public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction(
Name = "ufn_clr_GetEventLog",
FillRowMethodName = "FillEventLogRow",
TableDefinition = "EntryType nvarchar(50), " +
"TimeWritten datetime, " +
"Source nvarchar(4000), " +
"InstanceId bigint, " +
"Category nvarchar(255), " +
"Message nvarchar(max)"
)]
public static IEnumerable ReadLog(SqlString LogName, SqlString MachineName)
{
EventLog log = new EventLog();
return new EventLog(LogName.Value, MachineName.Value).Entries;
}
public static void FillEventLogRow(
Object Obj,
out SqlString EntryType,
out SqlDateTime TimeWritten,
out SqlString Source,
out SqlInt64 InstanceId,
out SqlString Category,
out SqlString Message
)
{
EventLogEntry entry = (EventLogEntry)Obj;
EntryType = entry.EntryType.ToString();
TimeWritten = new SqlDateTime(entry.TimeWritten);
Source = entry.Source;
InstanceId = new SqlInt64(entry.InstanceId);
Category = entry.Category;
Message = entry.Message;
}
};
Szybki komentarz do kodu:
- jest to klasyczna funkcja tabelaryczna CLR (zwraca kolekcję zgodną z interfejsem IEnumerable),
- w atrybucie SqlFunction definiujemy schemat tabeli zwracanej przez funkcji,
- metoda FillEventLogRow jest typowym “wypełniaczem” pojedynczego wiersza kolekcji zwracanej przez funkcję.
Kod wklejamy w Visual Studio do pliku .cs w projekcie opartym o szablon Database Project (C#). Wrzucamy assembly (PERMISSION_SET = UNSAFE) i funkcję do bazy danych (w Visiaul Studio w menu głównym kliknij Build – Deploy <nazwa_projektu>). Wywołanie tej funkcji może wyglądać tak (oczywiście, tu trzeba zadbać, by konto Windows, w kontekście którego działa SQL Server, miało możliwość podlgądania wskazanego dziennika zdarzeń):
SELECT * FROM dbo.ufn_clr_GetEventLog('Application', 'MojSerwer');
Przykładowy wynik:
Oczywiście, nie polecam za często uruchamiać tej funkcji na logach zawierających dużo wpisów. Lepiej z jej pomocą zaimportować wpisy zdarzeń do bazy danych do zaindeksowanej tabeli i później już zapytaniami filtrować, listować, grupować i co tam jeszcze przychodzi komu do głowy.
Uff, dwa posty w ciągu jednego dnia? Chyba oszalałem ;-) Obiecuję już tak nie robić więcej. I chwilowo dość pisania o CLR. Miłego weekendu.

Michał powiedział/a
Dziękuje :)
Rzadko się zdaża, żeby ktoś bezinteresownie /tak sądze ;) / takie pomoce udostepniał dla osób mi podobnych (początkujący DD, full DBA ;)
Pozdrawiam Kolegę i zyczę sukcesów w blogowaniu i spokojnego wypoczywania nie tylko przy pisaniu bloga ;)
C3PO powiedział/a
Michał, życie nauczyło mnie, że zazwyczaj dając coś z siebie dostaję wiele od innych. Nie inaczej jest z technologią. Jest wiele osób, o których mógłbym napisać, że w pewnym sensie mnie inspirują, czy czerpię z ich wiedzy. I tak to działa i mam nadzieję będzie działało. A najważniejsze, to nie pozwolić, by uszło z Ciebie powietrze (byś stracił zamiłowanie do tego, co lubisz i – mam nadzieję – robisz) ;-) Również udanego ew. urlopu :-)
SQL Server – Listowanie ostatnich N zdarzeń z dziennika zdarzeń (CLR) « Jasne i ciemne strony baz danych powiedział/a
[...] czytać dzienniki zdarzeń systemu Windows za pomocą funkcji napisanej dla SQL Servera w CLR (patrz tutaj). Jednak podana funkcja ma podstawową wadę – czyta cały dziennik, a to oczywiście może [...]
[PL] SQL Server – Listowanie ostatnich N zdarzeń z dziennika zdarzeń (CLR) « SQLGeek.pl powiedział/a
[...] czytać dzienniki zdarzeń systemu Windows za pomocą funkcji napisanej dla SQL Servera w CLR (patrz tutaj). Jednak podana funkcja ma podstawową wadę – czyta cały dziennik, a to oczywiście może [...]