O registro é uma parte importante de todos os aplicativos e beneficia não apenas nós, os desenvolvedores, mas também os usuários e mantenedores do sistema. Os aplicativos Spring Boot precisam coletar dados de log relevantes para nos ajudar a diagnosticar e corrigir problemas e medir o desempenho dos negócios.
A estrutura Spring Boot é pré-configurada com Logback como a implementação padrão em sua abordagem "competente" para a Estrutura Spring. Este artigo explora várias maneiras de configurar o log no Spring Boot.
Código de amostra
Este artigo é acompanhado por um exemplo de código de trabalho no GitHub .
Por que o diário é importante
As decisões sobre o que e onde registrar são frequentemente estratégicas e são feitas com a suposição de que um aplicativo pode não funcionar corretamente em ambientes do mundo real. Os logs desempenham um papel fundamental em ajudar o aplicativo a se recuperar rapidamente de tais travamentos e a retomar a operação normal.
Cometer erros em pontos de integração visíveis
A natureza distribuída dos aplicativos de hoje construídos usando uma arquitetura de microsserviço apresenta muitas peças de trabalho. Assim, naturalmente, você pode ter problemas devido a falhas temporárias em qualquer um dos sistemas de infraestrutura.
Os logs de exceção registrados em pontos de integração nos permitem identificar a causa raiz de uma interrupção e nos permitem tomar as medidas adequadas para a recuperação com impacto mínimo na experiência do usuário final.
Diagnóstico de erros funcionais no sistema de produção
Pode haver reclamações de clientes sobre o valor incorreto da transação. Para diagnosticar isso, precisamos fazer uma busca detalhada em nossos logs para encontrar a sequência de operações dos dados de solicitação quando a API é chamada para os dados de resposta no final da API de processamento.
Análise do histórico de eventos
. , .
, , , .
, , , , . CI / CD.
Spring Boot
Spring Boot - Logback .
, Spring Boot. -, start.spring.io . :
@SpringBootApplication
public class SpringLoggerApplication {
static final Logger log =
LoggerFactory.getLogger(SpringLoggerApplication.class);
public static void main(String[] args) {
log.info("Before Starting application");
SpringApplication.run(SpringLoggerApplication.class, args);
log.debug("Starting my application in debug with {} args", args.length);
log.info("Starting my application with {} args.", args.length);
}
}Maven Gradle jar , :
13:21:45.673 [main] INFO io.pratik.springLogger.SpringLoggerApplication - Before Starting application
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.2.RELEASE)
.
.
.
... : Started SpringLoggerApplication in 3.054 seconds (JVM running for 3.726)
... : Starting my application 0, Spring, . .
application.properties( application.yml), .
. .
java -jar target/springLogger-0.0.1-SNAPSHOT.jar --trace, , , .
, , Spring. , log.level.<package-name>:
java \\
-jar target/springLogger-0.0.1-SNAPSHOT.jar \\
-Dlogging.level.org.springframework=ERROR \\
-Dlogging.level.io.pratik=TRACE application.properties:
logging.level.org.springframework=ERROR
logging.level.io.app=TRACE , logging.file.name logging.file.path application.properties. info.
# Output to a file named application.log.
logging.file.name=application.log# Output to a file named spring.log in path /Users
logging.file.path=/Users , logging.file.name .
, Spring 2.2 , . 2.3.2.RELEASE.
, logging.pattern.file:
# Logging pattern for file
logging.pattern.file= %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%, :
| , | |
|---|---|---|
|
| 10 Mb |
|
| 7 |
| . , . |
|
|
|
, .
Spring . , off application.properties:
spring.main.banner-mode=off ANSI, spring.output.ansi.enabled. : , .
spring.output.ansi.enabled=ALWAYS spring.output.ansi.enabled DETECT. , ANSI.
Logback Spring Boot . log4j java util, spring-boot-starter-loging pom.xml:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>logback-spring.xml
, logback.xml logback-spring.xml XML . Spring logback-spring.xml, logback-spring.groovy .
appender configuration. encoder:
<configuration >
<include
resource="/org/springframework/boot/logging/logback/base.xml" />
<appender name="STDOUT"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
</pattern>
</encoder>
</appender>
</configuration>Logback
debug configuration true, .
<configuration debug="true">, Logback, :
...- About to instantiate appender of type [...ConsoleAppender]
...- About to instantiate appender of type [...RollingFileAppender]
..SizeAndTimeBasedRollingPolicy.. - setting totalSizeCap to 0 Bytes
..SizeAndTimeBasedRollingPolicy.. - ..limited to [10 MB] each.
..SizeAndTimeBasedRollingPolicy.. Will use gz compression
..SizeAndTimeBasedRollingPolicy..use the pattern /var/folders/
..RootLoggerAction - Setting level of ROOT logger to INFO, , .
, logback-spring.xml. , .
. Spring Boot , . , Logstash:
<appender name="LOGSTASH"
class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>localhost:4560</destination>
<encoder charset="UTF-8"
class="net.logstash.logback.encoder.LogstashEncoder" />
</appender> LogstashEncoder JSON localhost:4560. .
Lombok
, : Lombok, Slf4j :
@Service
@Slf4j
public class UserService {
public String getUser(final String userID) {
log.info("Service: Fetching user with id {}", userID);
}
}Neste artigo, vimos como usar o log no Spring Boot e como configurá-lo de acordo com nossos requisitos. Mas para aproveitar ao máximo os benefícios, os recursos de registro da estrutura precisam ser complementados com práticas de registro robustas e padronizadas em suas equipes de desenvolvimento.
Essas técnicas também precisarão ser implementadas por meio de uma combinação de revisão por pares e ferramentas automatizadas de controle de qualidade de código. Em conjunto, isso garante que, quando ocorrerem erros de produção, tenhamos o máximo de informações possível para diagnosticar.
Você pode encontrar todo o código-fonte usado no artigo no Github .