Os JavaDocs para ojava.util.logging.Level
estado:
Os níveis em ordem decrescente são:
SEVERE
(valor mais alto)WARNING
INFO
CONFIG
FINE
FINER
FINEST
(valor mais baixo)
Fonte
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
logger.setLevel(Level.FINER);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
Resultado
Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevelsBlunder main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevelsBlunder main
INFO: 2 4
Press any key to continue . . .
Declaração do problema
Meu exemplo define o Level
como FINER
, portanto, esperava ver 2 mensagens para cada loop. Em vez disso, vejo uma única mensagem para cada loop (as Level.FINE
mensagens estão faltando).
Questão
O que precisa ser alterado para ver a saída FINE
( FINER
ou FINEST
)?
Atualizar (solução)
Graças à resposta de Vineet Reynolds , essa versão funciona de acordo com minha expectativa. Ele exibe 3 x INFO
mensagens e 3 x FINE
mensagens.
import java.util.logging.*;
class LoggingLevelsBlunder {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
// LOG this level to the log
logger.setLevel(Level.FINER);
ConsoleHandler handler = new ConsoleHandler();
// PUBLISH this level
handler.setLevel(Level.FINER);
logger.addHandler(handler);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
java
logging
java.util.logging
Andrew Thompson
fonte
fonte
Respostas:
Os loggers apenas registram a mensagem, ou seja, eles criam os registros de log (ou solicitações de log). Eles não publicam as mensagens nos destinos, que são tratados pelos Manipuladores. Definir o nível de um registrador só faz com que ele crie registros de log correspondentes a esse nível ou superior.
Você pode estar usando um
ConsoleHandler
(não consegui inferir onde sua saída é System.err ou um arquivo, mas presumo que seja o primeiro), cujo padrão é a publicação de registros de log do nívelLevel.INFO
. Você terá que configurar este manipulador, para publicar registros de log de nívelLevel.FINER
e superior, para o resultado desejado.Eu recomendaria ler o guia Java Logging Overview , a fim de entender o design subjacente. O guia cobre a diferença entre o conceito de Logger e Handler.
Editando o nível do manipulador
1. Usando o arquivo de configuração
O arquivo de propriedades java.util.logging (por padrão, este é o
logging.properties
arquivoJRE_HOME/lib
) pode ser modificado para alterar o nível padrão do ConsoleHandler:2. Criação de manipuladores em tempo de execução
Isso não é recomendado, pois resultaria na substituição da configuração global. Usar isso em toda a sua base de código resultará em uma configuração de logger possivelmente não gerenciável.
fonte
Handler
.Logger.getGlobal().getParent().getHandlers()[0].setLevel(Level.FINER);
O porque
java.util.logging tem um logger root cujo padrão é
Level.INFO
e um ConsoleHandler anexado a ele que também assume o padrãoLevel.INFO
.FINE
é menor queINFO
, portanto, as mensagens finas não são exibidas por padrão.Solução 1
Crie um logger para toda a sua aplicação, por exemplo, a partir do nome do seu pacote ou uso
Logger.getGlobal()
, e conecte seu próprio ConsoleLogger a ele. Em seguida, peça ao logger root para desligar (para evitar saída duplicada de mensagens de nível superior) ou peça ao logger para não encaminhar os logs para o root.Solução 2
Alternativamente, você pode diminuir a barra do logger root.
Você pode defini-los por código:
Ou com o arquivo de configuração de registro, se você o estiver usando :
Ao diminuir o nível global, você pode começar a ver mensagens de bibliotecas centrais, como de alguns componentes Swing ou JavaFX. Nesse caso, você pode definir um Filtro no logger raiz para filtrar mensagens que não são do seu programa.
fonte
por que meu log de java não está funcionando
fornece um arquivo jar que o ajudará a descobrir por que seu login não está funcionando conforme o esperado. Ele fornece um dump completo de quais loggers e manipuladores foram instalados e quais níveis estão definidos e em que nível na hierarquia de log.
fonte
PORQUE
Conforme mencionado por @Sheepy, a razão pela qual não funciona é que
java.util.logging.Logger
tem um logger root que tem como padrãoLevel.INFO
, e oConsoleHandler
anexado a esse logger root também tem como padrãoLevel.INFO
. Portanto, para ver a saídaFINE
(FINER
ouFINEST
), você precisa definir o valor padrão do logger raiz e seuConsoleHandler
daLevel.FINE
seguinte maneira:O problema da sua atualização (solução)
Conforme mencionado por @mins, você terá as mensagens impressas duas vezes no console para
INFO
e acima: primeiro pelo logger anônimo, depois por seu pai, o logger root que também tem umConsoleHandler
definido comoINFO
por padrão. Para desativar o logger raiz, você precisa adicionar esta linha de código:logger.setUseParentHandlers(false);
Existem outras maneiras de evitar que os logs sejam processados pelo gerenciador de console padrão do logger raiz mencionado por @Sheepy, por exemplo:
Mas
Logger.getLogger("").setLevel( Level.OFF );
não funcionará porque apenas bloqueia a mensagem passada diretamente para o logger root, e não a mensagem que vem de um logger filho. Para ilustrar comoLogger Hierarchy
funciona, desenho o seguinte diagrama:public void setLevel(Level newLevel)
definir o nível de log especificando quais níveis de mensagem serão registrados por este logger. Níveis de mensagem inferiores a esse valor serão descartados. O valor de nível Level.OFF pode ser usado para desligar o registro. Se o novo nível for nulo, significa que este nó deve herdar seu nível de seu ancestral mais próximo com um valor de nível específico (não nulo).fonte
Eu encontrei meu problema real e não foi mencionado em nenhuma resposta: alguns dos meus testes de unidade estavam fazendo com que o código de inicialização de log fosse executado várias vezes no mesmo conjunto de testes, bagunçando o log nos testes posteriores.
fonte
Tentei outras variantes, isso pode ser adequado
fonte
Esta solução me parece melhor, em relação à manutenção e design para mudanças:
Crie o arquivo de propriedade de registro incorporando-o na pasta do projeto de recursos, para ser incluído no arquivo jar:
Carregue o arquivo de propriedade do código:
fonte