Um guia para anexar anexos de arquivos

Um guia para anexar anexos de arquivos

1. Visão geral

Embora os arquivos de log geralmente transmitam informações úteis, eles naturalmente aumentam com o tempo e, se puderem crescer indefinidamente, seu tamanho pode se tornar um problema.

As bibliotecas de registro resolvem esse problema usandorolling file appenders, which automatically “roll” or archive the current log file and resume logging in a new file quando certas condições predefinidas ocorrem, evitando assim o tempo de inatividade indesejado.

Neste artigo, exploraremos como configurar anexos de arquivos sem interrupção em algumas das bibliotecas de log mais usadas - Log4j, Log4j2 e Slf4j.

Mostraremos como rolar arquivos de log com base em tamanho, data / hora e uma combinação de tamanho e data / hora. Também demonstraremos como configurar cada biblioteca para compactar automaticamente e excluir mais tarde os arquivos de log antigos, poupando-nos de escrever códigos de manutenção tediosos.

2. Nosso aplicativo de amostra

Vamos começar com um aplicativo de exemplo que registra algumas mensagens. Esse código é baseado no Log4j, mas pode ser facilmente modificado para funcionar com o Log4j2 ou o Slf4j:

import org.apache.log4j.Logger;

public class Log4jRollingExample {

    private static Logger logger = Logger.getLogger(Log4jRollingExample.class);

    public static void main(String[] args) throws InterruptedException {
        for(int i = 0; i < 2000; i++) {
            logger.info("This is the " + i + " time I say 'Hello World'.");
            Thread.sleep(100);
        }
    }
}

O aplicativo é bastante ingênuo - ele grava algumas mensagens em um loop, com um pequeno atraso entre as iterações. Com 2.000 loops para executar e uma pausa de 100 ms em cada loop, o aplicativo deve demorar um pouco mais de três minutos para ser concluído.

Usaremos este exemplo para demonstrar vários recursos de diferentes tipos de anexadores de arquivo contínuo.

3. Anexadores de arquivo em movimento no Log4j

3.1. Dependências do Maven

Em primeiro lugar, para usar Log4j em seu aplicativo, adicione esta dependência ao arquivopom.xml do seu projeto:


    log4j
    log4j
    1.2.17

Para usar os anexadores adicionais fornecidos porapache-log-extras que usaremos nos próximos exemplos, adicione a seguinte dependência, certificando-se de usar a mesma versão que declaramos para Log4j a fim de garantir total compatibilidade:


    log4j
    apache-log4j-extras
    1.2.17

Você pode encontrar a versão mais recente deLog4jeApache Log4j Extras no Maven Central.

3.2. Rolagem com base no tamanho do arquivo

No Log4j, como nas outras bibliotecas de log, o rolamento de arquivos é delegado ao appender. Vejamos a configuração de um appender de arquivo contínuo no Log4j que rola com base no tamanho do arquivo:


    
    
    
        
            
        

Aqui, configuramos o Log4j para rolar o arquivo de log quando seu tamanho atingir 5 KB, usando o parâmetroMaxFileSize. Também instruímos Log4j a manter um máximo de dois arquivos de log rolados usando o parâmetroMaxBackupIndex.

Quando executamos nosso aplicativo de amostra, obtivemos os seguintes arquivos:

27/11/2016  10:28    138 app.log
27/11/2016  10:28  5.281 app.log.1
27/11/2016  10:28  5.281 app.log.2

O que aconteceu? Log4j começou a gravar no arquivoapp.log. Quando o tamanho do arquivo excedeu o limite de 5 KB, Log4j moveuapp.log paraapp.log.1, criou um novoapp.log vazio e continuou gravando novas mensagens de log emapp.log.

Então, depois que o novoapp.log excedeu o limite de 5 KB, esse processo de rolagem foi repetido. Desta vez,app.log.1 foi movido paraapp.log.2, abrindo espaço para outro novoapp.log vazio.

O processo de rolagem foi repetido várias vezes durante a execução, mas como configuramos nosso anexador para manter no máximo dois arquivos rolados, não há nenhum arquivo chamadoapp.log.3.

Portanto, resolvemos um dos problemas originais porque agora podemos definir um limite para o tamanho dos arquivos de log produzidos.

Por outro lado, quando verificamos a primeira linha deapp.log.2, ela continha a mensagem relacionada à 700ª iteração, o que significa que todas as mensagens de log anteriores foram perdidas:

2016-11-27 10:28:34 INFO  This is the 700 time I say 'Hello World'.

Vamos ver se podemos chegar a uma configuração mais adequada para um ambiente de produção, onde perder mensagens de log não pode ser considerada a melhor abordagem.

Para fazer isso, usaremos outros anexadores Log4j mais poderosos, flexíveis e configuráveis ​​que são enviados em um pacote dedicado chamadoapache-log4j-extras.

Os apêndices contidos neste artefato oferecem muitas opções para ajustar a rolagem do log e apresentam os conceitos distintos detriggering policyerolling policy. Otriggering policy descreve quando uma rolagem deve ocorrer, enquanto orolling policy descreve como a rolagem deve ser realizada. Esses dois conceitos são fundamentais para rolar os arquivos de log e também são usados ​​mais ou menos explicitamente por outras bibliotecas, como veremos em breve.

3.3. Rolando com Compressão Automática

Vamos voltar ao exemplo Log4j e melhorar nossa configuração adicionando a compactação automática dos arquivos rolados para economizar espaço:


    
        
        
    
    
    
    
        
    
    
        
    

Com o elementotriggering policy, afirmamos que a rolagem deve ocorrer quando o log exceder o tamanho de 5.120 bytes.

Dentro da tagrolling policy,, o parâmetroActiveFileName indica o caminho dos arquivos de log principais contendo as mensagens mais recentes e o parâmetroFileNamePattern especifica um modelo que descreve qual deve ser o caminho de os arquivos rolados. Notemos que este é realmente um padrão porque o marcador especial%i será substituído pelo índice do arquivo rolado.

Notemos também queFileNamePattern termina com uma extensão “.gz”. Sempre que usarmos uma extensão associada a um formato compactado suportado, os arquivos compactados antigos serão compactados sem nenhum esforço extra do nosso lado.

Agora, quando executamos o aplicativo, obtemos um conjunto diferente de arquivos de log:

03/12/2016 19:24 88 app.1.log.gz
...
03/12/2016 19:26 88 app.2.log.gz
03/12/2016 19:26 88 app.3.log.gz
03/12/2016 19:27 70 app.current.log

O arquivoapp.current.log é onde ocorreram os últimos logs. Os logs anteriores foram rolados e compactados quando seu tamanho atingiu o limite definido.

3.4. Rolando com base na data e hora

Em outros cenários, convém configurar o Log4j para rolar os arquivos com base na data e hora das mensagens de log, em vez do tamanho do arquivo. Em um aplicativo Web, por exemplo, convém que todas as mensagens de log sejam emitidas em um dia no mesmo arquivo de log.

Para fazer isso, você pode usarTimeBasedRollingPolicy. Com essa política, é obrigatório especificar um modelo para o caminho do arquivo de log que contém um espaço reservado relacionado ao tempo. Sempre que uma mensagem de log é emitida, o appender verifica qual seria o caminho de log resultante e, se diferir do último caminho usado, ocorrerá um roll. Aqui está um exemplo rápido que configura tal anexador:


    
        
    
    
        
    

3.5. Rolamento com base no tamanho e tempo

CombinandoSizeBasedTriggeringPolicyeTimeBasedRollingPolicy,, você pode obter um anexador que rola com base na data / hora e, quando o tamanho do arquivo atinge o limite definido, rola com base no tamanho também:


    
        
        
    
    
        
    
    
        
    

Quando executamos nosso aplicativo com essa configuração, obtivemos os seguintes arquivos de log:

03/12/2016 19:25 234 app.19-25.1481393432120.log.gz
03/12/2016 19:25 234 app.19-25.1481393438939.log.gz
03/12/2016 19:26 244 app.19-26.1481393441940.log.gz
03/12/2016 19:26 240 app.19-26.1481393449152.log.gz
03/12/2016 19:26 3.528 app.19-26.1481393470902.log

O arquivoapp.19-26.1481393470902.log é onde o registro atual ocorre. Como você pode ver, todos os logs no intervalo entre 19:25 e 19:26 são armazenados em vários arquivos de log compactados com nomes começando com “app.19-25″. O espaço reservado“%i” é substituído por um número cada vez maior .

4. Anexadores de arquivo móveis em Log4j2

4.1. Dependências do Maven

Para usar Log4j2 como nossa biblioteca de registro preferencial, precisamos atualizar o POM do nosso projeto com a seguinte dependência:


    org.apache.logging.log4j
    log4j-core
    2.7

Como de costume, você pode encontrarlatest version no Maven Central.

4.2. Rolagem com base no tamanho do arquivo

Vamos mudar nosso aplicativo de exemplo para usar as bibliotecas de registro Log4j2 e vamos explorar agora como podemos configurar a rolagem de arquivo com base no tamanho do arquivo de registro no arquivo de configuraçãolog4j2.xml:


    
        %d{yyyy-MM-dd HH:mm:ss} %p %m%n
    
    
        
        
    

Na tagPolicies, especificamos todas as políticas de acionamento que desejamos aplicar. OnStartupTriggeringPolicy dispara uma rolagem toda vez que o aplicativo é iniciado, o que pode ser útil para aplicativos independentes. Em seguida, especificamos umSizeBasedTriggeringPolicy informando que uma rolagem deve ocorrer sempre que o arquivo de log atingir 5 KB.

4.3. Rolando com base na data e hora

Usando as políticas oferecidas pelo Log4j2, vamos configurar um appender para rolar e compactar o arquivo de log com base no tempo:


    
        %d{yyyy-MM-dd HH:mm:ss} %p %m%n
    
    

Aqui, a chave é o uso deTimeBasedTriggeringPolicy que nos permite usar marcadores de posição relacionados ao tempo no modelo dos nomes de arquivo rolados. Observe que, como precisávamos apenas de uma única política de acionamento, não precisamos usar a tagPolicies como fizemos no exemplo anterior.

4.4. Rolamento com base no tamanho e tempo

Como descrito anteriormente, um cenário mais atraente é rolar e compactar arquivos de log com base no tempo e no tamanho. Aqui está um exemplo de como podemos configurar o Log4j2 para esta tarefa:


    
        %d{yyyy-MM-dd HH:mm:ss} %p %m%n
    
    
        
        
        
    
    
        
            
            
        
    

Com essa configuração, afirmamos que um rolo deve ocorrer com base no tempo e no tamanho. O appender é capaz de entender a que intervalo de tempo estamos nos referindo por causa do padrão usado para o nome do arquivo, “app.%d{MM-dd-yyyy-HH-mm}.%i.log.gz”, que implicitamente configura uma rolagem para ocorrer a cada minuto e compacta o arquivo rolado.

Também adicionamos umDefaultRolloverStrategy para excluir os arquivos antigos que correspondem a certos critérios. Configuramos o nosso para excluir arquivos que correspondam ao padrão especificado quando tiverem mais de 20 dias.

4.5. Dependências do Maven

Para usar Log4j2 como nossa biblioteca de registro preferencial, precisamos atualizar o POM do nosso projeto com a seguinte dependência:


    org.apache.logging.log4j
    log4j-core
    2.7

Como de costume, você pode encontrarlatest version no Maven Central.

5. Anexadores de arquivo em movimento no Slf4j

5.1. Dependências do Maven

Quando você quiser usar o Slf4j2 com um back-end Logback como bibliotecas de registro, adicione esta dependência ao seupom.xml:


    ch.qos.logback
    logback-classic
    1.1.7

Como de costume, você pode encontrarlatest version no Maven Central.

5.2. Rolagem com base no tamanho do arquivo

Vamos ver agora como usar o Slf4j, com seu back-end padrãoLogback. Vamos explorar como podemos configurar o rol de arquivos no arquivo de configuraçãologback.xml, que é colocado no classpath do aplicativo:


    target/slf4j/roll-by-size/app.log
    
        target/slf4j/roll-by-size/app.%i.log.zip
        1
        3
        1MB
    
    
       5KB
    
    
        %-4relative [%thread] %-5level %logger{35} - %msg%n
    

Mais uma vez, encontramos o conceito de política rotativa. O mecanismo básico é o mesmo usado pelo Log4j e pelo Log4j2. OFixedWindowRollingPolicy nos permite usar um marcador de posição de índice no padrão de nome do arquivo rolado.

Quando o tamanho do arquivo de log cresce acima do limite configurado, um novo arquivo é alocado e o conteúdo antigo é armazenado como o primeiro arquivo da lista, deslocando os existentes para outro local.

5.3. Rolando com base no tempo

No Slf4j, podemos rolar um arquivo de log com base no tempo usando oTimeBasedRollingPolicy fornecido. Essa política nos permite especificar o nome do modelo do arquivo contínuo usando espaços reservados relacionados a data e hora:


    target/slf4j/roll-by-time/app.log
    
        target/slf4j/roll-by-time/app.%d{yyyy-MM-dd-HH-mm}.log.zip
        
        20
        1MB
    
    
        %d{yyyy-MM-dd HH:mm:ss} %p %m%n
    

5.4. Rolamento com base no tamanho e tempo

Se precisar rolar um arquivo com base no tempo e no tamanho, você pode usar oSizeAndTimeBasedRollingPolicy fornecido. Ao usar esta política, você deve especificar um espaço reservado relacionado ao tempo e um espaço reservado ao índice.

Cada vez que o tamanho do arquivo de log para um determinado intervalo de tempo aumenta além do limite de tamanho configurado, outro arquivo de log com o mesmo valor para o espaço reservado relacionado ao tempo, mas com um índice incrementado, é criado:


    target/slf4j/roll-by-time-and-size/app.log
    
        
            target/slf4j/roll-by-time-and-size/app.%d{yyyy-MM-dd-mm}.%i.log.zip
        
        5KB
        20
        1MB
    
    
        %d{yyyy-MM-dd HH:mm:ss} %p %m%n
    

6. Conclusão

Como vimos, aproveitar uma biblioteca de registro para rolar os arquivos evita o ônus de gerenciar os arquivos de registro manualmente, permitindo que você se concentre no desenvolvimento de sua lógica de negócios. Anexadores de arquivos móveis são uma ferramenta valiosa que deve estar na caixa de ferramentas de todo desenvolvedor.

Como de costume, você encontrará as fonteson GitHub, onde os aplicativos de exemplo apresentados neste artigo são configurados para registrar usando várias configurações contínuas diferentes, a fim de permitir que você encontre uma boa configuração de base para ser ajustada para atender a necessidades.