Logging adalah bagian penting dari semua aplikasi dan bermanfaat tidak hanya bagi kami, para pengembang, tetapi juga pengguna dan pengelola sistem. Aplikasi Spring Boot perlu mengumpulkan data log yang relevan untuk membantu kami mendiagnosis dan memperbaiki masalah serta mengukur kinerja bisnis.
Framework Spring Boot telah dikonfigurasikan sebelumnya menggunakan Logback sebagai implementasi default dalam pendekatan "kompeten" ke Spring Framework. Artikel ini membahas berbagai cara untuk mengkonfigurasi logging di Spring Boot.
Kode sampel
Artikel ini disertai dengan contoh kode yang berfungsi di GitHub .
Mengapa penjurnalan itu penting
Keputusan tentang apa dan di mana log sering kali bersifat strategis dan dibuat dengan asumsi bahwa aplikasi mungkin tidak berfungsi dengan benar di lingkungan dunia nyata. Log memainkan peran penting dalam membantu aplikasi pulih dengan cepat dari kerusakan seperti itu dan melanjutkan pengoperasian normal.
Membuat kesalahan pada titik integrasi terlihat
Sifat terdistribusi dari aplikasi saat ini yang dibangun menggunakan arsitektur layanan mikro memperkenalkan banyak hal. Dengan demikian, secara alami, Anda dapat mengalami masalah karena kegagalan sementara di salah satu sistem infrastruktur.
Log pengecualian yang direkam pada titik integrasi memungkinkan kami mengidentifikasi akar penyebab gangguan dan memungkinkan kami mengambil tindakan yang sesuai untuk memulihkan dengan dampak minimal pada pengalaman pengguna akhir.
Diagnosis kesalahan fungsional dalam sistem produksi
Mungkin ada keluhan pelanggan tentang jumlah transaksi yang salah. Untuk mendiagnosis ini, kita perlu menelusuri log untuk menemukan urutan operasi dari data permintaan saat API dipanggil ke data respons di akhir API pemrosesan.
Analisis riwayat peristiwa
. , .
, , , .
, , , , . 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);
}
}
Di artikel ini, kami telah melihat cara menggunakan logging di Spring Boot dan cara mengkonfigurasinya sesuai dengan persyaratan kami. Namun untuk memanfaatkan manfaat sepenuhnya, kapabilitas logging kerangka kerja perlu dilengkapi dengan praktik logging yang kuat dan terstandarisasi di seluruh tim pengembangan Anda.
Teknik ini juga perlu diterapkan melalui kombinasi tinjauan sejawat dan alat kontrol kualitas kode otomatis. Secara keseluruhan, ini memastikan bahwa ketika kesalahan produksi terjadi, kami memiliki informasi sebanyak mungkin untuk didiagnosis.
Anda dapat menemukan semua kode sumber yang digunakan dalam artikel di Github .