青春期13分钟床戏被删减片段_看性生活片_在线看黄的网站_护士日本乳挤奶水_免费黄色录像片_啊啊啊好大好深_亚洲91在线视频_91污秽视频_欧美高清精品_亚洲国产精品肉丝袜久久

行業(yè)動態(tài)

了解最新公司動態(tài)及行業(yè)資訊

當前位置:首頁>新聞中心>行業(yè)動態(tài)
全部 1755 公司動態(tài) 599 行業(yè)動態(tài) 608

難以置信(springboot日志yml)springboot日志管理界面,Spring Boot日志配置與管理:從入門到精通,日志管理,

時間:2025-05-07   訪問量:1010

1. 日志基礎概念

1.1 什么是日志

日志是應用程序運行時記錄的事件、狀態(tài)和信息的集合,用于跟蹤應用程序的運行狀況、調(diào)試問題和監(jiān)控系統(tǒng)行為。

通俗理解:就像飛機的黑匣子,記錄著系統(tǒng)運行的所有關鍵信息,當出現(xiàn)問題時可以回放查看。

1.2 為什么需要日志管理

需求

說明

日常生活類比

問題診斷

當系統(tǒng)出現(xiàn)問題時快速定位

像醫(yī)院的病歷記錄

性能監(jiān)控

跟蹤系統(tǒng)性能指標

汽車的儀表盤

安全審計

記錄關鍵操作以備審查

銀行的交易記錄

行為分析

分析用戶行為模式

超市的購物小票

1.3 Java常見日志框架對比

框架

特點

適用場景

Spring Boot默認支持

Log4j

老牌日志框架,配置靈活

傳統(tǒng)Java項目

是(1.x)

Log4j2

Log4j升級版,性能更好

高性能需求項目

Logback

SLF4J原生實現(xiàn),性能好

Spring Boot默認

JUL (java.util.logging)

JDK自帶,功能簡單

簡單應用

2. Spring Boot日志基礎

2.1 默認日志配置

Spring Boot默認使用Logback作為日志框架,并通過spring-boot-starter-logging自動配置。

簡單使用示例

import org.slf4j.Logger; import org.slf4j.LoggerFactory; @RestController public class MyController { // 獲取Logger實例(通常在每個類中聲明) private static final Logger logger = LoggerFactory.getLogger(MyController.class); @GetMapping("/hello") public String hello() { logger.trace("This is a TRACE message"); logger.debug("This is a DEBUG message"); logger.info("This is an INFO message"); // 最常用 logger.warn("This is a WARN message"); logger.error("This is an ERROR message"); return "Hello World"; } }

2.2 日志級別詳解

級別

數(shù)值

說明

使用場景

TRACE

0

最詳細的跟蹤信息

開發(fā)階段深度調(diào)試

DEBUG

1

調(diào)試信息

開發(fā)階段問題排查

INFO

2

運行重要信息

生產(chǎn)環(huán)境常規(guī)監(jiān)控

WARN

3

潛在問題警告

需要注意但不緊急的問題

ERROR

4

錯誤事件但不影響系統(tǒng)

需要關注的問題

FATAL

5

嚴重錯誤導致系統(tǒng)退出

極少使用

通俗理解:就像醫(yī)院的分診系統(tǒng),TRACE是全面體檢,DEBUG是??茩z查,INFO是常規(guī)體檢,WARN是輕微癥狀,ERROR是需要立即處理的病癥。

3. 日志配置詳解

3.1 配置文件格式

Spring Boot支持以下格式的日志配置文件:

logback-spring.xml (推薦)logback.xmlapplication.properties/application.yml中的簡單配置

3.2 application.properties配置

# 設置全局日志級別 logging.level.root=WARN # 設置特定包日志級別 logging.level.com.myapp=DEBUG # 文件輸出配置 logging.file.name=myapp.log # 或者使用logging.file.path指定目錄 logging.file.path=/var/logs # 日志格式配置 logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n logging.pattern.file=%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n # 日志文件大小限制和保留策略 logging.logback.rollingpolicy.max-file-size=10MB logging.logback.rollingpolicy.max-history=7

3.3 logback-spring.xml詳細配置

<?xml version="1.0" encoding="UTF-8"?> <configuration scan="true" scanPeriod="30 seconds"> <!-- 定義變量 --> <property name="LOG_PATH" value="./logs" /> <property name="APP_NAME" value="my-application" /> <!-- 控制臺輸出appender --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 文件輸出appender --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_PATH}/${APP_NAME}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_PATH}/${APP_NAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>10MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>1GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 異步日志appender --> <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>512</queueSize> <discardingThreshold>0</discardingThreshold> <appender-ref ref="FILE" /> </appender> <!-- 日志級別配置 --> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="ASYNC_FILE" /> </root> <!-- 特定包日志級別 --> <logger name="com.myapp" level="DEBUG" /> <logger name="org.springframework" level="WARN" /> <!-- 環(huán)境特定配置 --> <springProfile name="dev"> <logger name="com.myapp" level="TRACE" /> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> </root> </springProfile> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="ASYNC_FILE" /> </root> </springProfile> </configuration>

3.4 配置項詳細解析

3.4.1 Appender類型

Appender類型

作用

適用場景

ConsoleAppender

輸出到控制臺

開發(fā)環(huán)境調(diào)試

RollingFileAppender

滾動文件輸出

生產(chǎn)環(huán)境持久化

SMTPAppender

郵件發(fā)送日志

錯誤報警

DBAppender

數(shù)據(jù)庫存儲日志

日志分析系統(tǒng)

AsyncAppender

異步日志

高性能需求

3.4.2 RollingPolicy策略

策略類型

特點

配置示例

TimeBasedRollingPolicy

按時間滾動

%d{yyyy-MM-dd}.log

SizeAndTimeBasedRollingPolicy

按大小和時間滾動

%d{yyyy-MM-dd}.%i.log

FixedWindowRollingPolicy

固定窗口滾動

myapp.%i.log.zip

3.4.3 日志格式模式

模式

說明

示例輸出

%d

日期時間

2023-01-01 12:00:00

%thread

線程名

main

%level

日志級別

INFO

%logger

Logger名稱

com.myapp.MyClass

%msg

日志消息

User login success

%n

換行符

-

%X

MDC內(nèi)容

{key:value}

4. 高級日志功能

4.1 MDC (Mapped Diagnostic Context)

MDC用于在日志中添加上下文信息,如用戶ID、請求ID等。

使用示例

import org.slf4j.MDC; @RestController public class OrderController { private static final Logger logger = LoggerFactory.getLogger(OrderController.class); @GetMapping("/order/{id}") public Order getOrder(@PathVariable String id) { // 添加上下文信息 MDC.put("userId", "user123"); MDC.put("orderId", id); MDC.put("ip", "192.168.1.1"); try { logger.info("Fetching order details"); // 業(yè)務邏輯... return orderService.getOrder(id); } finally { // 清除MDC MDC.clear(); } } }

logback配置中添加MDC

<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] [%X{userId}] [%X{orderId}] %-5level %logger{36} - %msg%n</pattern>

4.2 日志過濾

可以根據(jù)條件過濾日志,只記錄滿足條件的日志。

示例:只記錄包含"important"的ERROR日志

<appender name="IMPORTANT_ERRORS" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>important-errors.log</file> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>ERROR</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator"> <expression>message.contains("important")</expression> </evaluator> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <!-- 其他配置 --> </appender>

4.3 日志異步輸出

對于性能敏感的應用,可以使用異步日志減少I/O阻塞。

配置示例

<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender"> <!-- 隊列大小,默認256 --> <queueSize>512</queueSize> <!-- 當隊列剩余容量小于此值時,丟棄TRACE/DEBUG/INFO級別日志 --> <discardingThreshold>0</discardingThreshold> <!-- 引用實際的appender --> <appender-ref ref="FILE" /> </appender>

4.4 多環(huán)境日志配置

利用Spring Profile為不同環(huán)境配置不同的日志策略。

<!-- 開發(fā)環(huán)境配置 --> <springProfile name="dev"> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> </root> </springProfile> <!-- 生產(chǎn)環(huán)境配置 --> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="ASYNC_FILE" /> </root> <logger name="org.hibernate.SQL" level="WARN" /> </springProfile>

5. 日志最佳實踐

5.1 日志記錄原則

有意義的消息:避免無意義的日志,如"進入方法"、"退出方法"不好:logger.info("Method called");好:logger.info("Processing order {} for user {}", orderId, userId);適當?shù)娜罩炯墑eERROR:需要立即處理的問題WARN:潛在問題INFO:重要業(yè)務事件DEBUG:調(diào)試信息TRACE:詳細跟蹤避免副作用:日志記錄不應該改變程序行為不好:logger.debug("Value: " + expensiveOperation());好:logger.debug("Value: {}", () -> expensiveOperation());

5.2 性能優(yōu)化

使用參數(shù)化日志

// 不好 - 即使日志級別高于DEBUG也會執(zhí)行字符串拼接

logger.debug("User " + userId + " accessed resource " + resourceId);

// 好 - 只有在DEBUG級別才會格式化字符串

logger.debug("User {} accessed resource {}", userId, resourceId);
異步日志:對于文件、網(wǎng)絡等慢速Appender使用異步方式合理配置日志級別:生產(chǎn)環(huán)境適當提高日志級別

5.3 日志監(jiān)控與分析

ELK Stack (Elasticsearch, Logstash, Kibana)SplunkPrometheus + Grafana (配合日志指標)

6. 常見問題與解決方案

6.1 日志文件過大

解決方案

配置合理的滾動策略

logs/app-%d{yyyy-MM-dd}.%i.log

50MB

30

5GB

</rollingPolicy>
定期歸檔和清理舊日志

6.2 日志輸出混亂

解決方案

使用MDC區(qū)分不同請求配置合理的日志格式<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{requestId}] %-5level %logger{36} - %msg%n</pattern>

6.3 日志性能問題

解決方案

使用異步日志減少不必要的日志記錄避免在日志中執(zhí)行復雜操作

7. 實戰(zhàn)案例:電商系統(tǒng)日志配置

7.1 完整logback-spring.xml配置

<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 公共屬性 --> <property name="LOG_HOME" value="/var/logs/ecommerce" /> <property name="APP_NAME" value="ecommerce-app" /> <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] [%X{userId}] [%X{requestId}] %-5level %logger{36} - %msg%n" /> <!-- 控制臺輸出 --> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>${LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 主日志文件 --> <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${APP_NAME}.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${APP_NAME}-%d{yyyy-MM-dd}.%i.log</fileNamePattern> <maxFileSize>50MB</maxFileSize> <maxHistory>30</maxHistory> <totalSizeCap>10GB</totalSizeCap> </rollingPolicy> <encoder> <pattern>${LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 錯誤日志單獨文件 --> <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/${APP_NAME}-error.log</file> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>ERROR</level> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/${APP_NAME}-error-%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>90</maxHistory> </rollingPolicy> <encoder> <pattern>${LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 異步appender --> <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>1024</queueSize> <discardingThreshold>0</discardingThreshold> <includeCallerData>true</includeCallerData> <appender-ref ref="FILE" /> </appender> <!-- 異步錯誤appender --> <appender name="ASYNC_ERROR" class="ch.qos.logback.classic.AsyncAppender"> <queueSize>512</queueSize> <appender-ref ref="ERROR_FILE" /> </appender> <!-- 慢查詢?nèi)罩?--> <appender name="SLOW_QUERY" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${LOG_HOME}/slow-query.log</file> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator class="ch.qos.logback.classic.boolex.JaninoEventEvaluator"> <expression> (message.contains("SQL") || message.contains("Query")) && (contains("took") || contains("duration")) && (getMarker() != null && getMarker().contains("SLOW")) </expression> </evaluator> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <fileNamePattern>${LOG_HOME}/slow-query-%d{yyyy-MM-dd}.log</fileNamePattern> <maxHistory>60</maxHistory> </rollingPolicy> <encoder> <pattern>${LOG_PATTERN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- 根日志配置 --> <root level="INFO"> <appender-ref ref="CONSOLE" /> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="ASYNC_ERROR" /> </root> <!-- 特定包配置 --> <logger name="com.ecommerce.dao" level="DEBUG" /> <logger name="com.ecommerce.service" level="INFO" /> <logger name="org.hibernate.SQL" level="WARN" /> <logger name="org.springframework" level="WARN" /> <!-- 開發(fā)環(huán)境特殊配置 --> <springProfile name="dev"> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> </root> <logger name="com.ecommerce" level="DEBUG" /> </springProfile> <!-- 生產(chǎn)環(huán)境特殊配置 --> <springProfile name="prod"> <root level="INFO"> <appender-ref ref="ASYNC_FILE" /> <appender-ref ref="ASYNC_ERROR" /> </root> <logger name="com.ecommerce.api" level="INFO" additivity="false"> <appender-ref ref="SLOW_QUERY" /> </logger> </springProfile> </configuration>

7.2 日志使用示例代碼

@RestController @RequestMapping("/orders") public class OrderController { private static final Logger logger = LoggerFactory.getLogger(OrderController.class); private static final Marker SLOW_OPERATION_MARKER = MarkerFactory.getMarker("SLOW"); @Autowired private OrderService orderService; @GetMapping("/{id}") public ResponseEntity<Order> getOrder(@PathVariable String id, HttpServletRequest request) { // 設置MDC MDC.put("requestId", UUID.randomUUID().toString()); MDC.put("userId", request.getRemoteUser()); MDC.put("clientIp", request.getRemoteAddr()); try { logger.info("Fetching order with id: {}", id); long startTime = System.currentTimeMillis(); Order order = orderService.getOrderById(id); long duration = System.currentTimeMillis() - startTime; if (duration > 500) { logger.warn(SLOW_OPERATION_MARKER, "Slow order retrieval took {}ms for order {}", duration, id); } logger.debug("Order details: {}", order); return ResponseEntity.ok(order); } catch (OrderNotFoundException e) { logger.error("Order not found with id: {}", id, e); return ResponseEntity.notFound().build(); } catch (Exception e) { logger.error("Unexpected error fetching order {}", id, e); return ResponseEntity.internalServerError().build(); } finally { MDC.clear(); } } @PostMapping public ResponseEntity<Order> createOrder(@RequestBody OrderRequest request, @RequestHeader("X-User-Id") String userId) { MDC.put("userId", userId); try { logger.info("Creating new order for user {}", userId); logger.debug("Order request details: {}", request); Order createdOrder = orderService.createOrder(request, userId); logger.info("Order created successfully with id: {}", createdOrder.getId()); return ResponseEntity.ok(createdOrder); } catch (InvalidOrderException e) { logger.warn("Invalid order request from user {}: {}", userId, e.getMessage()); return ResponseEntity.badRequest().build(); } finally { MDC.clear(); } } }

8. 日志框架切換

8.1 切換到Log4j2

排除默認的Logback依賴添加Log4j2依賴<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>

8.2 Log4j2配置示例

log4j2-spring.xml:

<?xml version="1.0" encoding="UTF-8"?> <Configuration status="WARN" monitorInterval="30"> <Properties> <Property name="LOG_PATTERN">%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] [%X{requestId}] %-5level %logger{36} - %msg%n</Property> <Property name="LOG_DIR">logs</Property> </Properties> <Appenders> <Console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="${LOG_PATTERN}"/> </Console> <RollingFile name="File" fileName="${LOG_DIR}/app.log" filePattern="${LOG_DIR}/app-%d{yyyy-MM-dd}-%i.log"> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <SizeBasedTriggeringPolicy size="50MB"/> <TimeBasedTriggeringPolicy/> </Policies> <DefaultRolloverStrategy max="30"/> </RollingFile> <Async name="AsyncFile" bufferSize="512"> <AppenderRef ref="File"/> </Async> </Appenders> <Loggers> <Root level="info"> <AppenderRef ref="Console"/> <AppenderRef ref="AsyncFile"/> </Root> <Logger name="com.myapp" level="debug" additivity="false"> <AppenderRef ref="Console"/> </Logger> </Loggers> </Configuration>

9. 日志監(jiān)控與告警

9.1 常用監(jiān)控指標

指標

說明

監(jiān)控方式

ERROR日志頻率

單位時間內(nèi)ERROR日志數(shù)量

計數(shù)/分鐘

慢請求日志

超過閾值的請求響應時間

日志內(nèi)容分析

關鍵操作日志

如登錄、支付等

日志內(nèi)容匹配

日志量突變

日志量突然增加或減少

數(shù)量對比

9.2 集成Prometheus監(jiān)控

@Configuration public class LogMetricsConfig { private static final Counter errorCounter = Counter.build() .name("log_errors_total") .help("Total number of ERROR logs") .labelNames("logger", "exception") .register(); @Bean public MeterRegistryCustomizer<MeterRegistry> metricsCommonTags() { return registry -> registry.config().commonTags("application", "my-spring-app"); } @Bean public ApplicationListener<ApplicationReadyEvent> logMetricsListener() { return event -> { LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); loggerContext.getLoggerList().forEach(logger -> { ((ch.qos.logback.classic.Logger) logger).addAppender(new AppenderBase<ILoggingEvent>() { @Override protected void append(ILoggingEvent event) { if (event.getLevel().isGreaterOrEqual(Level.ERROR)) { errorCounter.labels( event.getLoggerName(), event.getThrowableProxy() != null ? event.getThrowableProxy().getClassName() : "none" ).inc(); } } }); }); }; } }

本文結(jié)束得如此突然,就像你永遠猜不到老板下一秒要改的需求。

頭條對markdown的文章顯示不太友好,想了解更多的可以關注微信公眾號:“Eric的技術雜貨庫”,后期會有更多的干貨以及資料下載。

上一篇:沒想到(中國民航信息股份有限公司是什么級別)中國民航信息網(wǎng)絡股份有限公司重慶分公司,中國民航信息網(wǎng)絡申請操作日志的數(shù)據(jù)管理專利,對同一系統(tǒng)模塊下的操作日志進行壓縮,日志管理,

下一篇:學到了嗎(日志管理是什么意思)日志管理組件,開源三大日志管理系統(tǒng)大比拼,你選哪個?,日志管理,

在線咨詢

點擊這里給我發(fā)消息 售前咨詢專員

點擊這里給我發(fā)消息 售后服務專員

在線咨詢

免費通話

24小時免費咨詢

請輸入您的聯(lián)系電話,座機請加區(qū)號

免費通話

微信掃一掃

微信聯(lián)系
返回頂部