Introduzione
Durante lo sviluppo di un’applicazione è buona norma pensare ad un'infrastruttura di log che consenta di avere una traccia dei comportamenti assunti dal nostro codice. Molto spesso alcuni di noi pensano che il logging sia sviluppo da poter implementare alla fine, anche se sarebbe meglio pensarci fin da subito.
Sapere come si comporta il nostro applicativo, anche durante i vari test, oppure conoscere gli esiti di particolari chiamate, sono tutte cose utilissime per capire se il nostro software si comporta come dovrebbe e quindi se risulta affidabile.
SSIS ci facilita le operazioni con i suoi
Log Provider. Ma andiamo a parlarne più in dettaglio.
Scenario
A titolo di esempio, ecco uno scenario generico, che usufruisce di vari tipi di task. Prendiamo come esempio un package, che legge dati da un xml, lo valida tramite un xsd, e lo elabora inserendo i dettagli all’interno di una tabella di
SQL Server 2005. Se i record esistono già li aggiorna, altrimenti li inserisce. Nello specifico, l'
XML contiene l’elenco di alcuni utenti e la tabella
SQL Server 2005 è la tabella dbo.Utenti. Ma procediamo per step:
Creazione tabella di destinazione, del file sorgente e dello schema XSD
Listato N°1 - Creazione tabella dbo.UtentiCREATE TABLE dbo.Utenti
(
IDUtente int NOT NULL
, Nome varchar(30) NOT NULL
, Cognome varchar(30) NOT NULL
, Eta tinyint NOT NULL
, Indirizzo varchar(100) NOT NULL
, CONSTRAINT PK_Utenti PRIMARY KEY CLUSTERED
(
IDUtente
)
)
La chiave primaria è l'
IDUtente e tutti i campi non accettano
NULL.
Listato N°2 – File xml degli utenti<?xml version="1.0" encoding="utf-8" ?>
<Utenti>
<Utente ID="1" Nome="Alessandro" Cognome="Alpi" Eta="26" Indirizzo="Via Verdi 10"></Utente>
<Utente ID="2" Nome="Marco" Cognome="Rossi" Eta="26" Indirizzo="Via Roma 20"></Utente>
<Utente ID="3" Nome="Michael" Cognome="Denny" Eta="24" Indirizzo="Via Venezia 30"></Utente>
<Utente ID="4" Nome="Matteo" Cognome="Celaschi" Eta="28" Indirizzo="Via Mantova 15"></Utente>
<Utente ID="5" Nome="Manuele" Cognome="Carra" Eta="26" Indirizzo="Via Bianchi 25"></Utente>
</Utenti>
Listato N°3 – Schema XSD<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Utenti">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Utente">
<xs:complexType>
<xs:attribute name="ID" type="xs:unsignedByte" use="required" />
<xs:attribute name="Nome" type="xs:string" use="required" />
<xs:attribute name="Cognome" type="xs:string" use="required" />
<xs:attribute name="Eta" type="xs:unsignedByte" use="required" />
<xs:attribute name="Indirizzo" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Composizione del package SSIS
Dopo aver creato la struttura che conterrà i dati ed aver definito la sorgente, andiamo a scrivere il control flow del nostro
SSIS. Come prima cosa, aggiungiamo due
File Connection fra i manager delle connessioni. Sono rispettivamente i file
Utenti.xml ed
Utenti.xsd, uno il file sorgente l’altro lo schema di validazione. Aggiungiamo poi un task XML per eseguire la validazione del documento sorgente, configurato come segue:
Il tipo di operazione deve essere impostato su
Validate. Selezionandolo la finestra delle proprietà cambierà aspetto, lasciando la possibilità di impostare particolari parametri, diversi da quelli proposti nell’operazione di default proposta (Diff). Come si può notare vi sono due proprietà importanti che definiscono i parametri per la validazione, la Source e la SecondOperand, che sono proprietà definite come FileConnection nelle rispettive proprietà collegate (quelle con suffisso Type). La prima è il file
Utenti.xml e la seconda è il file
Utenti.xsd. Infine vi è un’ultima opzione che consente di specificare se il task deve fallire o meno in caso di errore di validazione.
Aggiungiamo ora il dataflow che conterrà la logica di caricamento dei dati:
Ci spostiamo successivamente nel dataflow (doppio click sul Data Flow Task) ed andiamo a creare una nuova sorgente
XML.
Immettiamo i percorsi dell'
XML e dell'
XSD (purtroppo non possiamo usare i connection manager direttamente). Come possiamo notare vi è anche un flag
"Use Inline Schema" che consente di utilizzare uno schema già definito nell'
XML sorgente. In aggiunta vi è anche il pulsante atto a generare il file xsd, qualora non se ne avesse già uno disponibile. Nel nostro esempio, abbiamo sia il file sorgente sia il suo validatore.
Selezioniamo in seguito le colonne lette dallo schema:
È possibile anche rinominare i nomi delle colonne in output a questo task, qualora il nome di quelle proposte dallo schema non soddisfi i vostri criteri.
Siccome nel nostro esempio gli attributi stringa del file xml possono contenere anche stringhe unicode, siamo costretti a convertirli in stringhe non unicode affinché possano essere inserite nei campi varchar della tabella dbo.Utenti. Perciò dobbiamo aggiungere un task di conversione:
Selezioniamo le colonne da convertire e ne definiamo il nuovo tipo e lunghezza, dichiarando anche il nome delle colonne "nuove". Nell’esempio,
nome colonna + STR.
Per chiudere la definizione della logica del package, andiamo ad aggiungere una connessione OLEDB verso SQL Server 2005 ed il relativo task OLEDB Destination, da noi rinominato in
tbl Utenti:
A questo punto il package è pronto per essere eseguito. Possiamo quindi implementare la logica di logging vedendo come
SSIS ci rende piuttosto semplice la questione.
I Log Providers
Attraverso il menu
SSIS è possibile accedere alla definizione dei cosiddetti
Log Providers. Sono degli strumenti in grado di tracciare particolari (e selezionabili) eventi che vengono scatenati durante l’esecuzione dei task di un package. I provider possibili su Integration Services sono cinque:
1) Text File, che scrive il log su file di testo (csv)
2) XML File, che lo scrive su file xml
3) SQL Server 2005, che lo scrive su di una tabella chiamata sysdtslog90
4) Profiler, che scrive il log su di un file trc pronto per essere caricato su SQL Server Profiler
5) Event Log, che lo scrive sul registro degli eventi (Application log)
Ma ecco come appare l’interfaccia della selezione del provider:
Non ci resta che selezionarne uno e premere
Add.. Apparirà un provider apposito per la gestione del log. Ovviamente è possibile crearne più di uno, anche di tipo diverso, proprio per dare la possibilità all’utente di avere più punti di accesso.
Una volta selezionati uno o più provider, dobbiamo decidere se e quali attivare, spuntando il check alla sinistra del provider stesso. È possibile scegliere i provider solo quando esiste almeno un oggetto per il quale creare un log. Di conseguenza è necessario spuntare i task che si vogliono considerare nella traccia.
A titolo di esempio, selezioniamo tutto il package, clickando sul box a fianco della cartella Logging ed aggiungiamo un provider di ogni tipo, giusto per poter vedere i risultati in ogni modo possibile:
Ogni provider è stato selezionato ed ogni task del package è pronto per essere scritto nei vari log. Però mancano ancora alcune impostazioni. Innanzitutto, è necessario definire un connection manager per ogni provider, per indicare dove andare a scrivere i risultati. È possibile definirli direttamente da questa interfaccia, premendo su una delle celle della colonna Configuration. Si tratta di tre connessioni di tipo file e consiglio di creare a priori i file che conterranno il log, in modo da essere più veloci nell’assegnazione dei connection manager. Quella per
SQL Server è
OLEDB e possiamo utilizzare ad esempio, la stessa del database di destinazione del caricamento dati. Il provider per l’event viewer non necessita di configurazioni.
Altra caratteristica non trascurabile è quella di poter selezionare cosa portare nei nostri log. Spostarsi sul tab Details e definire le entry da includere. In basso nella form vi è un tasto
Advanced che consente di definire non solo gli eventi da tracciare ma anche la qualità di ogni riga che andiamo a scrivere. Se non volete che i vostri log diventino di dimensioni spropositate dopo poco tempo, utilizzate l’interfaccia avanzata e selezionate le sole colonne utili ai vostri scopi. Qui di seguito un modo per ridurre il logo alle informazioni strettamente necessarie:
Come potete notare, a fianco del tasto
Advanced/Basic vi sono due ulteriori pulsanti.
Load e Save ci consentono di salvare un template di log in formato
XML per poi poterlo caricare ogni qual volta riteniamo necessario seguire la stessa strada. E questa opzione, è molto comoda, soprattutto se avete l’abitudine di seguire sempre lo stesso modello di log, senza per forza ripetere tutte le selezioni.
Esecuzione del package e visualizzazione del log
Ma ora passiamo all’esecuzione del package. La prima volta il log non presenterà alcun errore al suo interno, poiché la tabella dbo.Utenti è inizialmente vuota, mentre alla seconda esecuzione il sarà leggermente diverso.
Risultati prima esecuzione, tutto corretto:
CSV FileXML FileTraccia ProfilerRisultati seconda esecuzione, errore di inserimento (chiave doppia sugli utenti, poiché cerco di inserire gli stessi dati):
CSV FileXML FileTraccia ProfilerEseguendo la seguente query sul database nel quale risiede la tabella utenti otterremo inoltre i dati relativi alla tabella
sysdtslog90, che contiene i log di tutte le esecuzioni effettuate:
SELECT
[event]
, Computer
, Operator
, Source
, [Message]
, StartTime
, EndTime
FROM
sysdtslog90
Ovviamente è possibile filtrare i risultati, ad esempio per controllare ogni volta che il
SSIS è andato in errore:
SELECT
[event]
, Computer
, Operator
, Source
, [Message]
, StartTime
, EndTime
FROM
sysdtslog90
WHERE
[event] = 'OnError'
Ed infine diamo uno sguardo anche all'
Event Viewer:
Oltre ai cinque tipi di provider disponibili, vi è la possibilità di scriverne di custom. I Books on line danno alcune istruzioni ma sulla rete è possibile trovare alcuni esempi in merito. Allego nelle risorse alcuni link utili.
Conclusioni
Abbiamo visto come sia semplice creare un’infrastruttura di log tramite
SSIS ed i suoi provider. Si tratta solo di impostare una o più tipologie di log, definire quali eventi e quali caratteristiche tracciare ed il gioco è fatto.
Vi è da dire che ogni nuova esecuzione incrementerà la dimensione del/dei file in maniera piuttosto imponente. Nel nostro esempio il file più piccolo, in caso di errore, incrementa di 20k, che non sono pochi.
Ovviamente bisogna considerare la frequenza di esecuzione, la grandezza del package che scrive il log, gli eventi e le entry selezionate. Comunque sia, a parte per il provider dell'
Event Viewer, sarebbe meglio prevedere una logica di archiviazione e/o svecchiamento dei log, per non dover gestire spiacevoli situazioni come quella del disco pieno o del file xml troppo grande per essere letto in tempi brevi. Quindi fate attenzione alla crescita dei vostri log. Tuttavia, vorrei chiudere sottolineando l’importanza di queste operazioni. Sono quelle che vi permettono di capire l’affidabilità del vostro package e della vostra applicazione in generale, quindi non dimenticate mai di scrivere log.
Link di approfondimento
DTLoggedExec, applicazione scritta da Davide Mauri per la gestione dei log di SSIS su codeplex.
DTLoggedExec XML TaskLink MSDN XML SourceBlog Link MSDN Data Conversion TransformationLink MSDN OLEDB Destination TaskBlog Link MSDN Connection ManagerBlog Link MSDN Custom Log ProvidersBlog Blog Link Technet