O documento discute boas práticas e anti-padrões para registro de logs em aplicações, enfatizando a importância de logs claros e legíveis para desenvolvedores e outros usuários. Sugere padronizar formatos de logs e evitar registros excessivos ou de difícil interpretação.
2. Pattern
"Patterns are formalized best practices that the programmer must implement
themselves in the application."
Introduction to Spring Framework (Acesso em: 25/09/2013)
http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/overview.html
Anti-Patterns
"Design anti-patterns are 'obvious, but wrong, solutions to recurring problems'."
Budgen, D. (2003). Software design. Harlow, Eng.: Addison-Wesley. p. 225. ISBN 0-20172219-4.
"...common approaches to solving recurring problems that prove to be ineffective. These
approaches are called antipatterns."
Scott W. Ambler (1998). Process patterns: building large-scale systems using object
technology. Cambridge, UK: Cambridge University Press. p. 4. ISBN 0-521-64568-9.
3.
Error - Usado quando o processo não pode continuar. Considerados intoleráveis
pelo sistema.
Warn - Para eventos críticos, porem onde o processo pode continuar mas com
cuidados extras.
Null Pointer Exception
Banco de Dados indisponível
Falha com conexão remota
Utilizando cache por falta de conexão
Em modo administrador
Usuário sem senha.
Info - Deve permitir que administrador ou usuários avançados entendam
rapidamente o que a aplicação esta fazendo ou acabou de fazer.
Caixa de supermercado. "Caixa NºX" fechou uma compra no valor "R$Y“.
[Fulano] comprou uma passagem de [lugar X] para [lugar Y]
4.
Debug - Elementos referentes a desenvolvimento, mas que podem ser
relevantes quando.
Valores recebidos ao entrar em um método
Valor de saída do método
Mudança de valor de variável
Trace - Informações detalhadas para o desenvolvedor. Recomendado utilizar
somente fora do ambiente de produção.
Valores de variável em determinados pontos
Log apenas para saber se tal linha executou
5.
Informações legíveis para meros mortais
entenderem o que se passa.
Anti-Pattern
log.debug(“Classe Beta1 lançou exceção 0x55”);
Pattern
log.debug(“Classe UsuárioDAO lançou exceção senhaException”);
6.
Não há necessidade de verificar se determinado
nível esta habilitado, o framework já faz isso.
Utilize apenas em conjunto com ‘else’, caso haja
a necessidade de sempre registrar algo.
Anti-Pattern
if(log.isDebugEnabled())
log.debug(“Cliente registrado com sucesso.”);
Pattern
if(log.isDebugEnabled())
log.debug(“Itens no checkout: {}”, compra.getItens());
else
log.info(“Nº de Itens no checkout: {}”, compra.getItens().size());
Ver Ex.
7.
Certifique-se de não tentar registrar em seu
log um Null Pointer Exception
Pattern
log.debug("Cliente com sobrenome: {}", cliente.getSobrenome());
8.
Utilize sempre em um único log, informação
e valor
Anti-Pattern
log.debug(“Cliente registrado com sucesso.”);
log.debug(cliente.getId());
Pattern
log.debug(“Cliente registrado com sucesso: {}”, cliente.getId());
Ver Ex.
9.
Registre informações fáceis para humano e
máquina lerem seus logs.
O separador utilizado também é importante
para facilitar o trabalho de um parser. Prefira
utilizar vírgulas ou tabs para separar valores
no log.
Evite utilizar mais de uma linha em um log.
Pattern
log.debug(“Horário requisitado: {} ({})", new Date(ttl), ttl);
// Horário requisitado: Wed Apr 28 20:14:12 CEST 2010 (1272478452437)
10.
Defina um padrão para seus logs
(Ex: data, level, thread, nome, mensagem)
Pattern
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} %-5level [%thread][%logger{0}] %m%n</pattern>
</encoder>
</appender>
Exemplo de definição de padrão no LogBack.
Ver Ex.
11.
Registrar parâmetros recebidos e valor de
retorno para métodos importantes.
Pattern
public String fazerAlgo(String a, int b, double c){
log.debug("iniciando fazerAlgo com a={}, b={} e c={}, a, b, c);
//processa várias coisas
log.debug("saindo de fazerAlgo com {}", resultado);
}
12.
Caso sua exceção não faça o tratamento e
apenas relançe aquela exceção, fazer log
pode resultar em stackTrace duplicado.
Anti-Pattern
}catch (Exception e){
log.error("IO exception", e);
throw new MyCustomException(e);
}
Ver Ex.
13.
Não instanciar logger passando a classe como
String.
Anti-Pattern
private final static Logger LOGGER = LoggerFactory.getLogger("com.ess.Usuario");
Pattern
private final static Logger LOGGER = LoggerFactory.getLogger(Usuario.class);
14.
Não instanciar o logger dentro de cada método,
crie uma instancia somente para a classe toda.
Anti-Pattern
public void metodo() {
Logger logger = LoggerFactory.getLogger(Foo.class);
logger.info(“ok!");
}
Pattern
private final static Logger LOGGER = LoggerFactory.getLogger(Vai.class);
public void metodo() {
LOGGER.info(“ok");
}
15.
Interagir com sistemas externos pode resultar
num objeto de tamanho inesperado. Quando
em produção evitar logs excessivos.
Pattern
Collection< Usuario> usuarios = //...
if(log.isDebugEnabled())
log.debug(“Usuários: {}", usuarios );
else
log.info(" Usuários size: {}", usuarios.size());
Ver Ex.
16.
Registre todo o stacktrace ao fazer um log
dentro de uma excessão.
Anti-Pattern
} catch (Exception e) {
LOGGER.error(“Algo errado occurreu.");
// ou: LOGGER.error(e.getMessage());
}
Pattern
} catch (Exception e) {
LOGGER.error(" Algo errado occurreu.", e);
// ou: LOGGER.error(e.getMessage(), e);
}
17.
Camada abstrata de log é diferente de framework de
log, um framework normalmente implementa uma
camada abstrata de log.
Certifique-se fazer os import da camada abstrata, pois
caso precise trocar de framework não será preciso
modificar o código, basta substituir os arquivos jar.
Anti-Pattern
import com.logback.Logger;
import com.logback.LoggerFactory;
Pattern
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
18.
Além de questões de armazenamento de
transferência de arquivos enormes, diferentes
usuários possuem diferentes necessidades,
principalmente em questões temporais.
Suporte pode trabalhar melhor com logs semanais.
Marketing poderia preferir logs diários para decisões
estratégicas ágeis.
Contabilidade prefere manter logs anuais.
Setor financeiro trabalha melhor com registros mensais.