Veľmi dôležitou vecou, ktorú musí mať každá aplikácia, je logovanie
chýb. Pre .NET aplikácie existuje výborná knižnica log4net. Síce jej chýba priamo
zabudovaný výstup do XML dokumentu, obsahuje generovanie XML fragmentov do
textového súboru a ten je možné potom vložiť ako externú
entitu do XML dokumentu.
log4net obsahuje dobrý základ pre logovanie chýb pomocou vlastných,
špecializovaných, objektov. Pomocou nich je možné napr. zalogovať podrobne
chyby v SQL príkaze, alebo všetky SQL príkazy, ktoré boli asociované
s DataAdapter-om, v ktorom nastala chyba. Takto je možné zistiť aj v akom
stave bolo spojenie s databázou.
Logovací systém log4net sa skladá z týchto základných objektov:
-
Layout – stará sa o formát, v akom budú logované záznamy
uložené.
-
Appender – ukladá záznamy do logovacieho výstupu. Výstup môže byť
súbor, databáza, konzola, logovací server a pod.
-
Filter – filtruje úroveň (Level) záznamov a iné vlastnosti, na
základe ktorých logovaný záznam predá appenderu, alebo nepredá.
-
Všetky logovacie metódy rozhrania ILog prijímajú ako
prvý parameter object, druhý, nepovinný, je
Exception. Napr.:
ILog.Error(object
message, Exception exception);
Pri spracovaní logovaného objektu (väčšinou v metóde
LayoutBase.Format(), v prípade XmlLayout-u vo FormatXml()) sa zavolá
message.ToString(). Štandardne sa do metódy posiela
string (zložitejší text sa formátuje napr. pomocou
ErrorFormat(string format, params
object[] args)). Nič nám však nebráni si
napísať vlastný logovací objekt, ktorý bude preťažovať metódu
ToString().
Prvá trieda je celkom jednoduchá: do textového logu vypisuje len chybovú
správu. (Zdrojový kód
SimpleLogItem)
public class SimpleLogItem
{
private string _message;
public SimpleLogItem()
: this("")
{ }
public SimpleLogItem(string message)
: this (message, null)
{ }
public SimpleLogItem(string message, params object[] args)
{
if (message != null)
_message = String.Format(message, args);
else
_message = message;
}
public string Message
{
get { return this._message == null ? "" : _message; }
}
public override string ToString()
{
return String.Concat("[Log message] ", Message);
}
}
Konštruktor SimpleLogItem priamo podporuje formátovanie
textu pre väčšie pohodlie. Celkovo však táto trieda nerobí nič, čo by sa
nedalo dosiahnuť „Format“ metódami v ILog. Slúži však
ako veľmi jednoduchý základ pre sofistikovanejšiu triedu:
SimpleSqlLogItem.
Zdrojový kód
triedy SimpleSqlLogItem je celkom veľký takže na neho
uvádzam len linku. Uvediem len použitie a výstup logu.
SqlCommand cmd;
SqlConnection conn;
// …
try
{
SqlDataReader reader = cmd.ExecuteReader();
// …
}
catch (SqlException ex)
{
log.Warn(new SimpleSqlLogItem(cmd, „Nepodarilo sa získať informácie o užívateľovi.“));
}
finally
{
conn.Close();
}
SimpleSqlLogItem môže naformátovať výstup napríklad
takto:
[Log message] Nepodarilo sa získať informácie o užívateľovi.
[SQL Command] SELECT id, meno, email FROM uzivatelia WHERE id = @ID AND meno = @meno
[param] int @ID = 1
[param] varchar @meno = ‚Administáror‘
[Connection] DBSERVER\SQLEXPRESS:UkazkovaDB (Open)
Btw: v tomto príklade sa nepodarilo získať informácie o užívateľovi
pretože dátový typ parametru @meno by mal byť
nvarchar. Takéto logovanie dokáže zachytiť aj aktuálny
stav pripojenia do databázy, pretože získanie stavu objektu
SqlCommand.Connection sa vykoná pred uzavretím spojenia
v kóde finally.
Nabudúce popíšem spôsob vytvorenia vylepšeného LogItem-u, ktorý bude
používať XmlWriter na zápis údajov.