Sugerencias para el registro de ULS parte 2

En la parte 1 de las sugerencias para el registro de ULS (http://blogs.msdn.com/b/sharepoint_sp/archive/2011/03/21/sugerencias-para-el-registro-de-uls.aspx) incluí código para agregar un área personalizada de registro de ULS y mostré cómo usarlo dentro del proyecto.  Después de trabajar un poco con él, me di cuenta de lo siguiente:

1.       Una parte del código no concordaba con el último SDK; básicamente, el SDK suponía que no se necesitaban algunas partes del código implementado y había algunas cosas que yo hacía de forma ligeramente diferente al ejemplo del SDK (que, por cierto, necesita actualizarse y trabajaré en ello en forma independiente).

2.       El registro se producía únicamente cuando establecía TraceSeverity en Medio; no existía un método eficaz para colocar en capas los diferentes niveles de seguimiento.

3.       Lo más molesto de todo es que al intentar invocar la clase personalizada que se requiere para el área personalizada, se producía un error cuando intentaba hacer algún registro durante una actividad POST.  Se desencadenaba un error muy común sobre la imposibilidad de actualizar un SPWeb durante una POST, a menos que estableciera la propiedad AllowUnsafeUpdates en true.  Ahora bien, establecerla en un SPWeb durante un evento de registro, solo para lograr que mi evento de registro funcionara, parecía una locura (por cierto, pido disculpas a todos los locos que andan por ahí).  Así que decidí que debía haber una manera mejor.

Por lo tanto, en esta entrada de blog, mejoraré el ejemplo anterior y le agregaré algunas cosas a medida que avancemos.  Esto es lo que se va a mostrar:

1.       Una clase mejorada para el área personalizada; en realidad es un poco más corta en esta versión.

2.       Integración con Configurar el registro de diagnóstico de la sección Supervisión de Administración central.  Esta integración proporcionará compatibilidad para configurar los niveles de seguimiento en el área y la categoría personalizadas.

3.       Información de registro; una forma muy sencilla para registrar y anular el registro de la clase de registro de ULS personalizada, de modo que se integre con Administración central y se pueda quitar de allí.

Para empezar, veamos la nueva versión optimizada de la clase.  Existen muchas similitudes entre esta y la versión que mostré en la primera entrada de blog, pero la que presento aquí es un poco más corta y sencilla.  Ahora su aspecto es el siguiente.

    [Guid("833B687D-0DD1-4F17-BF6A-B64FBC1AC6A8")]

    public class SteveDiagnosticService : SPDiagnosticsServiceBase

    {

 

        private const string LOG_AREA = "Steve Area";

 

 

        public enum LogCategories

        {

            SteveCategory

        }  

 

 

        public SteveDiagnosticService()

        {

        } 

 

 

        public SteveDiagnosticService(string name, SPFarm parent)

            : base(name, parent)

        {

        } 

 

 

        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()

        {

yield return new SPDiagnosticsArea(LOG_AREA, 0, 0, false,

new List<SPDiagnosticsCategory>()

{

new

SPDiagnosticsCategory(LogCategories.AzureConfig.ToString(),

                     TraceSeverity.Medium, EventSeverity.Information, 1,

                     Log.LOG_ID)

                     });

        }

    }

 

Los cambios importantes con respecto a la primera versión son los siguientes:

1.        Agregué el atributo Guid a la clase:

[Guid("833B687D-0DD1-4F17-BF6A-B64FBC1AC6A8")]

 

He agregado un atributo Guid a la clase, porque SharePoint lo necesita para identificar la clase de manera única en la base de datos de configuración.

2.       Cambié el constructor predeterminado:

        public SteveDiagnosticService()

        {

        } 

 

Ahora es solo un constructor estándar vacío.  Antes llamaba a la otra sobrecarga para el constructor, que toma un nombre para el servicio y un SPFarm.  Simplemente hay menos código, eso es todo. Es bueno lograr que funcione de esta manera.

3.       Eliminé la invalidación HasAdditionalUpdateAccess.  Nuevamente, me di cuenta de que en realidad no la usaba, por lo que para continuar con eso de que "menos es más", la quité.

 

4.       Acorté el método ProvideAreas de forma significativa; ahora coincide con el mismo patrón que se usa en el SDK:

 

yield return new SPDiagnosticsArea(LOG_AREA, 0, 0, false,

new List<SPDiagnosticsCategory>()

{

new

SPDiagnosticsCategory(LogCategories.AzureConfig.ToString(),

                     TraceSeverity.Medium, EventSeverity.Information, 1,

                     Log.LOG_ID)

                     });

Con eso se resuelve el problema nº 1 que indiqué anteriormente; ahora el código es un poco más eficaz.  Los otros problemas (falta de niveles de seguimiento, generación de una excepción cuando se registra durante una POST e integración con Administración central) se corrigieron esencialmente mejorando el código un poco más y mediante el registro.  Actualmente, el ejemplo del SDK es un poco débil en esta área, pero he podido lograr que haga lo que necesitamos.  Para simplificar la tarea, he creado una nueva característica para el ensamblado que contiene la clase personalizada de ULS descrita anteriormente.  Agregué un receptor de características, registré el ensamblado personalizado de ULS durante el evento FeatureInstalled y anulé su registro durante el evento FeatureUninstalling.  Esto fue una buena solución en mi caso, puesto que mi característica es de ámbito de la granja de servidores, de modo que se activa automáticamente cuando se agrega y se implementa la solución.  Resulta que el código para realizar y anular el registro es extremadamente simple; es el que se muestra a continuación:

public override void FeatureInstalled(SPFeatureReceiverProperties properties)

{

try

       {

SteveDiagnosticsService.Local.Update();

}

catch (Exception ex)

       {

throw new Exception("Error installing feature: " + ex.Message);

}

}

 

 

public override void FeatureUninstalling(SPFeatureReceiverProperties properties)

{

try

       {

SteveDiagnosticsService.Local.Delete();

}

catch (Exception ex)

{

throw new Exception("Error uninstalling feature: " + ex.Message);

}

}

 

El otro punto que hay que destacar aquí es que pude hacer referencia a "SteveDiagnosticService" porque: a) agregué una referencia al ensamblado con mi clase de registro personalizada en el proyecto donde empaqueté la característica y b) agregué una instrucción using a la clase de receptor de características para el ensamblado con mi clase de registro personalizada.

Al registrar la clase de registro de ULS personalizada, obtengo una gran cantidad de beneficios:

·         Ya no aparece ningún error acerca de los problemas de actualización de SPWeb al escribir en el registro de ULS durante una POST

·         El área de registro y la categoría personalizadas aparecen en Administración central, por lo que puedo entrar en Configurar el registro de diagnóstico y cambiar los niveles de seguimiento y evento.  Por ejemplo, cuando está en el nivel predeterminado de seguimiento, Medio, se escriben en el registro todos los ULS con TracingSeverity.Medium, pero no se escriben los que tienen TracingSeverity.Verbose.  Si quiero que las entradas con TracingSeverity.Verbose comiencen a aparecer en el registro, simplemente tengo que ir a Configurar el registro de diagnóstico y cambiar el nivel de seguimiento por Detallado.

En general, la solución es más sencilla y funcional.  Creo que es una de esas situaciones en las que todos ganan.

P.D.  Quiero registrar mi voto de protesta contra LaMarcus Aldridge de Portland Trailblazers.  El hecho de que no lo hayan llamado para formar parte del equipo de las estrellas de la Conferencia Oeste de la NBA es trágicamente estúpido.  Está bien, suficientes comentarios personales; sé que buscan información verdadera de Share-n-Dipity cuando entran aquí.  Espero que les resulte útil.

Esta entrada de blog es una traducción. Puede consultar el artículo original en Tips for ULS Logging Part 2