SlideShare uma empresa Scribd logo
E exceções !
  Autor: Pedro H. F. S. Diniz
  Grupo de GIS, Tecgraf
Sobre esta apresentação

Logs
  ●    O que é e porque é importante
  ●    Níveis de log
  ●    Appenders
  ●    Onde e quando devemos logar
  ●    Estudo de caso
  ●    Ferramentas que usamos hoje?
  ●    Tem coisa melhor?
  ●    Log assíncrono?
  ●    Boas práticas sobre o nosso código
Sobre esta apresentação

Exceção
●   O que é?
●   Tipos de exceção
●   Classificação
●   Quando lançar?
●   Quando tratar?
●   Boas práticas
●   Fique Atento!
O que é

●   É a história de vida do sistema

●   É uma instrução do código que grava informações de execução em algum
    lugar (email, arquivo, jms, banco de dados, etc..)

●   É a melhor maneira de se identificar um problema em produção

●   É uma ferramenta para realizar auditoria no sistema

●   É a ferramenta mais eficaz para que o cliente consiga rodar a manter a
    aplicação sem a intervenção dos desenvolvedores
Porque é importante

Pense que sua aplicação agora está fora do ambiente de desenvolvimento -
não está mais rodando na sua ide favorita e muito menos disponível para
debug.
É nessa hora que você irá percebeber a importância dos logs. Depois de ler
inúmeras linhas de log tentando identificar o que há de errado na aplicação
você vai entender que não é uma tarefa trivial.
Daí você se pergunta: com toda a minha experiência e conhecimento, é isso o
que eu estou destinado a fazer? Encontrar uma agulha em um palheiro de
logs?
Ou no nosso caso, delegando para o cliente (como na petrobras por exemplo),
que possui uma equipe de suporte e manutenção que igualmente nos
amaldiçoa pela gratificante e entediante tarefa!
Ou pior ainda, ter que levar até o cliente os arquitetos do software e fazer eles
se involverem, enquanto eles pensam a cada minuto como é um erro gastar o
seu tempo e habilidade com isso.
Níveis de log

Em geral são:

                - Trace


                - Debug


                - Info


                - Warning


                - Error


                -Fatal
Níveis de log

Trace
Traça toda entrada e saída de método, indicando os parâmetros. Geralmente só é ativada
temporariamente. O que diferencia esse nível do nível debug é que em produção o trace quase nunca
precisa ser utilizado.
public int sumNumbers(int first, int second){
       log.trace("sumNumbers({},{})", first, second);
       return first+second;
}



Debug
Grava todo e qualquer event ocom informações importantes sobre o funcionamento da aplicação.
Geralmente é ativada em produção para ajudar os desenvolvedores com informações extras.
public int sumNumbers(int first, int second){
       log.debug("sumNumbers() returned {}", first+second);
       return first+second;
}
Níveis de log
Info
Informa que algum evento importante da aplicação foi concluído. Em um mundo ideal, tanto
administradores como usuários avançados deveriam ser capazes de entender o que a aplicação está
fazendo através desses logs
public String importXml(String url){
        String xml = null;
        Connection connection = null;
        log.info("connecting to {}", url);
        connection = connectToUrl(url);
        log.info("importing xml");
        xml = importXml(connection);
        log.info("xml imported successfully");
        return xml;
}

Warning
Mensagem indicando que embora o processo possa continuar, algo está fora do esperado a atenção
deverá ser redobrada. Ex.
while ((nextLine = reader.readNext()) != null) {
        if (!StringUtil.toString(nextLine).trim().isEmpty()) {
                   readLine(nextLine);
        } else {
                   logger.warn("Foi lida uma linha em branco do csv, remova linhas sem conteúdo.");
        }
}
Níveis de log

Error
Algum problema intolerável aconteceu, que precisa ser investigado imediatamente. Nenhum sistema
deve tolerar eventos desse nível. Ex. NullPointerException, Connection
if (!FTPReply.isPositiveCompletion(reply)) {
        client.disconnect();
        logger.error("FTP server refused connection. Reply was {}", reply);
        return false;
}




Fatal
Eventos severos que impedem o funcionamento do aplicação. Após esse erro a aplicação
possivelmente irá parar de responder.
try {
        new GlobalsatDriverFtp().run();
} catch (Exception e) {
        logger.fatal("Error running GlobalsatDriver: ", e);
        e.printStackTrace();
}
Níveis de log

Trace x Debug

O trace deve ser usado apenas para indicar em qual método o sistema está passando, enquanto o
debug indica estados do sistema. O trace não deve indicar valor de variáveis.
Se existe a possibilidade de usar esse log em produção então não é trace. O trace é utilizado quase
que exclusivamente em ambiente de desenvolvimento somente.
Níveis de log

Debug x Info

O debug contém informações pertinentes ao desenvolvedor do sistema.
O Info contém informações pertinentes aos usuários do sistema, auditores, equipe de suporte,
desenvolvedores e outros...
Níveis de log

Info x Warning
O Info indica etapas do sistema que não requerem intervenção do usuário nem do desenvolvedor. Em
geral são apenas informações sobre o que está acontecendo por trás dos panos.
O Warning indica que ocorreu um comportamento inesperado, e embora o sistema possa continuar
geralmente espera-se investigação do ocorrido.
Níveis de log

Warning x Error
O Warning indica que ocorreu um comportamento inesperado mas mesmo assim o sistema
conseguiu continuar. Seria interessante por parte do desenvolvedor corrigir o problema.
O Error indica que ocorreu um comportamento inesperado no código em execução e o sistema não
conseguiu continuar. O desenvolvedor precisa corrigir o problema.
Níveis de log

Error x Fatal

O Error indica que um bloco de código foi abortado e não pôde continuar.
O Fatal indica que o sistema foi abortado e não pôde continuar.
Appenders

Common Appenders
      FileAppender - Escreve os logs em um arquivo
      RollingFileAppender - Estende o FileAppender permitindo backups a medida que o arquivo
atinge um tamanho limite
      DailyRollingFileAppender - Estende o FileAppender para que o roll em arquivo possa ser
definido por alguma frequência dada pelo usuário.
      ConsoleAppender - Escreve os logs no System.out ou System.error



Network Appenders
     SocketAppender - Envia os logs para um log server remoto
     SocketHubAppender - Envia os logs para um conjunto de log servers remotos
     JMSAppender - Publica logs em um tópico JMS.
     NTEventLogAppender - Registra log no sistema de eventos do sistema operacional
Appenders

Special Appenders
      AsyncAppender - Faz com que um appender seja asincrono, permitindo que a aplicação
continue a rodar independentemente.
      ExternallyRolledFileAppender - Permite que o sistema escuta uma porta do computador e ao
receber mensagem execute um rollover no log.
      JDBCAppender - Salva os logs em um banco de dados
      LF5Appender - Envia log para o console de uma aplicação java em swing.
      NullAppender - Útil para testes internos ou benchmarking
      SMTPAppender - Envia e-mail quando o log especificado for lançado pelo sistema.
      SyslogAppender - Envia os logs para um syslog daemon remoto.
      TelnetAppender - Envia log pelo telnet
      WriterAppender - WriterAppender anexa eventos de log a um Write ou OutputStream
dependendo da escolha do usuário.
Onde e quando devemos logar

Primeiro: identifique o público alvo
 ●   Auditores
 ●   Transações que envolvem dinheiro
 ●   Equipe de suporte ao sistema dentro do cliente (TI Petrobras)
 ●   Segurança, detectar ataques de DoS, etc..
 ●   Facilitar



Segundo: identifique para onde irá o log
 ●   Arquivo (desenvolvedores)
 ●   Jms
 ●   Email (Segurança)
 ●   Banco de dados (auditoria)
 ●   ETC...


Por último:
 ●   Se interessa ao público alvo, identifique o nível em que o log se adequa e logue!
Estudo de Caso

Como todo log é uma história, no nosso caso iremos contar uma história dos Simpsons
Estudo de Caso

O diretor da escola ligou para Marge e avisou que Bart anda matando aula. Ele disse que na semana
passada Bart faltou 2 vezes e que isso é preocupante pois suas notas não estão boas.
Marge preocupada, teve uma idéia de como descobrir o que estava acontecendo para mandar Bart
de volta à escola.
Estudo de Caso

Marge deu de presente um novo relógio para o Bart, e sem que ele saiba, o relógio irá enviar para o
email da Marge um log com uma foto do local e posição gps de onde ele está a cada minuto.
Estudo de Caso

Bart, feliz com seu novo relógio do Krusty, cola o relogio antes de dormir e o relógio começa a
funcionar.
Assim que Bart acorda de manhã para ir à escola o relógio faz seu primeiro log ((info))
Esse log é importante pois indica se Bart está com problema para acordar no horário.
Estudo de Caso

Após tomar seu café da manhã, Bart sai de casa para ir para a escola.
Nesse momento o relógio faz mais um log ((info))
Esse log será importante pois indica se ele se atrasa para pegar o ônibus ou sai no horário certo.
Estudo de Caso

Ao invés de pegar o ônibus, bart vai para a escola de skate.
O relógio mais uma vez faz um log com foto ((warn))
Esse log será importante pois indica que algo não está indo conforme o esperado, embora não seja
necessariamente um problema.
Estudo de Caso

A cada rua que Bart passa, o relógio realiza mais logs ((trace)).
O cada casa que o Bart passa o relógio faz log ((debug)) novamente , i
ndicando quem mora na casa.
Esse log será importante pois indica que ele passou na casa do Milhouse. Agora a mudança de rotina
faz começa a fazer sentido.
Estudo de Caso

Como Bart passa pela escola e segue em frente o sistema realiza mais um log ((error)).
Esse log é fundamental, o objetivo é a escola se ela não parou então algo está errado. Isso não pode
acontecer.
Estudo de Caso

Após passar pela escola Bart para em frente a um show de rock. Nesse momento o relógio faz mais
um log ((fatal)).
Esse log é o log final, de fato Bart não foi para escola. Agora não faz mais sentido fazer log, Marge
precisará intervir.
Estudo de Caso

Conclusão:
O log precisa contar uma história. E essa história precisa estar clara para que quem lê consiga
entender não só os acontecimentos, mas a sua importância, como corrigi-los e como evitá-los.
Ferramentas que usamos hoje?

Aqui no Tecgraf usamos apenas o Log4j (1.2.x)
 ● Ferramenta para java criada pela apache.
 ● Foi quem primeiro definiu padrões de log em java
 ● A versão 1.x apesar de estável não é mais ativamente desenvolvida
 ● Em geral todo log é feito concatenando strings. Ex. log.error("Fulano "+x+" disse "+y)
 ● Para debug usa-se if(logger.isDebugEnabled()), toda vez.
 ● Tem bons appenders

.

Commons login (JCL)
 ● Jakarta Commons logging.
 ● Não faz log, apenas define um façade para apis de log.
 ● Apesar de estável não é mais ativamente desenvolvida
 ● É muito comum encontrarmos essa biblioteca causando problemas de classloader em
    servidores.
Tem coisa melhor?
LOGBack
  ● Ferramenta java criada pelo desenvolvedor do Log4j 1.x
  ● Permitir mudar o nível de log sem reiniciar a aplicação
  ● É o novo padrão em log
  ● Todos recomendam logback ao invés de log4j 1.x
  ● Mais rápida que o log4j 1.x
  ● Já foi criado pensando no sl4j
  ● Melhor recuperação em falhas de I/O
  ● Mais e melhores opções de filtro
  ● Indica no log em que jar está a classe que gerou a exceção
  ● Não usa concatenação de string para log. Ex. log.error("Fulano {} disse {}", x, y);
  ● Não precisa de if(logger.isDebugEnabled());
  ● Tem bons appenders
  ● Permite agrupar logs para que sejam exibidos em ordem
  ● Permite separar log por usuário do sistema ou outra variável qualquer
slf4j
  ● Ferramenta java criada pelo desenvolvedor do Log4j 1.x
  ● Não faz log, apenas define um façade para apis de log.
  ● Todos recomendam slf4j ao invés de commons-logging
  ● Até a apache utiliza o slf4j
  ● Possui um jcl-over-slf4j para não criar conflito com o jcl e redirecionar para o slf4j
  ● Possui um log4j-over-slf4j para não criar conflito com o log4j e redirecionar para o slf4j
  ● Possui um sl4j migrator tool que migra automaticamente o seu código de log4j para sl4j
Tem coisa melhor?

Log4j (2.x.beta)
 ● Ferramenta para java criada pela apache.
 ● Substitui e o log4j 1.x
 ● Foi criada para ter tudo o que o logback tem.
 ● Resolve alguns problemas de arquitetura do logback
 ● Oferece mais funcionalidades que o logback
 ● As chances são de que ela seja o novo padrão, ao invés do logback
Log asíncrono?

●   Acaba sendo mais rápido para a aplicação

●   Faz log sem bloquear o código principal

 ● Especialmente eficaz em aplicações multithread uma vez que várias
threads precisarão escrever no mesmo arquivo

●   Extremamente recomendável quando a aplicação tem um número elevado
    de logs.

●   Não é suportado em containers J2EE, para esses caso usa-se o
    JMSAppender
Boas práticas sobre o nosso código

O catch foi criado para tratar exceções e não para fazer log. Neste caso o ideal
seria propagar a exceção.




catch (Exception e) {
     logger.error("", e);
     return false;
}
Boas práticas sobre o nosso código

Por utilizarmos o log4j 1.x nosso logs são cheios de contaneção. Devemos
atualizar a nossa biblioteca para usar novas versão de log e evitar esse
overhead desnecessário.




if (v == null || DatabaseConstants.VEHICLE_STATUS_INACTIVE.equals(v.getStatus())) {
    logger.info("Discarding planning " + plannedTrip.getPlanningNumber()
    + ". Vehicle " + plate + " is not registered or inactive.");
    return true;
}
Boas práticas sobre o nosso código

Use logs enxutos. O ideal é que cada mensagem de log não passe de uma
linha de texto.
PS: Repare que novamente a exceção não é tratada.




catch (InvalidParameterException e) {
    logger.warn(buildVDBDocWarnMessage(meta.getCanonicalName()), e);
}
Boas práticas sobre o nosso código

Repare que a concatenação de strings também faz com que a leitura do log
ganhe complexidade.




catch (IOException e) {
     logger.error("Error while creating the bean" + clazz + " / " + metadataName + " in
" + getClass().getSimpleName(), e);
}



catch(Exception e){
     logger.error("Login denied for user "+user.getLogin());
}
Boas práticas sobre o nosso código

Catch de Exception não pode ser feito:
Primeiro porque você não sabe que erro é esse portanto não tem como tratar
Segundo porque você impede o recibemto da exceção para quem sabe tratá-
la.
PS: Mais uma vez a exceção não é tratada e se perde no código



try{
       client.disconnect();
}catch(Exception e){
       logger.error(e);
}
Boas práticas sobre o nosso código

Não acesse variáveis dentro das mensagens de log, elas podem estar nulas.
A última coisa que faltava é o sistema parar de responder pq houve
NullPointerException ao criar uma mensagem de log.

_logger.trace("Ended task '" + task.getName() + "' (progress rate = " + _currentProgressRate +
"%)");



try {
processingService.saveResults(getUserContext(), env);
} catch (IOException e) {
LOGGER.error("Error saving processing results for moving object: " + moCache.getMovingObject().
getIdentifier(), e);
throw e;
}



_logger.debug("created start node id " + startNode.getId());
Boas práticas sobre o nosso código

Parábens para o nosso código que usou corretamente o if(debug).




if (debug) {
logger.debug("andAnyAttributeLocation()-" + clause);
}
Boas práticas sobre o nosso código

Pena que não é sempre assim, a maior parte do nosso código não usa o if
(debug).
Esse tipo de overhead pode ser evitado se usarmos o LogBack ou slf4j.
PS: Utilize logs de no máximo uma linha.
PS: Não acesse variáveis dentro das mensagens



String debugLine = "Received httpData Version: " + getVersionNumber() + "- deviceId: "
+ id[0] + ", cont: " + cont + ", time: "+ sessionTime.getTime() + ", httpData: " +
msgsDebug;
if (!hasInvalidCharacters(debugLine)){
    logger.debug(debugLine);
}else{
    logger.debug("Recebida requisição que contém caracteres inválidos.");
}
Boas práticas sobre o nosso código

Embora muito comumn, fazer catch de RuntimeException não é uma boa
prática.
Se o seu código tem muito tratamento de RuntimeException isso é um sinal de
que ele não está estável.




try{
       connect();
}catch(NullPointerException npe){
       logger.error("Erro ao conectar", npe);
}
Dúvidas?
Exceção em JAVA
O que é?

●   É um aviso indicando que o código em execução
    encontrou um comportamento impeditivo com o qual ele
    não sabe lidar.

●   É uma subclasse de "java.lang.Throwable".

●   Contém informações sobre o comportamento
    encontrado para que o código no topo da hierarquia
    possa tratá-lo ou seguir por outro caminho.
Tipos de exceção
Classificação

Checked Exceptions
São subclasses de Exception. Representam exceções onde o desenvolvedor consegue se recuperar.
Embora indiquem um comportamento inesperado, não são necessariamente um erro e não impedem
o sistema de continuar.
Ex. FileNotFoundException, ParseException , ...




Unchecked Exceptions
São subclasses de Error ou RuntimeException. Representam o inverso das Checked Exceptions.
Quando essas exceções ocorrem elas indicam que existe um erro no código e o sistema ou bloco de
código não pode continuar.
Geralmente essas exceções fazem com que o sistema seja desligado.
Ex. NullPointerException, StackOverflowError, OutOfMemoryError, NoClassDefFoundError,
IllegalArgumentException
Classificação

Porque vemos mais classes que herdam de Exception do que Error ou RuntimeException?

Não vemos muitas classes que herdam de Error porque por convenção somente a JVM pode criar e
lançar classes que herdam de Error.

Não vemos muitas classes que herdam de RuntimeException porque, como elas não precisam ser
declaradas, o sistema não fica preparado para que ela aconteça.
Relatos de desenvolvedores que usaram bastante RuntimeExceptions, explicam que todas as vezes
que a aplicação entrava em produção apareciam erros graves que bloqueavam o sistema.
O que provavelmente já teria sido tratado e não bloquearia o sistema se tivesse sido declarado
corretamente no throws.
Na comunidade Java há quem diga que os sistemas deveriam apenas usar apenas Exception, e que
RuntimeException e Error deveriam ser exclusivos da JVM.
Quando lançar?

THROW EARLY catch late
Quanto mais informação houver no stack trace, melhor. Portanto ao invés de deixar exceções como
NullpointerException acontecerem em locais pouco informativos, detecte o problema e lance a
exceção onde se encontra o verdadeiro problema.



public void readPreferences(String filename) throws IllegalArgumentException{
     if (filename == null)     {
              throw new IllegalArgumentException("filename is null");
     } //if
     //...perform other operations...
     InputStream in = new FileInputStream(filename);
     //...read the preferences file...
}
Quando tratar?

throw early CATCH LATE
A exceção deve ser lançada o suficiente para que quem tem mais informação possa tratá-la. Um erro
muito comum é tratar a exceção assim que ela acontece, impedindo que o sistema trate-a da maneira
apropriada. Propague a exceção para quem pode tratá-la.

public void readPreferences(String filename){
     //...
     InputStream in = null;
     // NÂO FAÇA ISSO!!!
     try{
             in = new FileInputStream(filename);
     }catch (FileNotFoundException e)    {
             logger.log(e);
             return;
     }
     in.read(...);
     //...
}
Boas práticas

Valide argumentos quando necessário
Mas também não precisa fazer isso em todos os métodos!
Valide os inputs nos métodos que já originaram bugs, assim você irá evitar que esses bugs ocorram
novamente.




if ( null == variable || variable.isEmpty()){
   throw new NullPointerException("the variable cannot be null at this point");
}
Boas práticas

Evite grandes blocos de try catch
Separe os try catch por escopo, assim o código fica mais fácil de entender e cada bloco irá pegas
apenas as exceções pertinentes a tarefas pontuais. Considere dividi-los em métodos diferentes.

try{
     s = pegarNomeDoArquivo();
     f = lerArquivo(s);
     v = validarArquivo(f);
}catch(FileNotFoundException fne){
}

try{
     x = fazerParseDoArquivo(f);
     z = modificarXml()
}catch(ParseException pe){
}
Boas práticas

Se não vai tratar, propague!
Não faça catch em exceções apenas para encher log. O catch foi feito para tratar exceções e não para
fazer log. Dessa forma você inpedirá que a exceção seja tratada por quem sabe como tratá-la.

try{
     s = pegarNomeDoArquivo();
     f = lerArquivo(s);
     v = validarArquivo(f);
}catch(Exception e){
     log.error("Error ao ler arquivo", e);
}
Boas práticas

Cuidado para não engulir exceções
No bloco abaixo caso aconteça um FileNotFoundException veremos apenas um NullPointerException
gerado pelo descuidado finally. O correto seria verificar se "input" é nulo no finally.

InputStream input = null;

 try{
        input = new FileInputStream("myFile.txt");
        //do something with the stream
 } catch(IOException e){
        throw new WrapperException(e);
 } finally {
   try{
        input.close();
   } catch(IOException e){
         throw new WrapperException(e);
   }
 }
Boas práticas

Enriqueça as exceções lançadas
Aproveite a propagação das exceções para enriquecê-las

public void parseXml(String filePath) throws ParseException, IOException{
      try{
            File f = leArquivo(filePath);
            fazParse(f);
      }catch(IOException ioe){
            throw new IOException("Parse falhou pois arquivo não existe {}", filePath, ioe);
      }
}

public File leArquivo(String filePath) throws IOException{
      //Irá gerar uma exceção
      return new File(filePath);
}
Fique atento!

No JAVA 7 haverá uma nova forma de tratar exceções
Para evitar o uso do try catch dentro do finally o java 7 criou o try-with-resources. Assim qualquer classe que
herde de java.lang.AutoCloseable é fechada pela java automaticamente no try catch



Try-with-resources

ANTIGO                                              NOVO
OldResource res = null;
 try {                                              try(NewResource res = new NewResource("Res1 closing")){
          res = new OldResource();                          res.doSomeWork("Listening to podcast");
          res.doSomeWork("Writing");                 } catch(Exception e){
 } catch (Exception e) {                                     System.out.println("Exception");
          System.out.println("Exception");           }
 } finally{
        try {
             res.close();
          } catch (Exception e) {
             System.out.println("Exception");
          }
}
Dúvidas?
Referências


●   http://architects.dzone.com/articles/high-performance-and-smarter
●   http://www.javacodegeeks.com/2011/01/10-tips-proper-application-logging.html
●   http://javarevisited.blogspot.com.br/2011/05/top-10-tips-on-logging-in-java.html
●   http://www.allapplabs.com/log4j/log4j_appenders.htm
●   http://logback.qos.ch/manual/appenders.html
●   http://www.javaworld.com/javaworld/jw-05-2004/jw-0510-logging.html?page=3
●   http://c2.com/cgi/wiki?LoggingBestPractices
●   https://wiki.base22.com/display/btg/Java+Logging+Standards+and+Guidelines
●   http://runjva.appspot.com/logging101/index.html
●   http://programmers.stackexchange.com/questions/112402/what-are-some-patterns-and-anti-patterns-of-application-logging
●   http://gojko.net/2006/12/09/logging-anti-patterns/
●   http://today.java.net/article/2006/04/04/exception-handling-antipatterns
●   http://www.wikijava.org/wiki/10_best_practices_with_Exceptions
●   http://tutorials.jenkov.com/java-exception-handling/index.html
●   http://www.javacodegeeks.com/2011/07/java-7-try-with-resources-explained.html

Mais conteúdo relacionado

PDF
Entendendo o google hacking na pratica e otimizando suas buscas com dorks
PDF
Sistemas de arquivos cap 04 (iii unidade)
PPTX
Avarias de computadores
PDF
Redes de Computadores
ODP
Aula Introdução a Arquitetura e Organização de Computadores
PPTX
SDAC 12º - M9 TGEI
PDF
Informação digital e segurança
KEY
HTML/CSS Patterns
Entendendo o google hacking na pratica e otimizando suas buscas com dorks
Sistemas de arquivos cap 04 (iii unidade)
Avarias de computadores
Redes de Computadores
Aula Introdução a Arquitetura e Organização de Computadores
SDAC 12º - M9 TGEI
Informação digital e segurança
HTML/CSS Patterns

Mais procurados (20)

PPTX
IMEI Módulo 8 (Curso profissional de Gestão de Equipamentos Informáticos)
PPT
3 2 Administracion Y Configuracion De Dispositivos
 
PPTX
Lenguaje de programación MySQL
PPT
Aula 04 arquitetura de computadores
PPT
Seguranca Digital
PDF
Introdução ao Desenvolvimemto de Jogos com Unity
PPTX
Sistemas operativos servidor
PPTX
Trabalho do sistemas operativos
PPTX
Trabalho Linux - Red Hat
PPTX
Avarias mais comuns nos computadores
PPTX
Processadores RISC
PDF
Montage Pc
PPT
CapíTulo 1 IntroduçãO à InformáTica
PPTX
Aula 07 instalação de hardware
PDF
Informática 1-conceitos e componentes
PPT
CapíTulo 2 Hardware
PPT
Ibm power ha v7 technical deep dive workshop
PPTX
Apresentação - sistemas operacionais
PPT
Trabalho Tic - Sistema Operativo
PDF
Modelagem de dados
IMEI Módulo 8 (Curso profissional de Gestão de Equipamentos Informáticos)
3 2 Administracion Y Configuracion De Dispositivos
 
Lenguaje de programación MySQL
Aula 04 arquitetura de computadores
Seguranca Digital
Introdução ao Desenvolvimemto de Jogos com Unity
Sistemas operativos servidor
Trabalho do sistemas operativos
Trabalho Linux - Red Hat
Avarias mais comuns nos computadores
Processadores RISC
Montage Pc
CapíTulo 1 IntroduçãO à InformáTica
Aula 07 instalação de hardware
Informática 1-conceitos e componentes
CapíTulo 2 Hardware
Ibm power ha v7 technical deep dive workshop
Apresentação - sistemas operacionais
Trabalho Tic - Sistema Operativo
Modelagem de dados
Anúncio

Destaque (20)

PPTX
JSF 2 e Primefaces - 4º Encontro Mensal do Gojava
PDF
Java 8 - Afinal onde usamos no dia a dia? TDC 2015 - Porto Alegre
PDF
JSR 375 Segurança em Java EE 8
PPTX
SLF4J Explained........
PPT
PDF
Java 8 - Afinal onde usamos no dia a dia? GOJava 15 anos!
PDF
Visão geral da segurança em Java EE
PPT
Jsf – Java Sever Faces
PPT
SLF4J (Simple Logging Facade for Java)
PDF
Tutorial JSF 2.0 (2012)
PDF
JBoss Fuse Workshop Desenvolvimento - Parte 1
PDF
Dicas e truques sobre performance em JavaEE, JPA e JSF
PPTX
Bibliotecas de interface rica no jsf 2
PPTX
Boas práticas com jpa 2 e hibernate flisol 2012
PDF
JSF com Primefaces
KEY
Construindo uma arquitetura com REST, HTML 5 e JSF 2
PPT
Java Server Pages
PPT
Introdução a JPA e Hibernate - TDC 2012
PPTX
Minicurso jpa e hibernate
JSF 2 e Primefaces - 4º Encontro Mensal do Gojava
Java 8 - Afinal onde usamos no dia a dia? TDC 2015 - Porto Alegre
JSR 375 Segurança em Java EE 8
SLF4J Explained........
Java 8 - Afinal onde usamos no dia a dia? GOJava 15 anos!
Visão geral da segurança em Java EE
Jsf – Java Sever Faces
SLF4J (Simple Logging Facade for Java)
Tutorial JSF 2.0 (2012)
JBoss Fuse Workshop Desenvolvimento - Parte 1
Dicas e truques sobre performance em JavaEE, JPA e JSF
Bibliotecas de interface rica no jsf 2
Boas práticas com jpa 2 e hibernate flisol 2012
JSF com Primefaces
Construindo uma arquitetura com REST, HTML 5 e JSF 2
Java Server Pages
Introdução a JPA e Hibernate - TDC 2012
Minicurso jpa e hibernate
Anúncio

Semelhante a Apresentacao log (20)

PPT
Log4net
PDF
Aprenda a programar-luciano_ramalho
PDF
Aprenda a programar-luciano_ramalho
PDF
Aprenda a programar-luciano_ramalho
PPT
FC-Logic
PPTX
"Monitoração - muito além do sistema operacional" - Marcus Vechiato (Locaweb)...
PPTX
Debugging node
ODP
Programação Defensiva
PDF
Monitoramento: logs como elementos de primeira ordem
PPTX
Como ser programador durante o dia e mesmo assim dormir bem à noite
PDF
Visualg primeira interação
PDF
Vivendo de hacking
PDF
Algoritmos com java script
PDF
Aula 02 - Introducao a Algoritmos.pptx.pdf
PDF
Aprenda a programar python
PDF
Webinar: Debugging em Linux embarcado
PDF
Aprenda a programar-luciano_ramalho
PPTX
Monitoração - muito além do sistema operacional - WeOp 2014
ODP
Calourada2010
PDF
Logs: A Chave para um Diagnóstico Eficiente e Boas Práticas de Monitoramento
Log4net
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalho
Aprenda a programar-luciano_ramalho
FC-Logic
"Monitoração - muito além do sistema operacional" - Marcus Vechiato (Locaweb)...
Debugging node
Programação Defensiva
Monitoramento: logs como elementos de primeira ordem
Como ser programador durante o dia e mesmo assim dormir bem à noite
Visualg primeira interação
Vivendo de hacking
Algoritmos com java script
Aula 02 - Introducao a Algoritmos.pptx.pdf
Aprenda a programar python
Webinar: Debugging em Linux embarcado
Aprenda a programar-luciano_ramalho
Monitoração - muito além do sistema operacional - WeOp 2014
Calourada2010
Logs: A Chave para um Diagnóstico Eficiente e Boas Práticas de Monitoramento

Apresentacao log

  • 1. E exceções ! Autor: Pedro H. F. S. Diniz Grupo de GIS, Tecgraf
  • 2. Sobre esta apresentação Logs ● O que é e porque é importante ● Níveis de log ● Appenders ● Onde e quando devemos logar ● Estudo de caso ● Ferramentas que usamos hoje? ● Tem coisa melhor? ● Log assíncrono? ● Boas práticas sobre o nosso código
  • 3. Sobre esta apresentação Exceção ● O que é? ● Tipos de exceção ● Classificação ● Quando lançar? ● Quando tratar? ● Boas práticas ● Fique Atento!
  • 4. O que é ● É a história de vida do sistema ● É uma instrução do código que grava informações de execução em algum lugar (email, arquivo, jms, banco de dados, etc..) ● É a melhor maneira de se identificar um problema em produção ● É uma ferramenta para realizar auditoria no sistema ● É a ferramenta mais eficaz para que o cliente consiga rodar a manter a aplicação sem a intervenção dos desenvolvedores
  • 5. Porque é importante Pense que sua aplicação agora está fora do ambiente de desenvolvimento - não está mais rodando na sua ide favorita e muito menos disponível para debug. É nessa hora que você irá percebeber a importância dos logs. Depois de ler inúmeras linhas de log tentando identificar o que há de errado na aplicação você vai entender que não é uma tarefa trivial. Daí você se pergunta: com toda a minha experiência e conhecimento, é isso o que eu estou destinado a fazer? Encontrar uma agulha em um palheiro de logs? Ou no nosso caso, delegando para o cliente (como na petrobras por exemplo), que possui uma equipe de suporte e manutenção que igualmente nos amaldiçoa pela gratificante e entediante tarefa! Ou pior ainda, ter que levar até o cliente os arquitetos do software e fazer eles se involverem, enquanto eles pensam a cada minuto como é um erro gastar o seu tempo e habilidade com isso.
  • 6. Níveis de log Em geral são: - Trace - Debug - Info - Warning - Error -Fatal
  • 7. Níveis de log Trace Traça toda entrada e saída de método, indicando os parâmetros. Geralmente só é ativada temporariamente. O que diferencia esse nível do nível debug é que em produção o trace quase nunca precisa ser utilizado. public int sumNumbers(int first, int second){ log.trace("sumNumbers({},{})", first, second); return first+second; } Debug Grava todo e qualquer event ocom informações importantes sobre o funcionamento da aplicação. Geralmente é ativada em produção para ajudar os desenvolvedores com informações extras. public int sumNumbers(int first, int second){ log.debug("sumNumbers() returned {}", first+second); return first+second; }
  • 8. Níveis de log Info Informa que algum evento importante da aplicação foi concluído. Em um mundo ideal, tanto administradores como usuários avançados deveriam ser capazes de entender o que a aplicação está fazendo através desses logs public String importXml(String url){ String xml = null; Connection connection = null; log.info("connecting to {}", url); connection = connectToUrl(url); log.info("importing xml"); xml = importXml(connection); log.info("xml imported successfully"); return xml; } Warning Mensagem indicando que embora o processo possa continuar, algo está fora do esperado a atenção deverá ser redobrada. Ex. while ((nextLine = reader.readNext()) != null) { if (!StringUtil.toString(nextLine).trim().isEmpty()) { readLine(nextLine); } else { logger.warn("Foi lida uma linha em branco do csv, remova linhas sem conteúdo."); } }
  • 9. Níveis de log Error Algum problema intolerável aconteceu, que precisa ser investigado imediatamente. Nenhum sistema deve tolerar eventos desse nível. Ex. NullPointerException, Connection if (!FTPReply.isPositiveCompletion(reply)) { client.disconnect(); logger.error("FTP server refused connection. Reply was {}", reply); return false; } Fatal Eventos severos que impedem o funcionamento do aplicação. Após esse erro a aplicação possivelmente irá parar de responder. try { new GlobalsatDriverFtp().run(); } catch (Exception e) { logger.fatal("Error running GlobalsatDriver: ", e); e.printStackTrace(); }
  • 10. Níveis de log Trace x Debug O trace deve ser usado apenas para indicar em qual método o sistema está passando, enquanto o debug indica estados do sistema. O trace não deve indicar valor de variáveis. Se existe a possibilidade de usar esse log em produção então não é trace. O trace é utilizado quase que exclusivamente em ambiente de desenvolvimento somente.
  • 11. Níveis de log Debug x Info O debug contém informações pertinentes ao desenvolvedor do sistema. O Info contém informações pertinentes aos usuários do sistema, auditores, equipe de suporte, desenvolvedores e outros...
  • 12. Níveis de log Info x Warning O Info indica etapas do sistema que não requerem intervenção do usuário nem do desenvolvedor. Em geral são apenas informações sobre o que está acontecendo por trás dos panos. O Warning indica que ocorreu um comportamento inesperado, e embora o sistema possa continuar geralmente espera-se investigação do ocorrido.
  • 13. Níveis de log Warning x Error O Warning indica que ocorreu um comportamento inesperado mas mesmo assim o sistema conseguiu continuar. Seria interessante por parte do desenvolvedor corrigir o problema. O Error indica que ocorreu um comportamento inesperado no código em execução e o sistema não conseguiu continuar. O desenvolvedor precisa corrigir o problema.
  • 14. Níveis de log Error x Fatal O Error indica que um bloco de código foi abortado e não pôde continuar. O Fatal indica que o sistema foi abortado e não pôde continuar.
  • 15. Appenders Common Appenders FileAppender - Escreve os logs em um arquivo RollingFileAppender - Estende o FileAppender permitindo backups a medida que o arquivo atinge um tamanho limite DailyRollingFileAppender - Estende o FileAppender para que o roll em arquivo possa ser definido por alguma frequência dada pelo usuário. ConsoleAppender - Escreve os logs no System.out ou System.error Network Appenders SocketAppender - Envia os logs para um log server remoto SocketHubAppender - Envia os logs para um conjunto de log servers remotos JMSAppender - Publica logs em um tópico JMS. NTEventLogAppender - Registra log no sistema de eventos do sistema operacional
  • 16. Appenders Special Appenders AsyncAppender - Faz com que um appender seja asincrono, permitindo que a aplicação continue a rodar independentemente. ExternallyRolledFileAppender - Permite que o sistema escuta uma porta do computador e ao receber mensagem execute um rollover no log. JDBCAppender - Salva os logs em um banco de dados LF5Appender - Envia log para o console de uma aplicação java em swing. NullAppender - Útil para testes internos ou benchmarking SMTPAppender - Envia e-mail quando o log especificado for lançado pelo sistema. SyslogAppender - Envia os logs para um syslog daemon remoto. TelnetAppender - Envia log pelo telnet WriterAppender - WriterAppender anexa eventos de log a um Write ou OutputStream dependendo da escolha do usuário.
  • 17. Onde e quando devemos logar Primeiro: identifique o público alvo ● Auditores ● Transações que envolvem dinheiro ● Equipe de suporte ao sistema dentro do cliente (TI Petrobras) ● Segurança, detectar ataques de DoS, etc.. ● Facilitar Segundo: identifique para onde irá o log ● Arquivo (desenvolvedores) ● Jms ● Email (Segurança) ● Banco de dados (auditoria) ● ETC... Por último: ● Se interessa ao público alvo, identifique o nível em que o log se adequa e logue!
  • 18. Estudo de Caso Como todo log é uma história, no nosso caso iremos contar uma história dos Simpsons
  • 19. Estudo de Caso O diretor da escola ligou para Marge e avisou que Bart anda matando aula. Ele disse que na semana passada Bart faltou 2 vezes e que isso é preocupante pois suas notas não estão boas. Marge preocupada, teve uma idéia de como descobrir o que estava acontecendo para mandar Bart de volta à escola.
  • 20. Estudo de Caso Marge deu de presente um novo relógio para o Bart, e sem que ele saiba, o relógio irá enviar para o email da Marge um log com uma foto do local e posição gps de onde ele está a cada minuto.
  • 21. Estudo de Caso Bart, feliz com seu novo relógio do Krusty, cola o relogio antes de dormir e o relógio começa a funcionar. Assim que Bart acorda de manhã para ir à escola o relógio faz seu primeiro log ((info)) Esse log é importante pois indica se Bart está com problema para acordar no horário.
  • 22. Estudo de Caso Após tomar seu café da manhã, Bart sai de casa para ir para a escola. Nesse momento o relógio faz mais um log ((info)) Esse log será importante pois indica se ele se atrasa para pegar o ônibus ou sai no horário certo.
  • 23. Estudo de Caso Ao invés de pegar o ônibus, bart vai para a escola de skate. O relógio mais uma vez faz um log com foto ((warn)) Esse log será importante pois indica que algo não está indo conforme o esperado, embora não seja necessariamente um problema.
  • 24. Estudo de Caso A cada rua que Bart passa, o relógio realiza mais logs ((trace)). O cada casa que o Bart passa o relógio faz log ((debug)) novamente , i ndicando quem mora na casa. Esse log será importante pois indica que ele passou na casa do Milhouse. Agora a mudança de rotina faz começa a fazer sentido.
  • 25. Estudo de Caso Como Bart passa pela escola e segue em frente o sistema realiza mais um log ((error)). Esse log é fundamental, o objetivo é a escola se ela não parou então algo está errado. Isso não pode acontecer.
  • 26. Estudo de Caso Após passar pela escola Bart para em frente a um show de rock. Nesse momento o relógio faz mais um log ((fatal)). Esse log é o log final, de fato Bart não foi para escola. Agora não faz mais sentido fazer log, Marge precisará intervir.
  • 27. Estudo de Caso Conclusão: O log precisa contar uma história. E essa história precisa estar clara para que quem lê consiga entender não só os acontecimentos, mas a sua importância, como corrigi-los e como evitá-los.
  • 28. Ferramentas que usamos hoje? Aqui no Tecgraf usamos apenas o Log4j (1.2.x) ● Ferramenta para java criada pela apache. ● Foi quem primeiro definiu padrões de log em java ● A versão 1.x apesar de estável não é mais ativamente desenvolvida ● Em geral todo log é feito concatenando strings. Ex. log.error("Fulano "+x+" disse "+y) ● Para debug usa-se if(logger.isDebugEnabled()), toda vez. ● Tem bons appenders . Commons login (JCL) ● Jakarta Commons logging. ● Não faz log, apenas define um façade para apis de log. ● Apesar de estável não é mais ativamente desenvolvida ● É muito comum encontrarmos essa biblioteca causando problemas de classloader em servidores.
  • 29. Tem coisa melhor? LOGBack ● Ferramenta java criada pelo desenvolvedor do Log4j 1.x ● Permitir mudar o nível de log sem reiniciar a aplicação ● É o novo padrão em log ● Todos recomendam logback ao invés de log4j 1.x ● Mais rápida que o log4j 1.x ● Já foi criado pensando no sl4j ● Melhor recuperação em falhas de I/O ● Mais e melhores opções de filtro ● Indica no log em que jar está a classe que gerou a exceção ● Não usa concatenação de string para log. Ex. log.error("Fulano {} disse {}", x, y); ● Não precisa de if(logger.isDebugEnabled()); ● Tem bons appenders ● Permite agrupar logs para que sejam exibidos em ordem ● Permite separar log por usuário do sistema ou outra variável qualquer slf4j ● Ferramenta java criada pelo desenvolvedor do Log4j 1.x ● Não faz log, apenas define um façade para apis de log. ● Todos recomendam slf4j ao invés de commons-logging ● Até a apache utiliza o slf4j ● Possui um jcl-over-slf4j para não criar conflito com o jcl e redirecionar para o slf4j ● Possui um log4j-over-slf4j para não criar conflito com o log4j e redirecionar para o slf4j ● Possui um sl4j migrator tool que migra automaticamente o seu código de log4j para sl4j
  • 30. Tem coisa melhor? Log4j (2.x.beta) ● Ferramenta para java criada pela apache. ● Substitui e o log4j 1.x ● Foi criada para ter tudo o que o logback tem. ● Resolve alguns problemas de arquitetura do logback ● Oferece mais funcionalidades que o logback ● As chances são de que ela seja o novo padrão, ao invés do logback
  • 31. Log asíncrono? ● Acaba sendo mais rápido para a aplicação ● Faz log sem bloquear o código principal ● Especialmente eficaz em aplicações multithread uma vez que várias threads precisarão escrever no mesmo arquivo ● Extremamente recomendável quando a aplicação tem um número elevado de logs. ● Não é suportado em containers J2EE, para esses caso usa-se o JMSAppender
  • 32. Boas práticas sobre o nosso código O catch foi criado para tratar exceções e não para fazer log. Neste caso o ideal seria propagar a exceção. catch (Exception e) { logger.error("", e); return false; }
  • 33. Boas práticas sobre o nosso código Por utilizarmos o log4j 1.x nosso logs são cheios de contaneção. Devemos atualizar a nossa biblioteca para usar novas versão de log e evitar esse overhead desnecessário. if (v == null || DatabaseConstants.VEHICLE_STATUS_INACTIVE.equals(v.getStatus())) { logger.info("Discarding planning " + plannedTrip.getPlanningNumber() + ". Vehicle " + plate + " is not registered or inactive."); return true; }
  • 34. Boas práticas sobre o nosso código Use logs enxutos. O ideal é que cada mensagem de log não passe de uma linha de texto. PS: Repare que novamente a exceção não é tratada. catch (InvalidParameterException e) { logger.warn(buildVDBDocWarnMessage(meta.getCanonicalName()), e); }
  • 35. Boas práticas sobre o nosso código Repare que a concatenação de strings também faz com que a leitura do log ganhe complexidade. catch (IOException e) { logger.error("Error while creating the bean" + clazz + " / " + metadataName + " in " + getClass().getSimpleName(), e); } catch(Exception e){ logger.error("Login denied for user "+user.getLogin()); }
  • 36. Boas práticas sobre o nosso código Catch de Exception não pode ser feito: Primeiro porque você não sabe que erro é esse portanto não tem como tratar Segundo porque você impede o recibemto da exceção para quem sabe tratá- la. PS: Mais uma vez a exceção não é tratada e se perde no código try{ client.disconnect(); }catch(Exception e){ logger.error(e); }
  • 37. Boas práticas sobre o nosso código Não acesse variáveis dentro das mensagens de log, elas podem estar nulas. A última coisa que faltava é o sistema parar de responder pq houve NullPointerException ao criar uma mensagem de log. _logger.trace("Ended task '" + task.getName() + "' (progress rate = " + _currentProgressRate + "%)"); try { processingService.saveResults(getUserContext(), env); } catch (IOException e) { LOGGER.error("Error saving processing results for moving object: " + moCache.getMovingObject(). getIdentifier(), e); throw e; } _logger.debug("created start node id " + startNode.getId());
  • 38. Boas práticas sobre o nosso código Parábens para o nosso código que usou corretamente o if(debug). if (debug) { logger.debug("andAnyAttributeLocation()-" + clause); }
  • 39. Boas práticas sobre o nosso código Pena que não é sempre assim, a maior parte do nosso código não usa o if (debug). Esse tipo de overhead pode ser evitado se usarmos o LogBack ou slf4j. PS: Utilize logs de no máximo uma linha. PS: Não acesse variáveis dentro das mensagens String debugLine = "Received httpData Version: " + getVersionNumber() + "- deviceId: " + id[0] + ", cont: " + cont + ", time: "+ sessionTime.getTime() + ", httpData: " + msgsDebug; if (!hasInvalidCharacters(debugLine)){ logger.debug(debugLine); }else{ logger.debug("Recebida requisição que contém caracteres inválidos."); }
  • 40. Boas práticas sobre o nosso código Embora muito comumn, fazer catch de RuntimeException não é uma boa prática. Se o seu código tem muito tratamento de RuntimeException isso é um sinal de que ele não está estável. try{ connect(); }catch(NullPointerException npe){ logger.error("Erro ao conectar", npe); }
  • 43. O que é? ● É um aviso indicando que o código em execução encontrou um comportamento impeditivo com o qual ele não sabe lidar. ● É uma subclasse de "java.lang.Throwable". ● Contém informações sobre o comportamento encontrado para que o código no topo da hierarquia possa tratá-lo ou seguir por outro caminho.
  • 45. Classificação Checked Exceptions São subclasses de Exception. Representam exceções onde o desenvolvedor consegue se recuperar. Embora indiquem um comportamento inesperado, não são necessariamente um erro e não impedem o sistema de continuar. Ex. FileNotFoundException, ParseException , ... Unchecked Exceptions São subclasses de Error ou RuntimeException. Representam o inverso das Checked Exceptions. Quando essas exceções ocorrem elas indicam que existe um erro no código e o sistema ou bloco de código não pode continuar. Geralmente essas exceções fazem com que o sistema seja desligado. Ex. NullPointerException, StackOverflowError, OutOfMemoryError, NoClassDefFoundError, IllegalArgumentException
  • 46. Classificação Porque vemos mais classes que herdam de Exception do que Error ou RuntimeException? Não vemos muitas classes que herdam de Error porque por convenção somente a JVM pode criar e lançar classes que herdam de Error. Não vemos muitas classes que herdam de RuntimeException porque, como elas não precisam ser declaradas, o sistema não fica preparado para que ela aconteça. Relatos de desenvolvedores que usaram bastante RuntimeExceptions, explicam que todas as vezes que a aplicação entrava em produção apareciam erros graves que bloqueavam o sistema. O que provavelmente já teria sido tratado e não bloquearia o sistema se tivesse sido declarado corretamente no throws. Na comunidade Java há quem diga que os sistemas deveriam apenas usar apenas Exception, e que RuntimeException e Error deveriam ser exclusivos da JVM.
  • 47. Quando lançar? THROW EARLY catch late Quanto mais informação houver no stack trace, melhor. Portanto ao invés de deixar exceções como NullpointerException acontecerem em locais pouco informativos, detecte o problema e lance a exceção onde se encontra o verdadeiro problema. public void readPreferences(String filename) throws IllegalArgumentException{ if (filename == null) { throw new IllegalArgumentException("filename is null"); } //if //...perform other operations... InputStream in = new FileInputStream(filename); //...read the preferences file... }
  • 48. Quando tratar? throw early CATCH LATE A exceção deve ser lançada o suficiente para que quem tem mais informação possa tratá-la. Um erro muito comum é tratar a exceção assim que ela acontece, impedindo que o sistema trate-a da maneira apropriada. Propague a exceção para quem pode tratá-la. public void readPreferences(String filename){ //... InputStream in = null; // NÂO FAÇA ISSO!!! try{ in = new FileInputStream(filename); }catch (FileNotFoundException e) { logger.log(e); return; } in.read(...); //... }
  • 49. Boas práticas Valide argumentos quando necessário Mas também não precisa fazer isso em todos os métodos! Valide os inputs nos métodos que já originaram bugs, assim você irá evitar que esses bugs ocorram novamente. if ( null == variable || variable.isEmpty()){ throw new NullPointerException("the variable cannot be null at this point"); }
  • 50. Boas práticas Evite grandes blocos de try catch Separe os try catch por escopo, assim o código fica mais fácil de entender e cada bloco irá pegas apenas as exceções pertinentes a tarefas pontuais. Considere dividi-los em métodos diferentes. try{ s = pegarNomeDoArquivo(); f = lerArquivo(s); v = validarArquivo(f); }catch(FileNotFoundException fne){ } try{ x = fazerParseDoArquivo(f); z = modificarXml() }catch(ParseException pe){ }
  • 51. Boas práticas Se não vai tratar, propague! Não faça catch em exceções apenas para encher log. O catch foi feito para tratar exceções e não para fazer log. Dessa forma você inpedirá que a exceção seja tratada por quem sabe como tratá-la. try{ s = pegarNomeDoArquivo(); f = lerArquivo(s); v = validarArquivo(f); }catch(Exception e){ log.error("Error ao ler arquivo", e); }
  • 52. Boas práticas Cuidado para não engulir exceções No bloco abaixo caso aconteça um FileNotFoundException veremos apenas um NullPointerException gerado pelo descuidado finally. O correto seria verificar se "input" é nulo no finally. InputStream input = null; try{ input = new FileInputStream("myFile.txt"); //do something with the stream } catch(IOException e){ throw new WrapperException(e); } finally { try{ input.close(); } catch(IOException e){ throw new WrapperException(e); } }
  • 53. Boas práticas Enriqueça as exceções lançadas Aproveite a propagação das exceções para enriquecê-las public void parseXml(String filePath) throws ParseException, IOException{ try{ File f = leArquivo(filePath); fazParse(f); }catch(IOException ioe){ throw new IOException("Parse falhou pois arquivo não existe {}", filePath, ioe); } } public File leArquivo(String filePath) throws IOException{ //Irá gerar uma exceção return new File(filePath); }
  • 54. Fique atento! No JAVA 7 haverá uma nova forma de tratar exceções Para evitar o uso do try catch dentro do finally o java 7 criou o try-with-resources. Assim qualquer classe que herde de java.lang.AutoCloseable é fechada pela java automaticamente no try catch Try-with-resources ANTIGO NOVO OldResource res = null; try { try(NewResource res = new NewResource("Res1 closing")){ res = new OldResource(); res.doSomeWork("Listening to podcast"); res.doSomeWork("Writing"); } catch(Exception e){ } catch (Exception e) { System.out.println("Exception"); System.out.println("Exception"); } } finally{ try { res.close(); } catch (Exception e) { System.out.println("Exception"); } }
  • 56. Referências ● http://architects.dzone.com/articles/high-performance-and-smarter ● http://www.javacodegeeks.com/2011/01/10-tips-proper-application-logging.html ● http://javarevisited.blogspot.com.br/2011/05/top-10-tips-on-logging-in-java.html ● http://www.allapplabs.com/log4j/log4j_appenders.htm ● http://logback.qos.ch/manual/appenders.html ● http://www.javaworld.com/javaworld/jw-05-2004/jw-0510-logging.html?page=3 ● http://c2.com/cgi/wiki?LoggingBestPractices ● https://wiki.base22.com/display/btg/Java+Logging+Standards+and+Guidelines ● http://runjva.appspot.com/logging101/index.html ● http://programmers.stackexchange.com/questions/112402/what-are-some-patterns-and-anti-patterns-of-application-logging ● http://gojko.net/2006/12/09/logging-anti-patterns/ ● http://today.java.net/article/2006/04/04/exception-handling-antipatterns ● http://www.wikijava.org/wiki/10_best_practices_with_Exceptions ● http://tutorials.jenkov.com/java-exception-handling/index.html ● http://www.javacodegeeks.com/2011/07/java-7-try-with-resources-explained.html