O que há com o registro em Java? [fechadas]


117

Por que um usaria um dos seguintes pacotes em vez do outro?

  • Java Logging
  • Commons Logging
  • Log4j
  • SLF4j
  • Logback

4
Você pode querer stackoverflow.com/questions/873051 , que compara SLF4j com Commons Logging.
James McMahon

24
Por que diabos Ceki criou 3 frameworks de log !!! isso é loucura ...
mP.

6
@mP. - log4j foi o primeiro, então surgiu um desacordo e slf4j + logback foi escrito. slf4j é a API e registra a implementação da API. Independentemente de tudo o mais, slf4j é extremamente útil.
Thorbjørn Ravn Andersen,

3
Para obter detalhes sobre por que Ceki Gülcü criou SLF4J + Logback, consulte a seguinte palestra da Devoxx
bitek

A melhor coisa a sair disso é a API slf4j que, esperançosamente, unificará o mundo de registro. Acho que o logback ainda não atingiu massa crítica com os desenvolvedores.
Thorbjørn Ravn Andersen

Respostas:


86

Em ordem cronológica de aparecimento de api (até onde eu sei):

  • Log4j porque quase todo mundo usa (na minha experiência)
  • Commons Logging porque os projetos de código aberto o usam (para que possam se integrar com qualquer estrutura de registro usada na solução integrada); especialmente válido se você for um API / Framework / OSS e confiar em outros pacotes que usam Commons Logging.
  • Commons Logging porque você não quer "bloquear" a uma estrutura de registro em particular (então, em vez disso, você bloqueia o que o Commons Logging oferece) - não acho que seja sensato decidir usando este ponto como o motivo.
  • Log de Java porque você não deseja adicionar um jar extra.
  • SLF4j porque é mais recente do que Commons Logging e fornece registro parametrizado:

logger.debug("The entry is {}.", entry);
//which expands effectively to
if (logger.isDebugEnabled()){
    // Note that it's actually *more* efficient than this - see Huxi's comment below...
    logger.debug("The entry is " + entry + "."); 
}
  • Logback porque é mais novo que log4j e, novamente, oferece suporte a registro parametrizado, uma vez que implementa SLF4j diretamente
  • SLF4j / Logback porque foi escrito pelo mesmo cara que fez o log4j, então ele o tornou melhor (de acordo com Ken G - obrigado. Parece que se encaixa quando olhamos suas postagens de notícias anteriores )
  • SLF4j porque eles também publicam um adaptador log4j para que você não precise "alternar" o log4j em um código antigo - apenas faça log4j.properties usar SLF4j e sua configuração

3
Pelo que eu posso dizer, a ideia por trás do log de commons é que ele deve ser usado em bibliotecas. Dessa forma, a biblioteca pode sempre usar a mesma estrutura de registro (por meio de registro comum) que o aplicativo de hospedagem usa.
Joachim Sauer

Muito obrigado a Loki pela pergunta. Agora sei que não vou mais usar log4j como meu framework padrão. SLF4j FTW! Também agradeço a Ken G por apontar que SLF4j foi escrito pelo mesmo cara que log4j
Stephen

3
O comentário em seu exemplo de código não está 100% correto. A formatação real da mensagem é realizada preguiçosamente pelo Logback, então só acontecerá se o evento for realmente manipulado por um appender e o appender exigir a mensagem formatada - o que não aconteceria no caso de, por exemplo, um SocketAppender, pois o evento é serializado usando o padrão de mensagem inalterado + os argumentos como Strings. Acho que depende apenas de como você define "efetivamente". Certamente emitiria a mesma mensagem (pelo menos se entrada e objeto forem iguais;)) então, por favor, perdoe minhas críticas.
Huxi

6
SLF4J, na verdade, é apenas uma API que se baseia em outras estruturas de registro. Semelhante ao objetivo do Commons Logging, mas mais intuitivo pela minha experiência.
James McMahon

37

Acho que o log em Java é confuso, inconsistente, mal documentado e especialmente aleatório. Além disso, há uma grande semelhança entre essas estruturas de registro, resultando em duplicação de esforços e confusão quanto ao ambiente de registro em que você está realmente múltiploambientes de registro de uma só vez; (por exemplo, o hibernate pode usar log4j e tomcat java.util.logging). O Apache commons destina-se a unir diferentes estruturas de registro, mas na verdade apenas adiciona mais complexidade. Se você não sabe disso com antecedência, é totalmente desconcertante. Por que minhas mensagens de log não são impressas no console, etc.? Ohh porque estou olhando os logs do Tomcat, e não o log4j. Adicionando ainda outra camada de complexidade, o servidor de aplicativos pode ter configurações de registro global que podem não reconhecer configurações locais para um aplicativo da web específico. Por fim, todas essas estruturas de registro são MUITO COMPLICADAS. Logar em Java tem sido uma bagunça desorganizada, deixando desenvolvedores como eu frustrados e confusos.

As primeiras versões do Java não tinham uma estrutura de registro integrada que levasse a esse cenário.


19
Isso é uma resposta? Parece mais um discurso retórico.
Michael Myers

15
Sinto muito. Ele é um pouco de um discurso retórico. Mas também é uma resposta convincente para "O que há com o Logging em Java?". A resposta, em resumo, é que está profundamente quebrado.
Julien Chastang

1
bem, não vale a pena um voto -1; P Mas algo para refletir sobre.
guyumu

21
Os problemas começaram quando a Sun realmente adicionou java.util.logging ao Java 1.4. Antes disso, o LOG4J estava bem estabelecido e amplamente utilizado. Depois disso, houve a necessidade de wrappers para suportar LOG4J e java.util.logging. Além disso, como jul está contido no pacote java. *, Ele não pode ser substituído trocando um JAR - que é a maneira como o SLF4J faz a ponte entre as outras estruturas. Essa foi provavelmente a pior ideia da Sun de todos os tempos ... e acabou levando à suposição errada de que um "bom cidadão Java" deveria usar jul.
Huxi

4
@Huxi, afirmo que a API do Calendário foi pior. Em defesa da Sun, não era o código deles, mas sim da Taglient.
Thorbjørn Ravn Andersen,

22

Há um ponto importante que não foi mencionado antes:

SLF4J (e ambos Logback e LOG4J como backend de registro) têm suporte para o chamado Contexto de Diagnóstico Mapeado (MDC, consulte javadoc e a documentação ).

Este é essencialmente um Map <String, String> thread-local que você pode usar para adicionar informações de contexto adicionais ao seu evento de registro. O estado atual do MDC é anexado a cada evento.

Isso pode ser extremamente útil se você inserir nele coisas como o nome de usuário e a URL da solicitação (no caso de um webapp). Isso pode ser feito automaticamente usando um filtro, por exemplo.


2
Tecnicamente, é um Map <String, String> thread local.
pdxleif


4

No projeto da nossa empresa usamos o LOG4j e é muito fácil de usar como o Stephen mostrou no seu exemplo. Também escrevemos nossas próprias classes de padrão para LOG4j para que você possa criar seus próprios esquemas de arquivo de saída. Você pode descrever como seu arquivo de log deve ser. É possível aprimorar as classes log4j originais.

Todas as propriedades do LOG4j podem ser alteradas em um arquivo log4j.properties, para que você possa usar arquivos diferentes para projetos diferentes.

O log Java não é meu favorito, mas isso pode ser porque eu uso o log4j desde o início.


4

A visão geral do Commons Logging fornece o motivo de sua existência: log do código da biblioteca, quando você não tem controle sobre a estrutura de log subjacente. Muito importante para os vários projetos Apache, que serão vinculados a aplicativos externos. Talvez não seja tão importante para projetos internos de TI, onde você tem controle total.

Dito isso, escrevo para Commons Logging, assim como muitos dos outros desenvolvedores que conheço. O motivo é minimizar a bagagem mental: você pode mudar de projeto ou trabalho e não precisa aprender uma nova estrutura (desde que o novo trabalho / projeto também use CL e / ou você possa convencê-los a mudar para ele).

Além disso, há algum valor em criar seus próprios wrappers em torno de qualquer estrutura que você usar. Conforme descrito aqui , gosto de usar um objeto LogWrapper para fornecer uma string customizada (importante) e minimizar a confusão visual de instruções de registro (menos importante).


1
Há também uma ponte commons.logging => SLF4J que pode ser usada para rotear todo o log de CL sobre SLF4J. SLF4J suporta ponte de commons.logging, LOG4J e (um pouco complicado, mas o melhor possível) java.util.logging, então todos os logs irão terminar em qualquer backend SLF4J que você usar. Consulte slf4j.org/legacy.html Eu usaria Logback, aliás, mas você pode argumentar que sou tendencioso.
Huxi

2

Geralmente eu usaria o padrão Log4J.

Eu usaria o Java Logging se não me importasse com a dependência do Java 1.4, mas ainda usaria o Log4J como preferência.

Eu usaria o Commons Logging se estivesse aprimorando algo que já o usasse.


Não se importou com uma dependência de 1.4 ?? Mesmo 1.4 chegou ao fim de sua vida útil.
Tom Hawtin - tackline

2
@Tom Ele significa jdk1.4 + não seja bobo.
mP.

Na verdade, recentemente fiz algum trabalho em um sistema que ainda estava em execução sob jdk 1.3 :-(, e foi há menos de dois anos, eu estava mantendo um sistema jdk 1.2 pela última vez . Muitos lugares não atualizam a menos que absolutamente tenham para, eles simplesmente se recusam a instalar as atualizações.
Michael Rutherfurd

0

Eu sugeriria a criação de uma fachada de registro fino que pode gravar em qualquer uma das estruturas de registro, ponto em que a escolha do mecanismo de apoio se torna praticamente um ponto discutível.


2
Isso é o que o registro comum faz, então por que reinventar a roda? Além disso, existem alguns problemas que sua fachada teria que lidar com o que o registro comum já faz.
James AN Stauffer

1 Para contrariar o argumento de registro comum, alguns aplicativos corporativos usam registrador personalizado. É sempre uma boa ideia ocultar a implementação subjacente. O invólucro 'fino' elimina a necessidade de outro frasco sendo embalado e não é tanto quanto reinventar.
questzen

1
Isso me salvou recentemente, quando portamos nosso framework para o Compact Framework (em .Net). Se tivéssemos dependências codificadas no nLog, estaríamos ferrados. Como usamos essa abordagem, conseguimos colocar um logger nulo e ficarmos felizes. Alguém vote em mim de volta para 0 Por favor :-)
tsimon

3
Já existe um - dê uma olhada em slf4j. É um thin wrapper aceito que permite alternar estruturas de registro na inicialização do aplicativo, alternando jars no classpath do tempo de execução.
deterb

1
o clogging tem sua própria maneira de descobrir qual framework usará - não é legal e é bastante complicado. Quantas estruturas de criação de log Ceki criou. Deve-se sempre se esforçar para definir um nível de interdirecção e ocultar uma implementação, mesmo que ela esteja obstruída com seu próprio registro. Nos bastidores, você pode inserir o plugin que quiser, conforme mencionado por Travis.
mP.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.