Skip Navigation Links



Translate this page now :



»Programação
»Programação.NET
»Banco de Dados
»Webdesign
»Office
» Certificações Microsoft 4
»Treinamentos4
»Programação 4
»Webdesign«
»Office & User Tips«
»Grupos de UsuĆ”rios
»CĆ©lulas AcadĆŖmicas«
intcontpiada : 118
Viciado
Você já está cadastrado e participa do grupo de usuários de sua cidade ? Se não, comente o porque.
 
 
FaƧa um pequeno teste com 10 questƵes de VB
.:.
Teste seus conhecimentos em Visual Basic, SQL Server e ASP 3.0 com nossas provas on-line
.:.
Aprimore seus conhecimentos em programaĆ§Ć£o com nosso treinamento on-line de lĆ³gica de programaĆ§Ć£o
.:.
Veja nosso calendƔrio de treinamentos
Gostou da PƔgina?
Então

para um amigo!

Pesquisa personalizada
Pesquisar Dicas:

 






Helth e Monitoring com ASP.NET 2.0

Muitos podem erroneamente pensar que a publicação do site web é o término de um trabalho, mas na verdade é apenas o começo. Um site web precisa ser constantemente vigiado, monitorado, observando-se possíveis falhas, as atividades dos usuários, entre outros detalhes do dia-a-dia.

Para permitir que um site ASP.NET seja devidamente monitorado em run-time o ASP.NET traz um novo sistema de eventos já implantado junto aos webControls.

É simples : O framework possui várias classes de eventos. Essas classes de eventos já são disparadas pelos webControls disponíveis em suas atividades. Através do uso de Providers podemos configurar onde os eventos serão registrados.

Configurar onde os eventos serão registrados significa configurar como o administrador será avisado. Event Viewer, e-mails, as possibilidades são diversas.

Primeiramente, para vermos o que é possivel obter com esses recursos, vamos testar exemplos simples. Para fazer esses testes vamos precisar de uma aplicação. Uma aplicação simples com dataGrid, como a que demonstramos em http://www.bufaloinfo.com.br/artigos/artigo01012006.asp , mas com a adição dos recursos de segurança (login) que você pode ver em http://www.bufaloinfo.com.br/artigos/artigo01022006.asp

Primeiramente rode a aplicação, pura e simplesmente. Faça um login inválido. Após fechar a aplicação, abra o event viewer.

No event viewer, no item "Application", você encontrará um evento registrando o login inválido. Essa é a configuração default, o envio de auditorias de falha para o log de eventos, o webControl de login gera uma auditoria de falha, o resto é resultado da configuração.

Feito esse teste, experimente adicionar o seguinte no web.config :

<healthMonitoring>

<rules>

<clear />
<add name="All Events" eventName="All Events" provider="EventLogProvider"
profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" />

</rules>

</healthMonitoring>

O "clear" remove as configurações existentes, então adicionamos um mapeamento de "All Events" para o event log. Depois de rodar a aplicação e fazer os mesmos testes, você encontrará no event viewer eventos de start e autorização de URLs, mas nenhum evento de falha de login.

Como mais um teste, remova o "clear". Verá que a configuração de All Events se adiciona as já existentes e você novamente verá a falha de login no event viewer.

Configuração

Para entendermos melhor esta arquitetura, vamos analisar a forma como é feita a configuração dos providers e eventos. Essa configuração é feita dentro do arquivo web.config global, veja como são as tags :

<healthMonitoring>

<bufferModes />
<providers />
<profiles />
<rules />
<eventMappings />

</healthMonitoring>

Em "providers" configuramos os providers que desejaremos utilizar para registrar os webEvents. Existem os seguintes providers no .NET :

EventLogWebEventProvider Faz o registro de eventos no eventLog
SqlWebEventProvider Faz o registro de eventos no SQL Server
WmiWebEventProvider Faz a publicação de webEvents via WMI
SimpleMailWebEventProvider Faz o envio dos eventos por e-mail
TemplatedMailWebEventProvider Também faz o envio dos eventos por e-mail, mas permite a criação de um template para os e-mails que serão enviados.

 

Cada provider fica ligado a um bufferMode. Podem haver inúmeros bufferModes configurados, mas cada provider vai estar ligado a apenas um. O bufferMode, conforme o nome diz, é um controle de buffer para os webEvents. Isso porque o registro demasiado de eventos pode gerar perda de performance, então podemos fazer com que os eventos fiquem guardados em um buffer, para serem depois registrados sem prejudicar a performance da aplicação. Eventos urgentes, graves, porém, em geral precisam que seu alerta seja dado imediatamente, enquanto que eventos menos graves não. Por isso a possibilidade de configurar diversos bufferModes.

Os eventos são basicamente classes do framework. Mas para efeito de configuração precisamos nomes fáceis e inteligíveis que simplifiquem a configuração de onde os eventos devem ser registrados. Para isso temos então o eventMappings.

O eventMappings cria vários nomes para conjuntos de eventos já existentes, de forma que podemos utilizar esses nomes na determinação de onde os eventos serão gravados. O mapeamento, quer dizer, a identificação de um nome, pode ser feita pela classe do evento e pelo código do evento (faixa de código), mas as configurações padrões do web.config apenas fazem o mapeamento por classe.

Com a configuração padrão, temos os seguintes eventMappings disponíveis :

All Events Todos os eventos
Heartbeats Utilizado para gerar um evento periódico, como um timer
Application Lifetime Events Eventos representando a vida da aplicação, como o start e o shutdown da aplicação
Request Processing Events Eventos de requisição de páginas
All Errors Todos os erros
Infrastructure Errors Erros de sistema, como configuração errada ou erros de programação - erros disparados pelo ASP.NET
Request Processing Errors Eventos relacionados com a requsição de páginas web
All Audits Apenas eventos de auditoria
Failure Audits Auditorias de falhas
Success Audits Auditorias de sucesso

 

Importante : Esses eventMappings mapeiam classes já existentes na class library do framework, funcionando portanto para os eventos já existentes e disparados internamente pelos webControls existentes. Porém existem diferenças na forma como os webControls disparam seus eventos e a forma que nos é disponibilizada para fazer o mesmo, por isso esses eventMappings não funcionarão para nossos eventos personalizados, precisaremos criar nossos próprios mappings.

Temos então as rules. As rules interligam os eventMappings aos providers. Basicamente são regras determinando quais providers vão tratar quais eventMappings. São a configuração final no sistema de eventos.

As rules ficam também ligadas aos profiles. Os profiles são regras para log dos eventos, falarei um pouco mais sobre estas regras adiante.

Veja como é a configuração que encontra-se no web.config global, observe estas características que citamos e a relação existente entre as configurações.

Providers

Na tab providers fazemos a especificação dos providers que irão determinar a forma de gravação dos eventos. Temos os típicos name e Type das chaves de configuração. Além disso temos também as seguintes configurações :

buffer True ou false, se vai ou não ser utilizada uma especificação de buffer.
bufferMode Indicação de qual bufferMode será utilizado caso buffer seja true
maxEventDetailsLength Tamanho máximo da mensagem de detalhes do evento.

 

Em casos complexos, essas configurações nos permitem inserir várias vezes providers do mesmo tipo. Os providers são identificados pelo nome, então podemos inserir o mesmo tipo de provider mais de uma vez. Para que ? Para podermos vincular um provider a mais de um bufferMode e criar regras que desviem alguns erros para um tipo de bufferMode e outros para outro tipo.

BufferModes

maxBufferSize : O número máximo de eventos que podem ser guardados antes de serem gravados em seu destino final (essa gravação final é chamada de "flush")

maxFlushSize : Número máximo de registros gravados em cada gravação (flush).

urgentFlushThreshold : Número mínimo de registros no buffer antes de uma gravação ser realizada.

regularFlushInterval : Intervalo entre as gravações (flush).

urgentFlushInterval : Tempo mínimo de intervalo entre as gravações (flush). Se o buffer for preenchido antes deste tempo, a operação de flush deverá esperar no mínimo este tempo.

maxBufferThreads : Número máximo de threads utilizadas na operação de flush.

Observe a configuração default que faz com que não exista tempo máximo, o flush acontecerá quando o buffer estiver cheio.

eventMappings

Os mapeamentos de eventos podem ser feitos pela classe do evento, pelo código do evento (ou faixa de códigos) ou ambos.

Os atributos startEventCode e endEventCode determinam a faixa de códigos de evento que estão sendo mapeados. Observe que a configuração default faz o mapeamento pelas classes, tomando o cuidado de deixar a faixa de códigos totalmente aberta, pegando todos os códigos de evento disparados com essa classe.

Conforme você deve ter observado nos nomes de eventos, um pouco mais acima, existe um aparente nível hierárquico entre os eventos. Por exemplo, existe um All Audits mas também existe um Sucess Audits e um Failure Audits. Além de tudo isso temos também um All Events.

Porém nos webControls internos existem formas diferenciadas de disparo dos eventos, utilizando métodos privados. Com isso a ação hierárquica dos eventMappings não tem um efeito completo nos eventos existentes. Por exemplo, "All Events" não afeta o evento de falha de login.

 

Rules

eventName Nome do evento para o qual esta regra se aplicará. Este nome será definido de acordo com os eventMappings
provider Nome do provider que será utilizado nesta regra
profile Nome do profile que será utilizado nesta regra
minInterval Valor de minInterval, substituindo o valor equivalente definido no profile
minInstances Valor de minInstances, substituindo o valor equivalente definido no profile
maxLimit Valor de maxLimit, substituindo o valor equivalente definido no profile

 

Observe que podemos definir um profile ou definir os 3 valores específicos, que estariam no profile. Outra alternativa seria ainda optar por um profile e substituir alguns de seus valores.

Profiles

Os eventos de um sistema podem ter diferentes características de disparo. Alguns eventos quando disparados isoladamente podem ser pouco significativos, enquanto que se forem repetidos, tornam-se críticos. Outros, por outro lado, estão fadados a uma repetição infinita quando ocorrerem, sendo a repetição pouco significativa.

Por exemplo, um evento de login inválido pode não ser importante, mas 10 eventos deste podem significar uma tentativa de invasão. Por outro lado um evento de falta de espaço em disco (apenas exemplo) apenas é significante em sua primeira execução, as repetição irão ocorrer até que seja liberado espaço em disco e não terão a mesma importância.

minInstances Número mínimo de ocorrências para um evento ser considerado e registrado.
maxLimit Limite máximo de registro das ocorrências de um evento.
minInterval Determinação de um intervalo mínimo para logar o mesmo evento novamente. Se o mesmo evento se repetir antes de passado este intervalo, não será logado.

 

Disparando um evento

As classes de eventos disponibilizadas para nós no framework (e mapeadas no eventMappings padrão) são classes abstratas, portanto não podemos dispara-las diretamente. Para disparar um evento precisamos criar um evento personalizado, escolhendo a classe mais adequada para servir de base para nosso novo evento.

Vejam os métodos que devemos sobrescrever em nosso evento personalizado :

Construtores : os construtores das classes base são protected, então somos obrigados a criar os nossos. A classe base nos oferece 2 construtores protected - um recebendo o código do evento e outro que além do código nos permite acrescentar um segundo código, o código detalhado do evento. Podemos criar apenas um deles para nosso evento personalizado ou os dois. Fazer algo totalmente diferente, apesar de possível, seria incomum.

FormatCustomEventDetails : Precisamos fazer um overrides neste método para acrescentarmos as informações personalizadas de nossa aplicação que desejamos que o evento exiba, formatando-as adequadamente na mensagem do evento.

Raise (opcional) : Fazer o override deste método é totalmente opcional. Só deveremos realiza-lo se desejarmos incluir alguma informação personalizada no exato momento do disparo do evento, tal como data e hora de disparo.

 

   42 Public Class MySuccessAudit

   43     Inherits System.Web.Management.WebSuccessAuditEvent

   44     Private customCreatedMsg, customRaisedMsg As String

   45 

   46 

   47 

   48     ' Invoked in case of events identified only by their event code.

   49     Public Sub New(ByVal msg As String, _

   50     ByVal eventSource As Object, ByVal eventCode As Integer)

   51 

   52 

   53         MyBase.New(msg, eventSource, eventCode)

   54         ' Perform custom initialization.

   55 

   56         customCreatedMsg = String.Format("Event created at: {0}", _

   57         DateTime.Now.TimeOfDay.ToString())

   58 

   59     End Sub 'New

   60 

   61 

   62     ' Invoked in case of events identified by their event code.and

   63     ' event detailed code.

   64     Public Sub New(ByVal msg As String, ByVal eventSource As Object, _

   65     ByVal eventCode As Integer, ByVal detailedCode As Integer)

   66 

   67 

   68         MyBase.New(msg, eventSource, eventCode, detailedCode)

   69         ' Perform custom initialization.

   70 

   71         customCreatedMsg = String.Format("Event created at: {0}", _

   72         DateTime.Now.TimeOfDay.ToString())

   73 

   74     End Sub 'New

   75 

   76 

   77     'Formats Web request event information.

   78     'This method is invoked indirectly by the provider using one of the

   79     'overloaded ToString methods.

   80     Public Overrides Sub FormatCustomEventDetails(ByVal formatter _

   81     As WebEventFormatter)

   82         MyBase.FormatCustomEventDetails(formatter)

   83 

   84         ' Add custom data.

   85         formatter.AppendLine("")

   86 

   87         formatter.IndentationLevel += 1

   88         formatter.AppendLine("**SampleWebSuccessAuditEvent Start **")

   89         formatter.AppendLine(String.Format("Request path: {0}", _

   90         RequestInformation.RequestPath))

   91         formatter.AppendLine(String.Format("Request Url: {0}", _

   92         RequestInformation.RequestUrl))

   93 

   94         ' Display custom event timing.

   95         formatter.AppendLine(customCreatedMsg)

   96 

   97         formatter.AppendLine("** SampleWebSuccessAuditEvent End **")

   98 

   99         formatter.IndentationLevel -= 1

  100 

  101     End Sub 'FormatCustomEventDetails

  102 End Class 'SampleWebSuccessAuditEvent

 

Agora que criamos nosso evento personalizado podemos dispara-lo quando ocorrer algum evento importante na aplicação. Vejam um exemplo :

 

   40     Protected Sub GridView1_RowUpdated(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewUpdatedEventArgs) Handles GridView1.RowUpdated

   41 

   42 

   43         Dim ae As MySuccessAudit

   44         Dim sb As New StringBuilder

   45 

   46         For Each id As DictionaryEntry In e.NewValues

   47             sb.Append(id.Key & " : " & id.Value.ToString & vbCrLf)

   48         Next

   49 

   50         ae = New MySuccessAudit(sb.ToString, "MinhaWebApp", WebEventCodes.WebExtendedBase + 1 )

   51         WebBaseEvent.Raise(ae)

   52 

   53     End Sub

Neste exemplo utilizei um stringBuilder para fazer a montagem dos dados a serem exibidos na mensagem do evento. Após isso basta fazer a criação do evento, com a mensagem, a origem e o código do evento como parâmetros.

Oberve que no lugar do código utilize WebEventCodes.WebExtendedBase + 1. Isso porque o ASP.NET reserva uma faixa de códigos para ele próprio, é necessário que o nosso evento tenha um código superior a constante WebExtendedBase.

Por fim, utilizei o método Raise, estático na classe WebBaseEvent, para realizar o disparo do evento.

Configurando os providers de E-mail

Temos dois providers para envio dos eventos por e-mail, SimpleMailProvider e TemplatedMailProvider. Para utiliza-los precisamos configurar o envio de e-mail nestes providers.

A configuração destes providers esta ligada a configuração do envio de e-mails, como um todo, pelo ASP.NET. Basta adicionarmos as seguintes tags no Web.Config :

<system.net>

<mailSettings>

<smtp deliveryMethod="Network">
<network from="admin@bufaloinfo.com.br" host="servidorSMTP"
defaultCredentials="false"
userName="usuario"
password="senha"
/>
</smtp>

</mailSettings>

</system.net>

Observe que nesta configuração informamos o servidor de SMTP que será utilizado para o envio de e-mail bem como o nome de usuário e senha para autenticação no servidor para os casos em que o servidor exige autenticação. Observe ainda que as tags acima ficam foram do System.Web

Feita esta configuração, vamos então configurar o provider. Veja como fica :

<providers>
<add name="exampleMailWebEventProvider" type="System.Web.Management.SimpleMailWebEventProvider" to="someone@contoso.com" from="someone@contoso.com" buffer="false" subjectPrefix="WebEvent has fired" />
</providers>

Nesta configuração acima especificamos o e-mail de origem e destino e o assunto das mensagens. Com isso basta alterar as rules para que o evento chegue por e-mail :

<add name="EnvioEmail" eventName="Successo" provider="exampleMailWebEventProvider"
profile="Default" minInstances="1" maxLimit="Infinite" minInterval="00:01:00" />

O SimpleMailWebEventProvider, utilizado no exemplo acima, tem uma formatação fixa para os emails enviados. Caso desejemos personalizar a formatação dos emails enviados devemos utilizar o TemplatedMailWebEventProvider. Veja como fica a configuração dele :

<add
name="exampleTemplatedMailWebEventProvider"
type="System.Web.Management.TemplatedMailWebEventProvider"
template="mailtemplate.aspx"
detailedTemplateErrors="true"
to="dennes@bufaloinfo.com.br"
from="contato@bufaloinfo.com.br"
buffer="false"
maxMessagesPerNotification="1"
maxEventsPerMessage="1"
/>

Observe o atributo template, que indica uma página .ASPX que será utilizada como template para o e-mail. A página mailtemplate.ASPX, neste exemplo, é processada e o HTML gerado por esta página é utilizado como corpo do e-mail.

Para a criação do template vamos utilizar uma instância da classe MailEventNotificationInfo, essa classe nos dará as informações sobre o evento que está ocorrendo. Para obter essa instância utilizamos TemplatedMailWebEventProvider.CurrentNotification

Vamos montar o HTML da página mailTemplate.aspx

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="mailTemplate.aspx.vb" Inherits="mailTemplate" %>
<%@ Import Namespace="System.Text.RegularExpressions" %>           
<asp:Label runat="server" id="Label0" /><p />
           <asp:Label runat="server" id="Label1" /><p />
           <asp:Label runat="server" id="Label2" /><p />
           <asp:Label runat="server" id="Label3" /><p />
           <asp:Label runat="server" id="Label4" /><p />
           <asp:Label runat="server" id="Label5" /><p />
           <asp:Label runat="server" id="Label6" /><p />
           <asp:Label runat="server" id="Label7" /><p />
           <asp:Label runat="server" id="Label8" /><p />
           <asp:Label runat="server" id="Label9" /><p />
<asp:DataList id="EventList" runat="server">
 <ItemTemplate>
   Event Received <br />
   Sequence:
      <%#DataBinder.Eval(Container.DataItem, "EventSequence").ToString().Replace(Regex.Unescape("\n"), "<br>")%>
   <br>
   Details: <%#Container.DataItem.ToString().Replace(Regex.Unescape("\n"), "<br>")%><br />
 </ItemTemplate>
 </asp:DataList>
           

Vamos programar o Load da página para realizar o preenchimento deste e-mail com dados :

 

   39         Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

   40 

   41 

   42         Dim info As MailEventNotificationInfo = TemplatedMailWebEventProvider.CurrentNotification

   43 

   44 

   45         Label0.Text = "EventsDiscardedByBuffer: " & info.EventsDiscardedByBuffer & "<br>"

   46         Label1.Text = "EventsInBuffer: " & info.EventsInBuffer & "<br>"

   47         Label2.Text = "NotificationSequence: " & info.NotificationSequence & "<br>"

   48         Label3.Text = "NotificationType: " & info.NotificationType & "<br>"

   49         Label4.Text = "EventsInNotification: " & info.EventsInNotification & "<br>"

   50         Label5.Text = "EventsRemaining: " & info.EventsRemaining & "<br>"

   51         Label6.Text = "MessagesInNotification: " & info.MessagesInNotification & "<br>"

   52 

   53 

   54         Label7.Text = "eventsDiscardedDueToMessageLimit: " & info.EventsDiscardedDueToMessageLimit & "<br>"

   55 

   56 

   57         Label8.Text = "messageSequence: " & info.MessageSequence & "<br>"

   58         Label9.Text = "LastNotificationUtc: " & info.LastNotificationUtc.ToLocalTime().ToString() & "<br>"

   59 

   60 

   61         EventList.DataSource = info.Events

   62         EventList.DataBind()

   63     End Sub

Conclusão

O sistema de Helth & Monitoring no ASP.NET 2.0 nos fornece toda a infraestrutura para a criação de nosso próprio conjunto de eventos, além de fornecer alguns eventos já pré-definidos.

 

Dennes Torres
MCAD,MCSD,MCSE,MCDBA




Envie seus comentįrios sobre este artigo

Nome :

E-mail :

Comentários :


Avise-me quando houverem novos comentįrios nesta pįgina

Veja abaixo os comentários já enviados :

Nome : Papaywp E-Mail : Papaywc@mail.com
Thank you.
Nome : Papayuw E-Mail : Papayrm@mail.com
Thank you!
Nome : Papaypi E-Mail : Papaybr@mail.com
Thank you!
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
-1'
Nome : -1' E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : -1'
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : 1 E-Mail : 1
1
Nome : DgBgIJnFv E-Mail : mehvr9bk@outlook.com
You know what the good thing is about getting older is we can do all of that and not give a shit! I would have worried about saying I loved certain things when I was younger in case it wan#9s3&;t cool, yes I was shallow ;o) But now I drink cocktails, whilst watching Murder She Wrote, I don&#39;t give a damn and I love you cos you don&#39;t either!!

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
Conheça mais sobre o nosso site :

::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



Quer saber mais?
Faça um curso na Búfalo Informática, Treinamento e Consultoria e
Prepare-se para o Mercado!
Veja o que a Búfalo tem para você.

ļæ½ BĆŗfalo InformĆ”tica, Treinamento e Consultoria - Rua Ɓlvaro Alvim, 37 Sala 920 - CinelĆ¢ndia - Rio de Janeiro / RJ
Tel.: (21)2262-1368 (21) 9240-5134 (21) 9240-7281 e-Mail:
contato@bufaloinfo.com.br