【Azure Spring Cloud】Azure Spring Cloud服務,如何獲取應用程式日誌文件呢?
- 2022 年 9 月 2 日
- 筆記
- 【Azure Spring Cloud】, Azure Spring Cloud, logback-spring.xml, Mount Storage Account, 配置App日誌文件到Mount Path
問題描述
在使用Azure Spring Cloud服務時,如果要收集應用程式的日誌。有控制台輸出(實時流日誌),也可以配置Log Analytics服務。
日誌流式處理
可以通過以下命令在 Azure CLI 中使用日誌流式處理。
az spring-cloud app logs -n hellospring -s yourspringcloudname -g <resource group name> –lines 100 -f
Log Analytics
在Azure Spring Cloud門戶頁面,轉到「服務 | 概述」頁,然後在「監視」部分中選擇「日誌」 。 選擇 Azure Spring Cloud 的一個示例查詢上的「運行」。
但是,如果應用中需要自行把日誌寫入到日誌文件中,那麼如果應用部署到Azure Spring Cloud 上後,如何來查看並獲取到應用程式自身專門用於記錄日誌的文件呢?
問題解答
Azure Spring Cloud 與 App Service有較大的區別。App Service可以通過Kudu工具訪問應用的文件系統,就可以在Home目錄下直接看見應用程式生成的日誌文件並下載。
而Spring Cloud服務,需要通過文件掛載(Mount)的方式,把一個存儲帳號(Storage Account)掛載到Spring Cloud的App上。
掛載Storage Account以及在程式碼中配置掛載後的日誌路徑步驟:
第一步:為Azure Spring Cloud服務添加一個Storage
- Storage name:為自定義名稱,根據自己情況設定,如 springstorage01
- Account name:為存儲帳號(Storage Account)的名稱,需要從Azure Storage Account的頁面中獲取
- Account Key:從Azure Storage Account的Access Key頁面中獲取。注意:此處只需要填寫Access Key就可以,不需要完整的Conneciton String
第二步:為Spring Cloud App添加掛載
在Spring Cloud頁面,點擊「Apps」列舉出所有的App。選中需要配置日誌文件路徑的應用。然後選擇「Configuration」 –> “Persistent Storage”
- Storage Name:為第一步中自定義的Storage Name。
- Share Name:為在Azure Storage Account的文件共享中所創建的一個共享文件夾。可以自定義文件夾名稱。
- Mount Path: 所掛載Spring Cloud App所運行實例上的文件路徑。這一步的內容也是將在應用為日誌文件所配置的存放路徑。非常關鍵!如使用 /app/logs
第三步:在Java Spring應用中重新配置日誌生成路徑
修改應用中的日誌保存路徑。如本實例中使用的 logback-spring.xml 。 修改文件輸出路徑為: <file>/app/logs/test.log</file>
重新生成Jar文件並再次發布。
第四步: 在存儲帳號中檢查應用日誌
在Azure門戶中,進入Storage Account中,查看Spring Cloud App的運行日誌。如下:
附錄:Spring Cloud應用示例程式碼
POM.XML 依賴包文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="//maven.apache.org/POM/4.0.0" xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="//maven.apache.org/POM/4.0.0 //maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.11</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.example</groupId> <artifactId>hellospring</artifactId> <version>0.0.1-SNAPSHOT</version> <name>hellospring</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> <spring-cloud.version>2021.0.3</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>net.logstash.logback</groupId> <artifactId>logstash-logback-encoder</artifactId> <version>6.5</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
application.properties 配置文件
spring.cloud.config.enabled=false
logback-spring.xml配置文件
<configuration> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <timestamp> <fieldName>timestamp</fieldName> <timeZone>UTC</timeZone> </timestamp> <loggerName> <fieldName>logger</fieldName> </loggerName> <logLevel> <fieldName>level</fieldName> </logLevel> <threadName> <fieldName>thread</fieldName> </threadName> <nestedField> <fieldName>mdc</fieldName> <providers> <mdc /> </providers> </nestedField> <stackTrace> <fieldName>stackTrace</fieldName> <!-- maxLength - limit the length of the stack trace --> <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"> <maxDepthPerThrowable>200</maxDepthPerThrowable> <maxLength>14000</maxLength> <rootCauseFirst>true</rootCauseFirst> </throwableConverter> </stackTrace> <message /> <throwableClassName> <fieldName>exceptionClass</fieldName> </throwableClassName> </providers> </encoder> </appender> <appender name="files" class="ch.qos.logback.core.FileAppender"> <file>/app/logs/test.log</file> <append>true</append> <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder"> <providers> <timestamp> <fieldName>timestamp</fieldName> <timeZone>UTC</timeZone> </timestamp> <loggerName> <fieldName>logger</fieldName> </loggerName> <logLevel> <fieldName>level</fieldName> </logLevel> <threadName> <fieldName>thread</fieldName> </threadName> <nestedField> <fieldName>mdc</fieldName> <providers> <mdc /> </providers> </nestedField> <stackTrace> <fieldName>stackTrace</fieldName> <!-- maxLength - limit the length of the stack trace --> <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter"> <maxDepthPerThrowable>200</maxDepthPerThrowable> <maxLength>14000</maxLength> <rootCauseFirst>true</rootCauseFirst> </throwableConverter> </stackTrace> <message /> <throwableClassName> <fieldName>exceptionClass</fieldName> </throwableClassName> </providers> </encoder> </appender> <root level="info"> <appender-ref ref="stdout" /> <appender-ref ref="files" /> </root> </configuration>
HelloController.java 程式碼
package com.example.hellospring; import org.springframework.web.bind.annotation.RestController; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.RequestMapping; @RestController public class HelloController { org.slf4j.Logger logger = LoggerFactory.getLogger(getClass()); @RequestMapping("/") public String index() { logger.info("Loging into Storage Folder.... request from index page.... test by lb @09-02"); return "Greetings from Azure Spring Cloud!"; } }
HellospringApplication.java 程式碼
package com.example.hellospring; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class HellospringApplication { public static void main(String[] args) { SpringApplication.run(HellospringApplication.class, args); } }
參考資料
快速入門:在 Azure Spring Cloud 中部署你的第一個應用程式://docs.azure.cn/zh-cn/spring-cloud/quickstart?tabs=Azure-CLI#build-and-deploy-the-app
日誌: //docs.azure.cn/zh-cn/spring-cloud/quickstart-logs-metrics-tracing?tabs=Azure-CLI