Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

logowanie procedur T-SQL

2 views
Skip to first unread message

Maro

unread,
Nov 27, 2009, 11:43:17 AM11/27/09
to
Witam,

(Z gory przepraszam jesli NTG, temat na pograniczu C#/TSQL.)

Mamy w projekcie ologowany kod C# (biblioteka log4net), logi zapisuja
sie w bazie danych (poziom error) oraz w rolling files (wszystko),
swietnie sie to sprawdza. Jestesmy w stanie przesledzic wykonanie
wszystkich akcji w aplikacji do momentu wywolania procedury
skladowanej. W momencie przejscia wykonania na strone bazy danych,
wpadamy w czarna dziure. Jesli kod T-SQL rzuci wyjatkiem to nie ma
mozliwosci uzyskac informacji z ktorego konkretnie miejsca i jaka
instrukcja ten wyjatek spowodowala. Jest to zwlaszcza problematyczne w
przypadku, gdy wywolujemy jakas procedure (mamy wiec punkt
zaczepienia), ale ta procedura wywoluje kolejne procedury, te wywoluja
kolejne itd. Taki poziom komplikacji kodu bazodanowego sprawia duze
trudnosci przy wykrywaniu, analizowaniu i poprawianiu bledow.
Refaktoring warstwy bazodanowej niestety nie wchodzi w gre.

Padl zatem pomysl opracowania mechanizmu logownia wykonania kodu w
procedurach skladowanych T-SQL (SQL Server 2k5, szukuje sie "niedlugo"
migracja na 2k8). Czyli parafrazujac nazewnictwo cos typu "log4TSQL".
Idealnym rozwiazaniem byloby umieszczanie tychze logow do tego samego
rolling file'a, do ktorego pisze log4net, aby zachowac logiczna
kolejnosc wykonywania sie kodu oraz tym samym ulatwic support itd.
Innym rozwiazaniem jest rowniez wpisywanie logow do tabeli, wraz z
timestampem, poziomem komunikatu (debug, info, error, critical),
loginem itp. To podejscie jest o tyle dobre, ze pozwala latwo
filtrowac i przegladac logi, co w przypadku pliku tekstowego nie jest
mozliwe. Idealnym rozwiazaniem byloby polaczenie tych dwoch opcji, tak
jak to ma miejsce w log4net - dodajemy tylko odpowiedni appender.

Jesli zas chodzi o samo ologowanie procedur, to dobrym punktem
startowym byloby uzyskanie sytuacji, w ktorej mamy zalogowane wejscie
do procedury plus wartosc wszystkich parametrow oraz wyjscie z
procedury. Wyobrazam to sobie w ten sposob, aby napisac mechanizm,
ktory automatycznie do ciala kazdej procedury dodaje na poczatku
odpowiednie wywolanie innej procedury. W tej dodanej procedurze bedzie
juz sie odbywac logowanie. No i tutaj juz pierwsze schody - jak cos
takiego napisac. Reflksji nie mamy:) Jest widok, w ktorym sa trzymane
ciala wszystkich procedur, ale napisanie skryptu, ktory to potrafi
sprytnie przeparsowac i powstawiac "to co trzeba, tam gdzie trzeba"
juz nie wydaje sie wcale banalna sprawa. Dodatkowo dochodzi tu sprawa
wydajnosci - czy aby zbyt duzo insertow nie zarznie serwera. inna
sprawa, ktora rowniez mnie nurtuje to transakcje. Kod w C# jest
napisany w ten sposob, ze transakcja jest otwierana na poziomie
aplikacji i jesli z procedury przyjdzie wyjatek, to w catchu robimy
rollback. Jesli zatem bedziemy robic inserty z logami to jakiejs
tabeli to w momencie rollbacka zostajemy z wroblem na dachu. Moze da
sie zrobic cos w rodzaju wewnetrznej transakcji do wykonania tych
insertow?

Troche moj mail jest nieuporzadkowany, za co przepraszam. Jest mnostwo
znakow zapytania i watpliwosci (nie sposob nawet wszystkich wymienic),
a wolalbym nie zaczynac pracy nie majac pewnosci, ze warto. Mam
nadzieje, ze udalo mi sie w miare jasno nakreslic sytuacje :)

Uprzejmie bym prosil o jakies wskazowki, linki do artykulow (niestety
nie znalazlem niczego sensownego), Wasze doswiadczenia i sugestie. Jak
sobie poradzic z takim problemem. A moze mechanizm logowania T-SQL'a
to slepy zaulek i istnieje jakis lepszy, uniwersalny sposob na to?

Z gory dziekuje ze wszelkie porady.
Pozdrawiam uprzejmie,
Maro

wloochacz

unread,
Nov 30, 2009, 5:24:25 AM11/30/09
to
Maro pisze:

> Witam,
>
> (Z gory przepraszam jesli NTG, temat na pograniczu C#/TSQL.)
>
> Mamy w projekcie ologowany kod C# (biblioteka log4net), logi zapisuja
> sie w bazie danych (poziom error) oraz w rolling files (wszystko),
> swietnie sie to sprawdza. Jestesmy w stanie przesledzic wykonanie
> wszystkich akcji w aplikacji do momentu wywolania procedury
> skladowanej.
Co rozumiesz pod pojęciem "wszystkich akcji w aplikacji"?

> W momencie przejscia wykonania na strone bazy danych,
> wpadamy w czarna dziure. Jesli kod T-SQL rzuci wyjatkiem to nie ma
> mozliwosci uzyskac informacji z ktorego konkretnie miejsca i jaka
> instrukcja ten wyjatek spowodowala.
> Jest to zwlaszcza problematyczne w
> przypadku, gdy wywolujemy jakas procedure (mamy wiec punkt
> zaczepienia), ale ta procedura wywoluje kolejne procedury, te wywoluja
> kolejne itd. Taki poziom komplikacji kodu bazodanowego sprawia duze
> trudnosci przy wykrywaniu, analizowaniu i poprawianiu bledow.

Generalnie nie powinno być takiej sytuacji, że stor procka spowodowała jakiś wyjątek, który nie jest związany z logiką.
Skoro dzieje się to często - coś jest nie tak. Być może projekt bazy lub projektant...

> Refaktoring warstwy bazodanowej niestety nie wchodzi w gre.

Dlaczego?

> Padl zatem pomysl opracowania mechanizmu logownia wykonania kodu w
> procedurach skladowanych T-SQL (SQL Server 2k5, szukuje sie "niedlugo"
> migracja na 2k8). Czyli parafrazujac nazewnictwo cos typu "log4TSQL".
> Idealnym rozwiazaniem byloby umieszczanie tychze logow do tego samego
> rolling file'a, do ktorego pisze log4net, aby zachowac logiczna
> kolejnosc wykonywania sie kodu oraz tym samym ulatwic support itd.

> Innym rozwiazaniem jest rowniez wpisywanie logow do tabeli, wraz z
> timestampem, poziomem komunikatu (debug, info, error, critical),
> loginem itp. To podejscie jest o tyle dobre, ze pozwala latwo
> filtrowac i przegladac logi, co w przypadku pliku tekstowego nie jest
> mozliwe.

Taki genialny Log4Net i nie ma wygodnej przeglądarki?
Lipa.

> Idealnym rozwiazaniem byloby polaczenie tych dwoch opcji, tak
> jak to ma miejsce w log4net - dodajemy tylko odpowiedni appender.

Napisz sobie taki appender.
Być może już ktoś napisał stosowny - użyj głowy i maszyny CLR wbudowanej w MS SQL...

> Jesli zas chodzi o samo ologowanie procedur, to dobrym punktem
> startowym byloby uzyskanie sytuacji, w ktorej mamy zalogowane wejscie
> do procedury plus wartosc wszystkich parametrow oraz wyjscie z
> procedury.

Do tego nie jest potrzebny ŻADEN log_coś_tam_jakbyś_tego_super_nie nazwał po stronie bazy danych. Do realizacji tego
zdania wystarczy zalogować (w aplikacji) zawołanie procedury, dodać do tego wartości jej parametrów, nazwę i zalogować
wyjście z parametrami wyjściowymi.
To banalne przecież... Nie wiem czego używasz do uruchamiania procedur, ale co by to nie było to możesz dopisać taką
funkcjonalność do tej klasy. Jak - jak chcesz, programować w .NET chyba umiesz, bo ja nie za bardzo ;)
Oczywiście mam nadzieję, że do wołania procedur (jak i obsługi jej wyjątków po stronie aplikacji) masz ten sam kod
(klasa?), bo jeśli za każdym razem piszesz taki kod - to zmień podejście.

> Wyobrazam to sobie w ten sposob, aby napisac mechanizm,
> ktory automatycznie do ciala kazdej procedury dodaje na poczatku
> odpowiednie wywolanie innej procedury. W tej dodanej procedurze bedzie
> juz sie odbywac logowanie.

Można, ale po co?
A poza tym, taki mechanizm musiałby działać automatycznie i automatycznie walidować zmieniane procedury, np. za pomocą
DDL triggers...


> No i tutaj juz pierwsze schody - jak cos
> takiego napisac. Reflksji nie mamy:)

Re czego?
Ostatnio słyszałem, że programiści .NET nie umieją myśleć - zaczynam myśleć, że ten co to powiedział jednak nie jest
skończonym idiotą...
Tak naprawdę Twój problem jest banalny, tylko Ty szukasz gotowego rozwiązania zamiast spojrzeć na problem z większej
perspektywy i napisać sobie taki mechanizm w max kilka godzin... Prawdopodobnie nawet w kwadrans (włączając testy), pod
warunkiem że masz jeden zunifikowany kod, który zarządza wołaniem stor procek i obsługuje ich wyjątki.

> Jest widok, w ktorym sa trzymane
> ciala wszystkich procedur, ale napisanie skryptu, ktory to potrafi
> sprytnie przeparsowac i powstawiac "to co trzeba, tam gdzie trzeba"
> juz nie wydaje sie wcale banalna sprawa.

Trywialna.
Zrobię to za 2,5k i na jutro będziesz miał.
To naprawdę nie jest żaden problem dla kogoś, kto wie jak pisać T-SQLa, jak zapytać MS SQL o metadane opisujące
parametry procedury i jak to wykorzystać...

> Dodatkowo dochodzi tu sprawa
> wydajnosci - czy aby zbyt duzo insertow nie zarznie serwera.

Z tego co czytam, to tej bazie danych niewiele już zaszkodzi :)
A poważnie - insert do tabelki, która nie jest zbytnio obciążona indeksami i triggerami jest praktycznie pomijalną sprawą...

> inna
> sprawa, ktora rowniez mnie nurtuje to transakcje. Kod w C# jest
> napisany w ten sposob, ze transakcja jest otwierana na poziomie
> aplikacji i jesli z procedury przyjdzie wyjatek, to w catchu robimy
> rollback. Jesli zatem bedziemy robic inserty z logami to jakiejs
> tabeli to w momencie rollbacka zostajemy z wroblem na dachu. Moze da
> sie zrobic cos w rodzaju wewnetrznej transakcji do wykonania tych
> insertow?

Eeee.... nie.
Da się zrobić transakcję zagnieżdżoną, ale ona też zostanie cofnięta.

> Troche moj mail jest nieuporzadkowany, za co przepraszam. Jest mnostwo
> znakow zapytania i watpliwosci (nie sposob nawet wszystkich wymienic),
> a wolalbym nie zaczynac pracy nie majac pewnosci, ze warto. Mam
> nadzieje, ze udalo mi sie w miare jasno nakreslic sytuacje :)
>
> Uprzejmie bym prosil o jakies wskazowki, linki do artykulow (niestety
> nie znalazlem niczego sensownego), Wasze doswiadczenia i sugestie. Jak
> sobie poradzic z takim problemem. A moze mechanizm logowania T-SQL'a
> to slepy zaulek i istnieje jakis lepszy, uniwersalny sposob na to?

A tak naprawdę... to nie ma w tym czymś, czego używasz, coś na kształt SQL Monitor po stronie aplikacji?
Wyobrażam to sobie po prostu jako event, do którego się podłączasz i masz dokładnie wszystko co jest wysyłane (i
odbierane; a więc preparacja T-SQla, wykonanie T-SQLa, fetchowanie danych itd.) do bazy danych.

--
wloochacz

yamma

unread,
Nov 30, 2009, 10:24:48 AM11/30/09
to
Maro wrote:
> Witam,
>
> (Z gory przepraszam jesli NTG, temat na pograniczu C#/TSQL.)

Skoro temat na pograniczu C#/TSQL, to moze zainteresuj sie tym:
http://www.sqlteam.com/article/writing-clr-stored-procedures-in-charp-introduction-to-charp-part-1
W ten spos�b m�glbys sprawdzac parametry wejsciowe i wyjscie z procedur oraz
ewentualne wyjatki, natomiast wymagaloby to dosc mocnego refaktoringu
aplikacji.
yamma

0 new messages