CodeGym /Blogue Java /Random-PT /Java Logging
John Squirrels
Nível 41
San Francisco

Java Logging

Publicado no grupo Random-PT
Oi! Ao escrever as aulas, enfatizo particularmente se houver um tópico específico que será absolutamente essencial no trabalho real. Então, OUÇA! O tópico que abordaremos hoje certamente será útil em todos os seus projetos desde o primeiro dia de trabalho. Vamos falar sobre Java Logging. Este tópico não é nada complicado (eu diria até fácil). Mas você terá coisas óbvias o suficiente para se estressar em seu primeiro emprego, então é melhor entendê-lo completamente agora :) Bem, vamos começar.

O que é logar em Java?

Logging é o ato de registrar dados sobre a operação de um programa. O local onde registramos esses dados é chamado de "log". Duas perguntas surgem imediatamente: quais dados são gravados e onde? Vamos começar com o "onde". Você pode escrever dados sobre o trabalho de um programa em muitos lugares diferentes. Por exemplo, durante seus estudos, você frequentemente System.out.println()para enviar dados para o console. Isso é realmente log, embora em sua forma mais simples. Claro, isso não é muito conveniente para os usuários ou para a equipe de suporte do produto: obviamente, eles não vão querer instalar um IDE e monitorar o console :) Existe um formato mais comum para registrar informações: arquivos de texto. Os humanos se sentem muito mais confortáveis ​​lendo dados neste formato e certamente é muito mais conveniente para armazenar dados! Agora a segunda pergunta: quais dados do programa devem ser registrados? Isso é inteiramente com você! O sistema de log do Java é muito flexível. Você pode configurá-lo para registrar tudo o que seu programa faz. Por um lado, isso é bom. Mas, por outro lado, imagine o tamanho dos logs do Facebook ou do Twitter se eles escrevessem tudo neles. Essas grandes empresas provavelmente têm a capacidade de armazenar tantos dados. Mas imagine como seria difícil encontrar informações sobre um erro crítico em 500 gigabytes de logs de texto? Isso seria pior do que procurar uma agulha no palheiro. Da mesma forma, o Java pode ser configurado para registrar apenas dados de erro. Ou mesmo apenas erros críticos! Dito isso, não é totalmente correto falar do sistema de registro nativo do Java. O fato é que os programadores precisavam registrar antes que essa funcionalidade fosse adicionada ao idioma. Na época em que Java introduziu sua própria biblioteca de registro, todos já estavam usando a biblioteca log4j. O histórico de login em Java é realmente muito longo e informativo. Resumindo, o Java tem sua própria biblioteca de log, mas quase ninguém a usa :) Mais tarde, quando várias bibliotecas de registro diferentes apareceram e começaram a ser usadas por programadores, surgiram problemas de compatibilidade. Para impedir que as pessoas reinventem a roda em uma dúzia de bibliotecas diferentes com diferentes interfaces, a estrutura abstrata SLF4J ("Service Logging Facade For Java") foi criada. É chamado de abstrato, porque mesmo que você use e chame os métodos das classes SLF4J, sob o capô eles realmente usam todas as estruturas de registro que vieram antes: log4j, o java.util.logging padrão e outros. Se em algum momento você precisar de algum recurso específico do Log4j que falta em outras bibliotecas, mas não quiser vincular seu projeto diretamente a esta biblioteca, basta usar o SLF4J. E então deixe-o chamar os métodos Log4j. Se você mudar de ideia e decidir que não precisa mais dos recursos do Log4j, basta reconfigurar o "aqui , e a biblioteca Log4j aqui . Em seguida, descompacte o arquivo e use o IntelliJ IDEA para adicionar os arquivos JAR ao classpath. Itens de menu: Arquivo -> Estrutura do Projeto -> Bibliotecas Selecione os arquivos JAR necessários e adicione-os ao projeto (os arquivos que baixamos contêm muitos arquivos JAR - veja as fotos para ver os que você precisa) Observe que esta instrução para esses Por que precisamos de registro - 2Por que precisamos de registro - 3alunos que não sabem usar o Maven. Se você sabe como usar o Maven, geralmente é melhor (muito mais fácil) tentar começar por aí. Se você usa Maven , adicione esta dependência:

    	<dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.14.0</version>
    	</dependency>
Ótimo! Nós descobrimos as configurações :) Vamos ver como o SLF4J funciona. Como podemos garantir que o trabalho do programa seja gravado em algum lugar? Para fazer isso, precisamos de duas coisas: logger e appender. Vamos começar com o primeiro. Um registrador é um objeto que fornece controle total do registro. Criar um logger é muito fácil: fazemos isso usando os métodos estáticos LoggerFactory.getLogger() . O parâmetro do método é a classe cuja operação será registrada. Vamos executar nosso código:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("Test log entry!!!");
       LOGGER.error("An error occurred!");
   }
}
Saída do console:

ERROR StatusLogger No Log4j 2 configuration file found. Using default configuration (logging only errors to the console), or user programmatically provided configurations. Set system property 'log4j2.debug' to show Log4j 2 internal initialization logging. See https://logging.apache.org/log4j/2.x/manual/configuration.html for instructions on how to configure Log4j 2 15:49:08.907 [main] ERROR MyTestClass - An error occurred!
O que vemos aqui? Primeiro, vemos uma mensagem de erro. Isso é resultado do fato de que agora não temos as configurações necessárias. Consequentemente, nosso logger atualmente só é capaz de enviar mensagens de erro (ERROR) e apenas para o console. O método logger.info() não funcionou. Mas logger.error() sim! No console vemos a data atual, o método onde ocorreu o erro ( main), a palavra "ERRO" e nossa mensagem! ERROR é o nível de registro. Em geral, se uma entrada de registro estiver marcada com a palavra "ERROR", ocorreu um erro neste ponto do programa. Se a entrada estiver marcada com a palavra "INFO", a mensagem simplesmente representa informações atuais sobre a operação normal do programa. A biblioteca SLF4J tem muitos níveis de registro diferentes que permitem configurar o registro de forma flexível. É tudo muito fácil de gerenciar: toda a lógica necessária já está na classe Java Logger . Você só precisa chamar os métodos relevantes. Se você deseja registrar uma mensagem de rotina, chame o método logger.info() . Para uma mensagem de erro, use logger.error() . Para um aviso, use logger.warn()

Agora vamos falar sobre appender

Um anexador é o local para onde seus dados vão. De certa forma, o oposto de uma fonte de dados, ou seja, "ponto B". Por padrão, os dados são enviados para o console. Observe que no exemplo anterior não tivemos que configurar nada: o texto apareceu no console e o logger da biblioteca Log4j só pode enviar mensagens de nível ERROR para o console. Obviamente, é mais conveniente para as pessoas ler e gravar logs em um arquivo de texto. Para alterar o comportamento padrão do logger, precisamos configurar nosso anexador de arquivos. Para começar, você precisa criar um arquivo log4j.xml diretamente na pasta src. Você já está familiarizado com o formato XML: recentemente tivemos uma aula sobre ele :) Aqui está o conteúdo do arquivo:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
   <Appenders>
       <File name="MyFileAppender" fileName="C:\Users\Username\Desktop\testlog.txt" immediateFlush="false" append="false">
           <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </File>
   </Appenders>
   <Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
   </Loggers>
</Configuration>
Nada particularmente especial ou difícil aqui :) Mas ainda assim, vamos passar pelo conteúdo.
<Configuration status="INFO">
Este é o chamado StatusLogger. Não está relacionado ao nosso logger e é usado nos processos internos do Log4j. Se você definir status="TRACE" em vez de status="INFO", todas as informações sobre o trabalho interno do Log4j serão exibidas no console (StatusLogger exibe dados no console, mesmo que nosso anexador seja um arquivo). Não precisamos disso agora, então vamos deixar como está.

<Appenders>
   <File name="MyFileAppender" fileName="C:\Users\Evgeny\Desktop\testlog.txt" append="true">
       <PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
   </File>
</Appenders>
Aqui criamos nosso appender. A tag <File> indica que será um anexador de arquivo. name="MyFileAppender" define o nome do anexador. fileName="C:\Users\Username\Desktop\testlog.txt" indica o caminho para o arquivo de log onde todos os dados serão gravados. append="true" indica se os dados devem ser escritos no final do arquivo. No nosso caso, é exatamente isso que faremos. Se você definir o valor como falso, o conteúdo antigo do arquivo de log será excluído toda vez que o programa for iniciado. <PatternLayout pattern="%d{aaaa-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>indica as configurações de formatação. Aqui podemos usar expressões regulares para personalizar como o texto é formatado em nosso log.

<Loggers>
       <Root level="INFO">
           <AppenderRef ref="MyFileAppender"/>
       </Root>
</Loggers>
Aqui indicamos o nível raiz. Definimos o nível "INFO", o que significa que todas as mensagens cujos níveis forem superiores a INFO (conforme tabela que vimos acima) não serão registradas. Nosso programa terá 3 mensagens: uma INFO, uma WARN e uma ERROR. Com a configuração atual, todas as 3 mensagens serão registradas. Se você alterar o nível raiz para ERROR, apenas a última mensagem da chamada do método LOGGER.error() terminará no log. Além disso, uma referência ao appender também vai aqui. Para criar tal referência, você precisa criar uma tag <ApprenderRef> dentro da tag <Root> e adicionar o atributo ref='your appender's name' a ela. Caso você tenha esquecido, é aqui que definimos o nome do appender: <. E aqui está o nosso código!

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyTestClass {

   public static final Logger LOGGER = LoggerFactory.getLogger(MyTestClass.class);

   public static void main(String[] args) {

       LOGGER.info("The program is starting!!!");

       try {
           LOGGER.warn("Attention! The program is trying to divide a number by another.
           System.out.println(12/0);
       } catch (ArithmeticException x) {

           LOGGER.error("Error! Division by zero!");
       }
   }
}
É claro que é um pouco maluco (capturar uma RuntimeException é uma ideia questionável), mas é perfeito para nossos propósitos :) Vamos executar nosso método main() 4 vezes seguidas e examinar nosso arquivo testlog.txt. Você não precisa criá-lo com antecedência: a biblioteca fará isso automaticamente. Tudo funcionou! :) Agora você tem um logger configurado. Você pode brincar com alguns de seus programas antigos, adicionando chamadas de logger a cada método. Em seguida, observe o log resultante :) Ele considera o tópico de login em profundidade. Seria um desafio ler tudo de uma só vez. Dito isso, ele contém muitas informações úteis adicionais. Por exemplo, você aprenderá como configurar o logger para que ele crie um novo arquivo de texto se nosso arquivo testlog.txt atingir um determinado tamanho :) E isso conclui nossa aula! Hoje você se familiarizou com um tópico muito importante e esse conhecimento certamente será útil para você em seu trabalho futuro. Até a próxima vez! :)
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION