Neste post vou explicar como usar a API de Log para mostrar os logs de execução da aplicação e também como usar o componente TraceTarget, que é muito útil para poder recuperar as informações das chamadas para o servidor, facilitando a resolução de problemas.
No Flex temos duas opções para recuperar informações ou logs de execução de uma aplicação. Uma primeira maneira e a mais utilizada, é usar a função global trace(”) para mostrar informações no console do FlashBuilder. Essa abordagem sempre requer que a aplicação esteja sendo executada em modo de debug, o que exige a instalação de um FlashPlayer versão de debug. Lógico que para o ambiente de desenvolvimento isso não é um problema, já que a instalação do FlashBuilder já inclui a versão correta do FlashPlayer versão debug. Mais e quando a aplicação está em produção, ou seja, quando não contamos com a versão de debug do FlashPlayer? Ai que entra a segunda opção.Na segunda opção vamos usar a API de Logging do Flex, que vai nos permitir delegar para uma classe a função de logar informações, seja usando o trace(”), primeira abordagem, ou até mesmo customizando a forma de apresentação. Esta abordagem também nos permite controlar o que é exibido, utilizado categorias e nível de log.
A API de Logging do Flex é muito simples de ser usada. Toda vez que queremos usa-la, estaremos envolvendo duas partes:
Para ficar mais fácil de entender como usar a API, vamos imaginar que queremos logar quando a aplicação é pré-inicializado, inicializado e criado.Inicialmente iremos usar a função global trace(”) e depois usar as classes de Log.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" preinitialize="application_preinitializeHandler(event)" initialize="application_initializeHandler(event)" creationComplete="application_creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protected function application_preinitializeHandler(event:FlexEvent):void { trace('A Aplicação foi pré inicializada'); } protected function application_initializeHandler(event:FlexEvent):void { trace('A Aplicação foi inicializada'); } protected function application_creationCompleteHandler(event:FlexEvent):void { trace('A Aplicação foi criada'); } ]]> </fx:Script> </s:Application> |
Debugando a aplicação teremos no Console:
1 2 3 | A Aplicação foi pré inicializada A Aplicação foi inicializada A Aplicação foi criada |
Agora vamos ver como ficaria se usarmos a API:
1 | private var log:ILogger = Log.getLogger("br.com.dclick.LogginExample"); |
1 2 3 4 5 6 7 8 9 10 11 | { log.info('A Aplicação foi pré inicializada'); } protected function application_initializeHandler(event:FlexEvent):void { log.warn('A Aplicação foi inicializada'); } protected function application_creationCompleteHandler(event:FlexEvent):void { log.log(LogEventLevel.INFO, 'A Aplicação foi criada'); } |
Perceba a utilização dos métodos info(), warn() e log() para registrar as informações. É possível usar tokens no log para serem trocados
por informações. Todos os tokens devem ser representados por {} como por exemplo, {0}, {1} e etc…
1 2 3 | { log.info('A Aplicação foi pré inicializada em: {0}', [new Date().toDateString()]); } |
Se debugarmos a aplicação após a implementação, podemos ver que nada é apresentado no console. Isso acontece por que ainda não informamos qual será o Log Target.
Vale lembrar que só é necessário declara-lo uma vez só na aplicação inteira. Ainda podemos customizar este target como por exemplo definir quais os levels que quero mostrar e se quero apresentar informações adicionais. Antes de mais nada, se debugarmos a aplicação teremos:
1 2 3 | A Aplicação foi pré inicializada em: Sat Mar 5 2011 A Aplicação foi inicializada A Aplicação foi criada |
1 | <s:TraceTarget includeCategory="true" includeDate="true" includeLevel="true" includeTime="true" level="{LogEventLevel.INFO}" /> |
Resultando em:
1 2 3 | 3/5/2011 21:27:41.840 [INFO] br.com.dclick.LogginExample A Aplicação foi pré inicializada em: Sat Mar 5 2011 3/5/2011 21:27:41.870 [WARN] br.com.dclick.LogginExample A Aplicação foi inicializada 3/5/2011 21:27:42.013 [INFO] br.com.dclick.LogginExample A Aplicação foi criada |
Se prestarmos atenção no último exemplo, definimos que o level seria info, mais então porque o level warn foi logado? A API nos permite selecionar os níveis ALL –> DEBUG –> INFO –> WARN –> ERROR –> FATAL. Então se selecionarmos o nível INFO, tudo o que for INFO e menos abrangente será logado. Se selecionarmos o nível ERROR, somente logs com o nível ERROR e FATAL serão apresentados.
Para exemplificar a utilização das categorias, vamos criar um componente adicional:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | <?xml version="1.0" encoding="utf-8"?> <s:Group xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" preinitialize="group1_preinitializeHandler(event)" initialize="group1_initializeHandler(event)" creationComplete="group1_creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; import mx.logging.ILogger; import mx.logging.Log; private var log:ILogger = Log.getLogger("br.com.dclick.components.MyComponent"); protected function group1_preinitializeHandler(event:FlexEvent):void { log.info("MyComponent preinitialized"); } protected function group1_initializeHandler(event:FlexEvent):void { log.info("MyComponent initialized"); } protected function group1_creationCompleteHandler(event:FlexEvent):void { log.info("MyComponent created"); } ]]> </fx:Script> <fx:Declarations> <!-- Place non-visual elements (e.g., services, value objects) here --> </fx:Declarations> </s:Group> |
Vamos declarar o componente e debugar a aplicação.
1 | <components:MyComponent /> |
O resultado é:
1 2 3 4 5 6 | 3/5/2011 21:38:56.878 [INFO] br.com.dclick.LogginExample A Aplicação foi pré inicializada em: Sat Mar 5 2011 3/5/2011 21:38:56.909 [INFO] br.com.dclick.components.MyComponent MyComponent preinitialized 3/5/2011 21:38:56.909 [INFO] br.com.dclick.components.MyComponent MyComponent initialized 3/5/2011 21:38:56.910 [WARN] br.com.dclick.LogginExample A Aplicação foi inicializada 3/5/2011 21:38:57.057 [INFO] br.com.dclick.components.MyComponent MyComponent created 3/5/2011 21:38:57.057 [INFO] br.com.dclick.LogginExample A Aplicação foi criada |
Imagine que só queremos apresentar os logs com a categoria br.com.dclick.components.*
1 | level="{LogEventLevel.INFO}" filters="['br.com.dclick.components.*']"/>; |
O Resultado é:
1 2 3 | 3/5/2011 21:59:44.240 [INFO] br.com.dclick.components.MyComponent MyComponent preinitialized 3/5/2011 21:59:44.241 [INFO] br.com.dclick.components.MyComponent MyComponent initialized 3/5/2011 21:59:44.387 [INFO] br.com.dclick.components.MyComponent MyComponent created |
Poderia querer imprimir os logs com a categoria br.com.dclick.components.MyComponent e br.com.dclick.LogginExample:
1 | level="{LogEventLevel.INFO}" filters="['br.com.dclick.components.MyComponent', 'br.com.dclick.LogginExample']"/>; |
O Resultado é:
1 2 3 4 5 6 | 3/5/2011 22:02:40.929 [INFO] br.com.dclick.LogginExample A Aplicação foi pré inicializada em: Sat Mar 5 2011 3/5/2011 22:02:40.960 [INFO] br.com.dclick.components.MyComponent MyComponent preinitialized 3/5/2011 22:02:40.960 [INFO] br.com.dclick.components.MyComponent MyComponent initialized 3/5/2011 22:02:40.961 [WARN] br.com.dclick.LogginExample A Aplicação foi inicializada 3/5/2011 22:02:41.105 [INFO] br.com.dclick.components.MyComponent MyComponent created 3/5/2011 22:02:41.106 [INFO] br.com.dclick.LogginExample A Aplicação foi criada |
Moral da história, para poder filtrar os logs pela categoria, usamos a propriedade filter, que recebe uma lista de strings com as categorias permitidas. A API também permite a utilização do curinga *, e por padrão o filtro é igual a *, ou seja, imprime tudo.
A última coisa que gostaria de mostrar é como usuar o TraceTarget para logar informações sobre as chamadas remotas. Irei utilizar como exemplo um HttpService consumindo o rss do Globo Esporte.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | <?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" creationComplete="application_creationCompleteHandler(event)"> <fx:Script> <![CDATA[ import mx.events.FlexEvent; protected function application_creationCompleteHandler(event:FlexEvent):void { rss.send(); } ]]> </fx:Script> <fx:Declarations> <s:TraceTarget /> <s:HTTPService id="rss" url="http://globoesporte.globo.com/dynamo/rss2.xml" /> </fx:Declarations> </s:Application> |
No console podemos ver a chamada feita e o resultado da chamada.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | '136ECED5-AD86-47EB-E77F-88EE4AA0EA34' producer set destination to 'DefaultHTTP'. 'direct_http_channel' channel endpoint set to http: '136ECED5-AD86-47EB-E77F-88EE4AA0EA34' producer sending message 'E52C0A6D-882A-37F9-F4C9-88EE4B7DF0FC' 'direct_http_channel' channel sending message: (mx.messaging.messages::HTTPRequestMessage)#0 body = (Object)#1 clientId = (null) contentType = "application/x-www-form-urlencoded" destination = "DefaultHTTP" headers = (Object)#2 httpHeaders = (Object)#3 messageId = "E52C0A6D-882A-37F9-F4C9-88EE4B7DF0FC" method = "GET" recordHeaders = false timestamp = 0 timeToLive = 0 url = "http://globoesporte.globo.com/dynamo/rss2.xml" '136ECED5-AD86-47EB-E77F-88EE4AA0EA34' producer connected. '136ECED5-AD86-47EB-E77F-88EE4AA0EA34' producer acknowledge of 'E52C0A6D-882A-37F9-F4C9-88EE4B7DF0FC'. Decoding HTTPService response Processing HTTPService response message: (mx.messaging.messages::AcknowledgeMessage)#0 body = "<?xml version="1.0" encoding="utf-8"?> <rss>...</rss>" clientId = "DirectHTTPChannel0" correlationId = "E52C0A6D-882A-37F9-F4C9-88EE4B7DF0FC" destination = "" headers = (Object)#1 DSStatusCode = 200 messageId = "FDA3E270-BAD8-82AD-2770-88EE5BE5C3E8" timestamp = 0 timeToLive = 0 |
E isso é tudo o que você precisa para começar a utilizar a API, nos próximos posts irei ensinar como customizar a saída do log.
Nenhum comentário
Deixe Seu Comentário