Suggerimenti per la registrazione tramite ULS (Unified Logging Service)
Suggerimenti per la registrazione tramite ULS (Unified Logging Service)
Aggiornato il 4/2/2011: consiglio di consultare la versione aggiornata dell'esempio illustrato in questo post, all'indirizzo https://blogs.msdn.com/b/sharepoint_it/archive/2011/03/21/suggerimenti-per-la-registrazione-tramite-uls-unified-logging-service-parte-2.aspx . Il nuovo esempio è migliore e contiene funzionalità più complete.
Quando ho aggiunto la registrazione tramite ULS a un progetto recente, ho notato uno spiacevole inconveniente. Nei registri ULS l'area viene indicata come "sconosciuta". Anche se alcuni aspetti di questo problema sono già stati trattati altrove, ho deciso di creare un breve post riassuntivo in cui illustrare le informazioni che ho trovato e il metodo più rapido per risolvere il problema (sicuramente meno complicato di alcune soluzioni alternative descritte in altri articoli). Vale la pena di segnalare che, se non desiderate implementare questa soluzione personalmente, potete utilizzare il Framework di registrazione creato dal team delle best practice su CodePlex, in cui è già implementata. Ma poiché quando posso preferisco scrivere il codice personalmente, ora vi illustro brevemente la mia soluzione.
Occorre innanzitutto osservare che la maggior parte della documentazione dell'SDK presuppone la creazione di un nuovo oggetto SPDiagnosticsCategory. Il costruttore delle nuove istanze della classe consente di specificare il nome della categoria. In questo modo, è possibile visualizzare qualsiasi nome di categoria personalizzato nella colonna della categoria del registro USL. Nella maggior parte dei casi, quando si utilizza la registrazione personalizzata si desidera creare anche un'area personalizzata da associare alle categorie personalizzate. Sfortunatamente, la tecnica prevista a questo scopo dall'SDK è decisamente troppo complicata, perché non è possibile utilizzare un semplice costruttore per creare e utilizzare una nuova area, ma è necessario creare una classe personalizzata che deriva da SPDiagnosticsServiceBase.
Per implementare questa soluzione, ho scelto di creare un singolo file CS che contiene sia la classe di registrazione, sia la classe di base del servizio di diagnostica. Inizierò dalla classe di base del servizio di diagnostica. Di seguito ho incollato l'intera classe e più avanti illustrerò gli aspetti più interessanti.
public class SteveDiagnosticService : SPDiagnosticsServiceBase
{
private const string LOG_AREA = "Steve Area";
public enum LogCategories
{
SteveCategory
}
public SteveDiagnosticService()
: base("Steve Diagnostics Service", SPFarm.Local)
{
}
public SteveDiagnosticService(string name, SPFarm parent)
: base(name, parent)
{
}
protected override bool HasAdditionalUpdateAccess()
{
return true;
}
public static SteveDiagnosticService Local
{
get
{
return SPDiagnosticsServiceBase.GetLocal<SteveDiagnosticService>();
}
}
public void LogMessage(ushort id, LogCategories LogCategory, TraceSeverity traceSeverity,
string message, params object[] data)
{
if (traceSeverity != TraceSeverity.None)
{
SPDiagnosticsCategory category
= Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];
Local.WriteTrace(id, category, traceSeverity, message, data);
}
}
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsCategory> categories = new List<SPDiagnosticsCategory>();
categories.Add(new SPDiagnosticsCategory(
LogCategories.SteveCategory.ToString(),
TraceSeverity.Medium, EventSeverity.Information));
SPDiagnosticsArea area = new SPDiagnosticsArea(
LOG_AREA, 0, 0, false, categories);
List<SPDiagnosticsArea> areas = new List<SPDiagnosticsArea>();
areas.Add(area);
return areas;
}
}
Ora esaminiamo le parti più interessanti:
private const string LOG_AREA = "Steve Area";
Questa istruzione definisce il nome dell'area da scrivere nel registro ULS.
public enum LogCategories
{
SteveCategory
}
Questo è l'elenco delle categorie che intendo aggiungere all'area personalizzata. In questo caso desidero utilizzare una sola categoria con quest'area, ma se volessi aggiungerne molte altre, mi basterebbe espandere i contenuti dell'enumerazione.
public void LogMessage(ushort id, LogCategories LogCategory, TraceSeverity traceSeverity,
string message, params object[] data)
{
if (traceSeverity != TraceSeverity.None)
{
SPDiagnosticsCategory category
= Local.Areas[LOG_AREA].Categories[LogCategory.ToString()];
Local.WriteTrace(id, category, traceSeverity, message, data);
}
}
Questo è uno dei due metodi importanti che ho implementato e che eseguono la scrittura effettiva nel registro ULS. Nella prima riga viene recuperato l'oggetto SPDiagnosticCategory, facendo riferimento all'area a cui appartiene. Nella seconda riga viene semplicemente chiamato il metodo della classe di base sulla classe SPDiagnosticsServiceBase locale, per scrivere nel registro ULS, e nel farlo viene passata al metodo la categoria associata all'area personalizzata.
protected override IEnumerable<SPDiagnosticsArea> ProvideAreas()
{
List<SPDiagnosticsCategory> theCategories = new List<SPDiagnosticsCategory>();
theCategories.Add(new SPDiagnosticsCategory(
LogCategories.SteveCategory.ToString(),
TraceSeverity.Medium, EventSeverity.Information));
SPDiagnosticsArea theArea = new SPDiagnosticsArea(
LOG_AREA, 0, 0, false, theCategories);
List<SPDiagnosticsArea> theArea = new List<SPDiagnosticsArea>();
theArea.Add(area);
return theArea;
}
Questo override restituisce tutte le aree personalizzate a SharePoint. In questo caso intendo utilizzare solo l'area personalizzata che ho creato, quindi restituirò solo quella. Come ho accennato in precedenza, ho scelto di utilizzare una sola categoria personalizzata con tale area. Per utilizzare più categorie personalizzate, dovrei 1) aggiungerle all'enumerazione descritta in precedenza e 2) aggiungere le singole categorie all'istanza dell'elenco theCategories definita in questo metodo.
Questo è di fatto ciò che consente di aggiungere un'area personalizzata e visualizzarla nella colonna appropriata dei registri ULS. Anche l'implementazione della classe di registrazione è piuttosto intuitiva. Di seguito ho incollato la parte principale di tale classe, che illustrerò più avanti.
public class Log
{
private const int LOG_ID = 11100;
public static void WriteLog(string Message, TraceSeverity TraceLogSeverity)
{
try
{
//in this simple example, I’m always using the same category
//you could of course pass that in as a method parameter too
//and use it when you call SteveDiagnosticService
SteveDiagnosticService.Local.LogMessage(LOG_ID,
SteveDiagnosticService.LogCategories.SteveCategory,
TraceLogSeverity, Message, null);
}
catch (Exception writeEx)
{
//ignore
Debug.WriteLine(writeEx.Message);
}
}
}
Questo codice può essere implementato in modo molto semplice dai metodi che vi fanno riferimento. Ad esempio, poiché WriteLog è un metodo statico il codice può essere semplicemente Log.WriteLog(“This is my error message”, TraceSeverity.Medium); . In questo caso, nella categoria "SteveCategory" dell'area "Steve Area" del registro ULS viene creata una voce con il messaggio "This is my error message".
Questo è un post di blog localizzato. Consultate l'articolo originale: Tips for ULS Logging