Instrumentação com SharePoint 2010

Instrumentação, de acordo com a Wikipédia, significa “a ciência que estuda, desenvolve e aplica instrumentos de medição e controle de processos”, ou seja, com base em informações geradas a partir de medições e controle desses processos, conseguimos saber o que está acontecendo com determinado objeto, seja ele uma usina hidroelétrica ou um programa de computador.

Neste post vamos falar um pouco sobre intrumentação no SharePoint 2010, como podemos controlar a execução de nossos processos para descobrir problemas de performance e o controle de erros. Os recursos abordados neste artigo serão uma introdução à developer dashboard e como gravar informações nela e o registro de erros no log do SharePoint e do Windows.

Developer Dashboard

A developer dashboard é um painel de acompanhamento da execução da página, nela aparecem informações importantes para descobrir problemas de performance ou erros. Por padrão a developer dashboard está desabilitada no SharePoint, para habitá-la é necessário executar um comando através de Power Shell do SharePoint 2010. A listagem 01 exibe o comando em detalhes.

$service = [Microsoft.SharePoint.Administration.SPWebService]::ContentService
$addsetting =$service.DeveloperDashboardSettings

$addsetting.DisplayLevel =

      [Microsoft.SharePoint.Administration.

          SPDeveloperDashboardLevel]::OnDemand

$addsetting.Update()

Listagem 01: Habilitando a developer dashboard

A developer dasboard pode ser utilizada em três modos:

  • On: é exibida em todas as páginas automaticamente;
  • OnDemand: não é exibida nas páginas mas o usuário pode ativá-la manualmente clicando no ícone que ficar perto do seu login, conforme mostra a imagem 01;
  • Off: desligada e nunca é exibida.

Imagem 01: Ativando/desativando a developer dashboard em modo OnDemand

Ao ativar a developer dashboard na página (na imagem 02 é possível observar a Developer Dashboard ativa, ela está visível na parte inferior da página), várias informações sobre o processamento da página e atividades relacionadas serão exibidas. Cada área consiste em um tipo de informação (ver imagem 02):

  1. Exibe o processo de renderização do ASP.NET, exibindo o tempo de execução e renderização de cada controle em milissegundos (ms). É aqui que problemas de performance de controles/métodos serão avaliados individualmente;
  2. Exibe o tempo total de processamento da página, que consiste na soma de todos os tempos dos outros recursos. Exibe o usuário atual e nível check-out da página;
  3. Exibe os erros que aconteceram durante a execução da página;
  4. Exibe as consultas feitas no banco de dados com o respectivo tempo de duração;
  5. Exibe o de processamento das web parts, mostrando o tempo de execução (em milissegundos) dos eventos por web part.

Imagem 02: Developer dashboard

Com base nessas informações o desenvolvedor irá descobrir, por exemplo, se a sua web part está lenta, se de repente o problema de lentidao é no banco e as consultas estão demorando demais, e por aí adiante.

Registrando Eventos na Developer Dashboard

O conteúdo exibido na developer dashboard é o conteúdo padrão do SharePoint, os controles que o próprio SharePoint utiliza. Mas como desenvolvedor apenas isso acaba não resolvendo o meu problema, o que fazer então?

Podemos usar a facilidade de registrar na developer dashboard os eventos, e assim exibir no painel as ações e tempos de execução destes eventos. Dessa forma conseguimos ter um rastreamento melhor da execução de nossos artefatos.

Para fazer o registro das informações na developer dashboard devemos utilizar a classe SPMonitoredScope dentro de um using. Assim, tudo o que estiver dentro do escopo do using será computado como uma ação e o tempo total será registrado. No exemplo da listagem 02, estamos abrindo o using para criar o objeto SPMonitoredScope e colocando um sleep de 1 segundo. Dessa forma a developer dashboard irá informar que o tempo de execução do MeuTexto foi de 1 segundo (aproximadamente).

using (new SPMonitoredScope("MeuTexto"))
{
System.Threading.Thread.Sleep(1000);
}

Listagem 02: Exemplo de uso da classe SPMonitoredScope

Para melhorar a exibição e controle das informações, podemos utilizar os registros na developer dashboard de forma aninhada, ou seja, uns dentro de outros. A listagem 03 mostra em detalhes. Dessa forma o tempo de execução de MeuTexto passa para 2 segundos e o tempo de DentroMeuTexto é de 1 segundo. Tudo o que estiver dentro do using será considerado tempo de execução para o escope criado e para casa using interno é feito o mesmo controle, de forma aninhada.

using (new SPMonitoredScope("MeuTexto"))
{
System.Threading.Thread.Sleep(1000);

    using (new SPMonitoredScope("DentroMeuTexto"))
{
System.Threading.Thread.Sleep(1000);
}
}

Listagem 03: Exemplo de uso da classe SPMonitoredScope de forma aninhada

O próximo exemplo temos uma amostra de como instrumentar as classes e assim controlar a performance de execução dos métodos usando ainda o SPMonitoredScope. A listagem 04 mostra a criação de uma classe chamada Pessoa que possui alguns métodos que estão registrando o tempo de execução, depois a listagem 05 mostra como chamar essa classe e possui um outro registro do tempo de exeução, só que em nível macro de todas as chamadas dos métodos da classe pessoa. O resultado disso poder ser visto na imagem 03.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Utilities;

namespace WebPartInstrumentada
{
public class Pessoa
{
public List<Pessoa> ObterTodasPessoas()
{
using (new SPMonitoredScope("ObterTodasPessoas"))
{
System.Threading.Thread.Sleep(1000);
}

            return null;
}

        public Pessoa ObterPessoaPeloID(int id)
{
using (new SPMonitoredScope("ObterPessoaPeloID"))
{
System.Threading.Thread.Sleep(100);
}

            return null;
}

        public Pessoa ObterPessoaPeloNome(string nome)
{
try
{
throw new Exception("Erro ao obter pessoa pelo nome, contate o administrador do sistema");
}
catch (Exception ex)
{
// Registra o erro no log do SharePoint
TratamentoErro.RegistrarErroLogSharePoint(ex);
// Registra o erro no log do Windows
TratamentoErro.RegistrarErroEventViewer(ex);
}

            return null;
}
}
}

Listagem 04: Classe pessoa

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint.Utilities;

namespace WebPartInstrumentada.WebPartInstrumentada
{
public partial class WebPartInstrumentadaUserControl : UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
using (new SPMonitoredScope("Processando pessoas"))
{
Pessoa pessoa = new Pessoa();

                pessoa.ObterPessoaPeloID(1);

                pessoa.ObterTodasPessoas();

                pessoa.ObterPessoaPeloNome("Fabian");
}
}
}
}

Listagem 05: User Control

Da mesma forma que usamos a developer dashboard para exibir os nosso eventos customizados, também podemos usá-la para exibir erros tratados nesse processo. O próximo capítulo fala de como tratar erros e registrá-los no log do SharePoint ou no log do Windows. A imagem 03 mostra que os erros customizados para aparecer nos logs do Sharepoint e do Windows, também são mostrado na developer dashboard, na seção “Asserts and Critival Events”.

Imagem 03: Developer dashboard exibindo o tempo de execução da rotina de processamento de pessoas

Registrando eventos no log do SharePoint e log do Windows

Além das informações de performance, podermos gravar informações de erro ou avisos nos logs do SharePoint ou do Windows, para isso utilizamos a classe do SharePoint chamada SPDiagnosticsService, que é responsável por gravar os registros no log do SharePoint ou do Windows.

A listagem 06 mostra a implementação de uma classe de tratamento de erro, nesta classe temos um método para gravar no log do SharePoint e outro para gravar no log do Windows.  No caso do log do SharePoint, conforme a severidade informada para o registro, ele poderá ser exibido no log do SharePoint ou não. Isso depende da configuração feita na Administração Central relacionada à severiade do log de diagnóstico do SharePoint. Seria interessante personalizar o método RegistrarErroLogSharePoint para trabalhar com mais parâmetros, principalmente parâmetros que fossem relativos a severidade. Geralmente trabalhamos com mais de um tipo de informação de instrumentação, pois nem tudo é erro. Durante a execução podemos ter informações, avisos, erros, entre outros, e dessa forma conseguimos configurar o SharePoint para só gravar erros, por exemplo.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;

namespace WebPartInstrumentada
{
public static class TratamentoErro
{
/// <summary>
/// Método que registra os erros no log do SharePoint (pasta C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\LOGS)
/// </summary>
/// <param name="ex"></param>
public static void RegistrarErroLogSharePoint(Exception ex)
{
SPDiagnosticsService diagnostics = SPDiagnosticsService.Local;
diagnostics.WriteTrace(1409,
new SPDiagnosticsCategory("ErroCustomizado",
TraceSeverity.Monitorable,
EventSeverity.Error),
TraceSeverity.Monitorable,
"Ocorreu um erro: {0}",
new object[] { ex });
}

        /// <summary>
/// Método que registra os erros no log do Windows (Visualizador de Eventos)
/// </summary>
/// <param name="ex"></param>
public static void RegistrarErroEventViewer(Exception ex)
{
SPDiagnosticsService diagnostics = SPDiagnosticsService.Local;
diagnostics.WriteEvent(1408,
new SPDiagnosticsCategory("ErroCustomizado",
TraceSeverity.Monitorable,
EventSeverity.Warning),
EventSeverity.Error,
"Ocorreu um erro: {0}",
new object[] { ex });
}
}
}

Listagem 06: Classe de tratamento de erro

A listagem 07 mostra a implementação do método ObterPessoaPeloNome da classe pessoa (já feito anteriormente na listagem 04). Veja que no tratamento de exceção o erro está sendo gravado no log do Sharepoint e no log do Windows.

public Pessoa ObterPessoaPeloNome(string nome)
{
try
{
throw new Exception("Erro ao obter pessoa pelo nome, contate o administrador do sistema");
}
catch (Exception ex)
{
// Registra o erro no log do SharePoint
TratamentoErro.RegistrarErroLogSharePoint(ex);
// Registra o erro no log do Windows
TratamentoErro.RegistrarErroEventViewer(ex);
}

    return null;
}

Listagem 07: Utilização do tratamento de erro gravando no log do SharePoint e Windows

Agora basta conferir o resultado do tratamento de erro e execução do método ObterPessoaPeloNome, que pode ser visto no log do SharePoint, conforme a imagem 04, e no log de eventos do Windows, conforme imagem 05.

Imagem 04: Evento gravado no log do SharePoint

Imagem 05: Evento gravado no log do Windows

Referências