Spring Boot Actuator 使用

原文地址:https://www.jianshu.com/p/af9738634a21

Spring Boot 的 Actuator 提供了很多生產級的特性,比如監控和度量Spring Boot 應用程序。Actuator 的這些特性可以通過衆多 REST 接口、遠程 shell 和 JMX 獲得。

一、Actuator 的 REST 接口

Spring Boot Actuator 的關鍵特性是在應用程序裏提供衆多 Web 接口,通過它們瞭解應用程序運行時的內部狀況。Actuator 提供了 13 個接口,可以分爲三大類:配置接口、度量接口和其它接口,具體如下表所示。

HTTP 方法路徑描述
GET/autoconfig提供了一份自動配置報告,記錄哪些自動配置條件通過了,哪些沒通過
GET/configprops描述配置屬性(包含默認值)如何注入Bean
GET/beans描述應用程序上下文裏全部的Bean,以及它們的關係
GET/dump獲取線程活動的快照
GET/env獲取全部環境屬性
GET/env/{name}根據名稱獲取特定的環境屬性值
GET/health報告應用程序的健康指標,這些值由HealthIndicator的實現類提供
GET/info獲取應用程序的定製信息,這些信息由info打頭的屬性提供
GET/mappings描述全部的URI路徑,以及它們和控制器(包含Actuator端點)的映射關係
GET/metrics報告各種應用程序度量信息,比如內存用量和HTTP請求計數
GET/metrics/{name}報告指定名稱的應用程序度量值
POST/shutdown關閉應用程序,要求endpoints.shutdown.enabled設置爲true
GET/trace提供基本的HTTP請求跟蹤信息(時間戳、HTTP頭等)

要啓用 Actuator 的端點,只要在項目中引入 Actuator 的依賴即可。對於 Maven 依賴,引入的依賴是這樣的:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

1. 查看配置明細

Actuator 有一些接口不僅可以顯示組件映射關係,還可以告訴你自動配置在配置 Spring 應用程序上下文時做了哪些決策。

1.1 獲得 Bean 裝配報告

要了解應用程序中 Spring 上下文的情況,最重要的接口就是 /beans。它會返回一個 JSON 文檔,描述上下文裏每個 bean 的情況,包括其 Java 類型以及注入的其它 bean。返回的信息如下所示:

[
    {
        "context": "application",
        "parent": null,
        "beans": [
            {
                "bean": "demoApplication",
                "aliases": [],
                "scope": "singleton",
                "type": "com.example.DemoApplication$$EnhancerBySpringCGLIB$$88686e04",
                "resource": "null",
                "dependencies": []
            },
            {
                "bean": "org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory",
                "aliases": [],
                "scope": "singleton",
                "type": "org.springframework.core.type.classreading.CachingMetadataReaderFactory",
                "resource": "null",
                "dependencies": []
            }
        ]
    }
]

所有的 Bean 條目都有五類信息:

  • bean:Spring 應用程序上下文中的 Bean 名稱或 ID。
  • resource:.class 文件的物理位置,通常是一個 URL,指向構建出的 JAR 文件。這會隨着應用程序的構建和運行方式發生變化。
  • dependencies:當前 Bean 注入的 Bean ID 列表。
  • scope:Bean 的作用域(通常是單例,這也是默認作用域)。
  • type:Bean 的 Java 類型。
1.2 詳解自動配置

/autoconfig接口能告訴你爲什麼會有這個 bean ,或者爲什麼沒有這個 bean。

{
    "positiveMatches": {
        "AuditAutoConfiguration#auditListener": [
            {
                "condition": "OnBeanCondition",
                "message": "@ConditionalOnMissingBean (types: org.springframework.boot.actuate.audit.listener.AbstractAuditListener; SearchStrategy: all) did not find any beans"
            }
        ],
        "MultipartAutoConfiguration#multipartConfigElement": [
            {
                "condition": "OnBeanCondition",
                "message": "@ConditionalOnMissingBean (types: javax.servlet.MultipartConfigElement; SearchStrategy: all) did not find any beans"
            }
        ]
    },
    "negativeMatches": {
        "AuditAutoConfiguration#authenticationAuditListener": {
            "notMatched": [
                {
                    "condition": "OnClassCondition",
                    "message": "@ConditionalOnClass did not find required class 'org.springframework.security.authentication.event.AbstractAuthenticationEvent'"
                }
            ],
            "matched": []
        },
        "AuditAutoConfiguration#authorizationAuditListener": {
            "notMatched": [
                {
                    "condition": "OnClassCondition",
                    "message": "@ConditionalOnClass did not find required class 'org.springframework.security.access.event.AbstractAuthorizationEvent'"
                }
            ],
            "matched": []
        }
    }
}
1.3 查看配置屬性

/env接口會生成應用程序可用的所有環境屬性的列表,無論這些屬性是否用到。這其中包括環境變量、JVM 屬性、命令行參數,以及 application.properties 或 application.yml 文件提供的屬性。

{
    "profiles": [],
    "server.ports": {
        "local.server.port": 8080
    },
    "servletContextInitParams": {},
    "systemProperties": {
        "java.runtime.name": "Java(TM) SE Runtime Environment",
        "spring.output.ansi.enabled": "always",
        "sun.boot.library.path": "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib",
        "java.vm.version": "25.121-b13",
        "gopherProxySet": "false",
        "java.vm.vendor": "Oracle Corporation",
        "java.vendor.url": "http://java.oracle.com/",
        "path.separator": ":",
        "idea.launcher.port": "7532",
        "java.vm.name": "Java HotSpot(TM) 64-Bit Server VM",
        "file.encoding.pkg": "sun.io",
        "user.country": "CN",
        "sun.java.launcher": "SUN_STANDARD",
        "sun.os.patch.level": "unknown",
        "PID": "2716",
        "java.vm.specification.name": "Java Virtual Machine Specification",
        "user.dir": "/Users/FlySheep/FlySheep/Code/ServerCode/SpringBoot_Demo/demo",
        "java.runtime.version": "1.8.0_121-b13",
        "java.awt.graphicsenv": "sun.awt.CGraphicsEnvironment",
        "org.jboss.logging.provider": "slf4j",
        "java.endorsed.dirs": "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/endorsed",
        "os.arch": "x86_64",
        "visualvm.id": "11136812717769",
        "java.io.tmpdir": "/var/folders/d6/zn9yrwns46j4pwbl1_mv_6hw0000gn/T/",
        "line.separator": "\n",
        "java.vm.specification.vendor": "Oracle Corporation",
        "os.name": "Mac OS X",
        "sun.jnu.encoding": "UTF-8",
        "spring.beaninfo.ignore": "true",
        "java.library.path": "/Users/FlySheep/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.",
        "java.specification.name": "Java Platform API Specification",
        "java.class.version": "52.0",
        "sun.management.compiler": "HotSpot 64-Bit Tiered Compilers",
        "os.version": "10.11",
        "user.home": "/Users/FlySheep",
        "catalina.useNaming": "false",
        "user.timezone": "Asia/Shanghai",
        "java.awt.printerjob": "sun.lwawt.macosx.CPrinterJob",
        "file.encoding": "UTF-8",
        "idea.launcher.bin.path": "/Applications/IntelliJ IDEA.app/Contents/bin",
        "java.specification.version": "1.8",
        "catalina.home": "/private/var/folders/d6/zn9yrwns46j4pwbl1_mv_6hw0000gn/T/tomcat.6698906163877756728.8080",
        "java.class.path": "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/lib/tools.jar:/Users/FlySheep/FlySheep/Code/ServerCode/SpringBoot_Demo/demo/target/classes:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-starter-web/1.5.2.RELEASE/spring-boot-starter-web-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-starter/1.5.2.RELEASE/spring-boot-starter-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot/1.5.2.RELEASE/spring-boot-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-autoconfigure/1.5.2.RELEASE/spring-boot-autoconfigure-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-starter-logging/1.5.2.RELEASE/spring-boot-starter-logging-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar:/Users/FlySheep/.m2/repository/ch/qos/logback/logback-core/1.1.11/logback-core-1.1.11.jar:/Users/FlySheep/.m2/repository/org/slf4j/jcl-over-slf4j/1.7.24/jcl-over-slf4j-1.7.24.jar:/Users/FlySheep/.m2/repository/org/slf4j/jul-to-slf4j/1.7.24/jul-to-slf4j-1.7.24.jar:/Users/FlySheep/.m2/repository/org/slf4j/log4j-over-slf4j/1.7.24/log4j-over-slf4j-1.7.24.jar:/Users/FlySheep/.m2/repository/org/yaml/snakeyaml/1.17/snakeyaml-1.17.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-starter-tomcat/1.5.2.RELEASE/spring-boot-starter-tomcat-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/apache/tomcat/embed/tomcat-embed-core/8.5.11/tomcat-embed-core-8.5.11.jar:/Users/FlySheep/.m2/repository/org/apache/tomcat/embed/tomcat-embed-el/8.5.11/tomcat-embed-el-8.5.11.jar:/Users/FlySheep/.m2/repository/org/apache/tomcat/embed/tomcat-embed-websocket/8.5.11/tomcat-embed-websocket-8.5.11.jar:/Users/FlySheep/.m2/repository/org/hibernate/hibernate-validator/5.3.4.Final/hibernate-validator-5.3.4.Final.jar:/Users/FlySheep/.m2/repository/javax/validation/validation-api/1.1.0.Final/validation-api-1.1.0.Final.jar:/Users/FlySheep/.m2/repository/org/jboss/logging/jboss-logging/3.3.0.Final/jboss-logging-3.3.0.Final.jar:/Users/FlySheep/.m2/repository/com/fasterxml/classmate/1.3.3/classmate-1.3.3.jar:/Users/FlySheep/.m2/repository/com/fasterxml/jackson/core/jackson-databind/2.8.7/jackson-databind-2.8.7.jar:/Users/FlySheep/.m2/repository/com/fasterxml/jackson/core/jackson-annotations/2.8.0/jackson-annotations-2.8.0.jar:/Users/FlySheep/.m2/repository/com/fasterxml/jackson/core/jackson-core/2.8.7/jackson-core-2.8.7.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-web/4.3.7.RELEASE/spring-web-4.3.7.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-aop/4.3.7.RELEASE/spring-aop-4.3.7.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-beans/4.3.7.RELEASE/spring-beans-4.3.7.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-context/4.3.7.RELEASE/spring-context-4.3.7.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-webmvc/4.3.7.RELEASE/spring-webmvc-4.3.7.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-expression/4.3.7.RELEASE/spring-expression-4.3.7.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-starter-actuator/1.5.2.RELEASE/spring-boot-starter-actuator-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/springframework/boot/spring-boot-actuator/1.5.2.RELEASE/spring-boot-actuator-1.5.2.RELEASE.jar:/Users/FlySheep/.m2/repository/org/slf4j/slf4j-api/1.7.24/slf4j-api-1.7.24.jar:/Users/FlySheep/.m2/repository/org/springframework/spring-core/4.3.7.RELEASE/spring-core-4.3.7.RELEASE.jar:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar",
        "user.name": "FlySheep",
        "java.vm.specification.version": "1.8",
        "sun.java.command": "com.intellij.rt.execution.application.AppMain com.example.DemoApplication",
        "java.home": "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre",
        "sun.arch.data.model": "64",
        "user.language": "zh",
        "java.specification.vendor": "Oracle Corporation",
        "awt.toolkit": "sun.lwawt.macosx.LWCToolkit",
        "java.vm.info": "mixed mode",
        "java.version": "1.8.0_121",
        "java.ext.dirs": "/Users/FlySheep/Library/Java/Extensions:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/ext:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java",
        "sun.boot.class.path": "/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/sunrsasign.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/jre/classes",
        "java.awt.headless": "true",
        "java.vendor": "Oracle Corporation",
        "catalina.base": "/private/var/folders/d6/zn9yrwns46j4pwbl1_mv_6hw0000gn/T/tomcat.6698906163877756728.8080",
        "file.separator": "/",
        "java.vendor.url.bug": "http://bugreport.sun.com/bugreport/",
        "sun.io.unicode.encoding": "UnicodeBig",
        "sun.cpu.endian": "little",
        "sun.cpu.isalist": ""
    },
    "systemEnvironment": {
        "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:/Library/Java/JavaVirtualMachines/jdk1.7.0_79.jdk/Contents/Home/bin:/usr/local/mysql/bin:/Users/FlySheep/FlySheep/JavaTools/apache-maven-3.3.9/bin/bin",
        "SHELL": "/bin/zsh",
        "PAGER": "less",
        "LSCOLORS": "Gxfxcxdxbxegedabagacad",
        "OLDPWD": "/Applications/IntelliJ IDEA.app/Contents/bin",
        "USER": "FlySheep",
        "VERSIONER_PYTHON_PREFER_32_BIT": "no",
        "ZSH": "/Users/FlySheep/.oh-my-zsh",
        "TMPDIR": "/var/folders/d6/zn9yrwns46j4pwbl1_mv_6hw0000gn/T/",
        "SSH_AUTH_SOCK": "/private/tmp/com.apple.launchd.vZEKsGdZ1T/Listeners",
        "JAVA_MAIN_CLASS_2716": "com.intellij.rt.execution.application.AppMain",
        "XPC_FLAGS": "0x0",
        "VERSIONER_PYTHON_VERSION": "2.7",
        "__CF_USER_TEXT_ENCODING": "0x1F5:0x19:0x34",
        "Apple_PubSub_Socket_Render": "/private/tmp/com.apple.launchd.5VgRuDCQ5D/Render",
        "LOGNAME": "FlySheep",
        "LESS": "-R",
        "LC_CTYPE": "",
        "PWD": "/Users/FlySheep/FlySheep/Code/ServerCode/SpringBoot_Demo/demo",
        "XPC_SERVICE_NAME": "com.jetbrains.intellij.136992",
        "HOME": "/Users/FlySheep"
    },
    "applicationConfig: [classpath:/application.properties]": {
        "management.security.enabled": "false"
    }
}

基本上,任何能給Spring Boot 應用程序提供屬性的屬性源都會列在 /env 的結果裏,同時會顯示具體的屬性。
  爲了避免敏感信息暴露到 /env 裏,所有名爲password、secret、key(或者名字中最後一段是這些)的屬性在 /env 裏都會加上“*”。舉個例子,如果有一個屬性名字是database.password,那麼它在/env中的顯示效果是這樣的:

"database.password":"******"

/env 接口還能用來獲取單個屬性的值,只需要在請求時在 /env 後加上屬性名即可。

1.4 查看屬性的使用方法

/configprops 接口會生成一個報告,說明屬性如何進行設置(注入或其他方式)。

{
    "endpoints-org.springframework.boot.actuate.endpoint.EndpointProperties": {
        "prefix": "endpoints",
        "properties": {
            "enabled": true,
            "sensitive": null
        }
    },
    "management.info-org.springframework.boot.actuate.autoconfigure.InfoContributorProperties": {
        "prefix": "management.info",
        "properties": {
            "git": {
                "mode": "SIMPLE"
            }
        }
    },
    "metricsEndpoint": {
        "prefix": "endpoints.metrics",
        "properties": {
            "id": "metrics",
            "sensitive": true,
            "enabled": true
        }
    },
    "spring.jackson-org.springframework.boot.autoconfigure.jackson.JacksonProperties": {
        "prefix": "spring.jackson",
        "properties": {
            "propertyNamingStrategy": null,
            "defaultPropertyInclusion": null,
            "dateFormat": null,
            "timeZone": null,
            "locale": null,
            "jodaDateTimeFormat": null
        }
    },
    "heapdumpMvcEndpoint": {
        "prefix": "endpoints.heapdump",
        "properties": {
            "path": "/heapdump",
            "sensitive": true,
            "enabled": true
        }
    },
    "endpoints.cors-org.springframework.boot.actuate.autoconfigure.EndpointCorsProperties": {
        "prefix": "endpoints.cors",
        "properties": {
            "allowedOrigins": [],
            "maxAge": 1800,
            "exposedHeaders": [],
            "allowedHeaders": [],
            "allowedMethods": [],
            "allowCredentials": null
        }
    },
    "environmentMvcEndpoint": {
        "prefix": "endpoints.env",
        "properties": {
            "path": "/env"
        }
    },
    "environmentEndpoint": {
        "prefix": "endpoints.env",
        "properties": {
            "id": "env",
            "sensitive": true,
            "enabled": true
        }
    },
    "spring.http.multipart-org.springframework.boot.autoconfigure.web.MultipartProperties": {
        "prefix": "spring.http.multipart",
        "properties": {
            "maxRequestSize": "10MB",
            "fileSizeThreshold": "0",
            "location": null,
            "maxFileSize": "1MB",
            "enabled": true,
            "resolveLazily": false
        }
    },
    "spring.info-org.springframework.boot.autoconfigure.info.ProjectInfoProperties": {
        "prefix": "spring.info",
        "properties": {
            "build": {
                "location": {}
            },
            "git": {
                "location": {}
            }
        }
    },
    "auditEventsEndpoint": {
        "prefix": "endpoints.auditevents",
        "properties": {
            "enabled": true
        }
    },
    "traceEndpoint": {
        "prefix": "endpoints.trace",
        "properties": {
            "id": "trace",
            "sensitive": true,
            "enabled": true
        }
    },
    "metricsMvcEndpoint": {
        "prefix": "endpoints.metrics",
        "properties": {
            "path": "/metrics"
        }
    },
    "infoEndpoint": {
        "prefix": "endpoints.info",
        "properties": {
            "id": "info",
            "sensitive": false,
            "enabled": true
        }
    },
    "auditEventMvcEndpoint": {
        "prefix": "endpoints.auditevents",
        "properties": {
            "path": "/auditevents",
            "sensitive": true,
            "enabled": true
        }
    },
    "management.trace-org.springframework.boot.actuate.trace.TraceProperties": {
        "prefix": "management.trace",
        "properties": {
            "include": [
                "COOKIES",
                "REQUEST_HEADERS",
                "RESPONSE_HEADERS",
                "ERRORS"
            ]
        }
    },
    "spring.resources-org.springframework.boot.autoconfigure.web.ResourceProperties": {
        "prefix": "spring.resources",
        "properties": {
            "cachePeriod": null,
            "addMappings": true,
            "chain": {
                "cache": true,
                "htmlApplicationCache": false,
                "gzipped": false,
                "strategy": {
                    "fixed": {
                        "enabled": false,
                        "paths": [
                            "/**"
                        ],
                        "version": null
                    },
                    "content": {
                        "enabled": false,
                        "paths": [
                            "/**"
                        ]
                    }
                }
            },
            "staticLocations": [
                "/",
                "classpath:/META-INF/resources/",
                "classpath:/resources/",
                "classpath:/static/",
                "classpath:/public/"
            ]
        }
    },
    "management.health.status-org.springframework.boot.actuate.autoconfigure.HealthIndicatorProperties": {
        "prefix": "management.health.status",
        "properties": {
            "order": null
        }
    },
    "healthMvcEndpoint": {
        "prefix": "endpoints.health",
        "properties": {
            "path": "/health"
        }
    },
    "serverProperties": {
        "prefix": "server",
        "properties": {
            "address": null,
            "maxHttpPostSize": 0,
            "undertow": {
                "maxHttpPostSize": 0,
                "bufferSize": null,
                "buffersPerRegion": null,
                "ioThreads": null,
                "workerThreads": null,
                "directBuffers": null,
                "accesslog": {
                    "enabled": null,
                    "pattern": "common",
                    "prefix": "access_log.",
                    "suffix": "log",
                    "dir": "/Users/FlySheep/FlySheep/Code/ServerCode/SpringBoot_Demo/demo/logs",
                    "rotate": true
                }
            },
            "tomcat": {
                "accesslog": {
                    "enabled": false,
                    "pattern": "common",
                    "directory": "logs",
                    "prefix": "access_log",
                    "suffix": ".log",
                    "rotate": true,
                    "renameOnRotate": false,
                    "requestAttributesEnabled": false,
                    "buffered": true
                },
                "internalProxies": "10\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|192\\.168\\.\\d{1,3}\\.\\d{1,3}|169\\.254\\.\\d{1,3}\\.\\d{1,3}|127\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}|172\\.1[6-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.2[0-9]{1}\\.\\d{1,3}\\.\\d{1,3}|172\\.3[0-1]{1}\\.\\d{1,3}\\.\\d{1,3}",
                "protocolHeader": null,
                "protocolHeaderHttpsValue": "https",
                "portHeader": "X-Forwarded-Port",
                "remoteIpHeader": null,
                "basedir": null,
                "backgroundProcessorDelay": 30,
                "maxThreads": 0,
                "minSpareThreads": 0,
                "maxHttpPostSize": 0,
                "redirectContextRoot": null,
                "uriEncoding": null,
                "maxConnections": 0,
                "acceptCount": 0,
                "additionalTldSkipPatterns": []
            },
            "displayName": "application",
            "session": {
                "timeout": null,
                "trackingModes": null,
                "persistent": false,
                "storeDir": null,
                "cookie": {
                    "name": null,
                    "domain": null,
                    "path": null,
                    "comment": null,
                    "httpOnly": null,
                    "secure": null,
                    "maxAge": null
                }
            },
            "contextPath": null,
            "error": {
                "path": "/error",
                "includeStacktrace": "NEVER"
            },
            "ssl": null,
            "serverHeader": null,
            "useForwardHeaders": null,
            "port": null,
            "maxHttpHeaderSize": 0,
            "servletPath": "/",
            "jspServlet": null,
            "jetty": {
                "maxHttpPostSize": 0,
                "acceptors": null,
                "selectors": null
            },
            "connectionTimeout": null
        }
    },
    "spring.metrics.export-org.springframework.boot.actuate.metrics.export.MetricExportProperties": {
        "prefix": "spring.metrics.export",
        "properties": {
            "excludes": null,
            "statsd": {
                "host": null,
                "port": 8125,
                "prefix": null
            },
            "includes": null,
            "enabled": true,
            "redis": {
                "prefix": "spring.metrics.application.7a5b013db041f4a1b6c45b6456487d05",
                "key": "******"
            },
            "aggregate": {
                "prefix": "application.7a5b013db041f4a1b6c45b6456487d05",
                "keyPattern": "k.d"
            }
        }
    },
    "configurationPropertiesReportEndpoint": {
        "prefix": "endpoints.configprops",
        "properties": {
            "id": "configprops",
            "sensitive": true,
            "enabled": true
        }
    },
    "healthEndpoint": {
        "prefix": "endpoints.health",
        "properties": {
            "timeToLive": 1000,
            "id": "health",
            "sensitive": false,
            "enabled": true
        }
    },
    "loggersMvcEndpoint": {
        "prefix": "endpoints.loggers",
        "properties": {
            "path": "/loggers"
        }
    },
    "loggersEndpoint": {
        "prefix": "endpoints.loggers",
        "properties": {
            "id": "loggers",
            "sensitive": true,
            "enabled": true
        }
    },
    "endpoints.metrics.filter-org.springframework.boot.actuate.autoconfigure.MetricFilterProperties": {
        "prefix": "endpoints.metrics.filter",
        "properties": {
            "counterSubmissions": [
                "MERGED"
            ],
            "gaugeSubmissions": [
                "MERGED"
            ]
        }
    },
    "dumpEndpoint": {
        "prefix": "endpoints.dump",
        "properties": {
            "id": "dump",
            "sensitive": true,
            "enabled": true
        }
    },
    "autoConfigurationReportEndpoint": {
        "prefix": "endpoints.autoconfig",
        "properties": {
            "id": "autoconfig",
            "sensitive": true,
            "enabled": true
        }
    },
    "endpoints.jmx-org.springframework.boot.actuate.autoconfigure.EndpointMBeanExportProperties": {
        "prefix": "endpoints.jmx",
        "properties": {
            "uniqueNames": false,
            "enabled": true,
            "domain": ""
        }
    },
    "spring.http.encoding-org.springframework.boot.autoconfigure.web.HttpEncodingProperties": {
        "prefix": "spring.http.encoding",
        "properties": {
            "charset": "UTF-8",
            "force": false,
            "mapping": null,
            "forceRequest": false,
            "forceResponse": false
        }
    },
    "shutdownEndpoint": {
        "prefix": "endpoints.shutdown",
        "properties": {
            "id": "shutdown",
            "sensitive": true,
            "enabled": false
        }
    },
    "beansEndpoint": {
        "prefix": "endpoints.beans",
        "properties": {
            "id": "beans",
            "sensitive": true,
            "enabled": true
        }
    },
    "managementServerProperties": {
        "prefix": "management",
        "properties": {
            "security": {
                "enabled": false,
                "roles": [
                    "ACTUATOR"
                ],
                "sessions": "STATELESS"
            },
            "address": null,
            "port": null,
            "addApplicationContextHeader": true,
            "contextPath": "",
            "ssl": null
        }
    },
    "requestMappingEndpoint": {
        "prefix": "endpoints.mappings",
        "properties": {
            "id": "mappings",
            "sensitive": true,
            "enabled": true
        }
    },
    "endpoints.health-org.springframework.boot.actuate.autoconfigure.HealthMvcEndpointProperties": {
        "prefix": "endpoints.health",
        "properties": {
            "mapping": {}
        }
    },
    "spring.mvc-org.springframework.boot.autoconfigure.web.WebMvcProperties": {
        "prefix": "spring.mvc",
        "properties": {
            "dateFormat": null,
            "servlet": {
                "loadOnStartup": -1
            },
            "staticPathPattern": "/**",
            "dispatchOptionsRequest": true,
            "dispatchTraceRequest": false,
            "locale": null,
            "ignoreDefaultModelOnRedirect": true,
            "logResolvedException": false,
            "async": {
                "requestTimeout": null
            },
            "messageCodesResolverFormat": null,
            "mediaTypes": {},
            "view": {
                "prefix": null,
                "suffix": null
            },
            "localeResolver": "ACCEPT_HEADER",
            "throwExceptionIfNoHandlerFound": false
        }
    },
    "diskSpaceHealthIndicatorProperties": {
        "prefix": "management.health.diskspace",
        "properties": {
            "path": "/Users/FlySheep/FlySheep/Code/ServerCode/SpringBoot_Demo/demo/.",
            "threshold": 10485760
        }
    }
}
1.5 生成接口道控制器的映射

在應用程序相對較小的時候,很容易搞清楚控制器都映射到了哪些接口上。如果Web界面的控制器和請求處理方法數量多,那最好能有一個列表,羅列出應用程序發佈的全部接口。/mappings 接口就提供了這麼一個列表。

{
    "/webjars/**": {
        "bean": "resourceHandlerMapping"
    },
    "/**": {
        "bean": "resourceHandlerMapping"
    },
    "/**/favicon.ico": {
        "bean": "faviconHandlerMapping"
    },
    "{[/error]}": {
        "bean": "requestMappingHandlerMapping",
        "method": "public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)"
    },
    "{[/error],produces=[text/html]}": {
        "bean": "requestMappingHandlerMapping",
        "method": "public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)"
    },
    "{[/env/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EnvironmentMvcEndpoint.value(java.lang.String)"
    },
    "{[/env || /env.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/beans || /beans.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/auditevents || /auditevents.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public org.springframework.http.ResponseEntity<?> org.springframework.boot.actuate.endpoint.mvc.AuditEventsMvcEndpoint.findByPrincipalAndAfterAndType(java.lang.String,java.util.Date,java.lang.String)"
    },
    "{[/autoconfig || /autoconfig.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/loggers/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.get(java.lang.String)"
    },
    "{[/loggers/{name:.*}],methods=[POST],consumes=[application/vnd.spring-boot.actuator.v1+json || application/json],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.LoggersMvcEndpoint.set(java.lang.String,java.util.Map<java.lang.String, java.lang.String>)"
    },
    "{[/loggers || /loggers.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/heapdump || /heapdump.json],methods=[GET],produces=[application/octet-stream]}": {
        "bean": "endpointHandlerMapping",
        "method": "public void org.springframework.boot.actuate.endpoint.mvc.HeapdumpMvcEndpoint.invoke(boolean,javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse) throws java.io.IOException,javax.servlet.ServletException"
    },
    "{[/mappings || /mappings.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/trace || /trace.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/configprops || /configprops.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/dump || /dump.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/metrics/{name:.*}],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.MetricsMvcEndpoint.value(java.lang.String)"
    },
    "{[/metrics || /metrics.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    },
    "{[/health || /health.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.HealthMvcEndpoint.invoke(javax.servlet.http.HttpServletRequest,java.security.Principal)"
    },
    "{[/info || /info.json],methods=[GET],produces=[application/vnd.spring-boot.actuator.v1+json || application/json]}": {
        "bean": "endpointHandlerMapping",
        "method": "public java.lang.Object org.springframework.boot.actuate.endpoint.mvc.EndpointMvcAdapter.invoke()"
    }
}

這裏我們可以看到不少接口的映射。每個映射的鍵都是一個字符串,其內容就是 Spring MVC 的 @RequestMapping 註解上設置的屬性。實際上,這個字符串能讓你清晰地瞭解控制器是如何映射的,哪怕不看源代碼。每個映射的值都有兩個屬性:bean 和 method。bean 屬性標識了 Spring Bean 的名字,映射源自這個Bean。method屬性是映射對應方法的全限定方法簽名。

2. 運行時指標

對運行時指標情況做一個快照,這對評估應用程序的健康情況很有幫助。Actuator 提供了一系列接口,讓你能在運行時快速檢查應用程序。

2.1 查看應用程序的指標值

關於運行中的應用程序,有很多有趣而且有用的信息。舉個例子,瞭解應用程序的內存情況 (可用或空閒)有助於決定給JVM分配多少內存。對Web應用程序而言,不用查看Web服務器日誌,如果請求失敗或者是耗時太長,就可以大概知道內存的情況了。運行中的應用程序有諸多計數器和度量器,/metrics 接口提供了這些東西的快照。

{
    "mem": 365004,
    "mem.free": 153938,
    "processors": 8,
    "instance.uptime": 852279,
    "uptime": 855002,
    "systemload.average": 3.509765625,
    "heap.committed": 316928,
    "heap.init": 262144,
    "heap.used": 162989,
    "heap": 3728384,
    "nonheap.committed": 50816,
    "nonheap.init": 2496,
    "nonheap.used": 48077,
    "nonheap": 0,
    "threads.peak": 18,
    "threads.daemon": 16,
    "threads.totalStarted": 23,
    "threads": 18,
    "classes": 5974,
    "classes.loaded": 5974,
    "classes.unloaded": 0,
    "gc.ps_scavenge.count": 4,
    "gc.ps_scavenge.time": 35,
    "gc.ps_marksweep.count": 1,
    "gc.ps_marksweep.time": 27,
    "httpsessions.max": -1,
    "httpsessions.active": 0,
    "gauge.response.mappings": 4,
    "gauge.response.configprops": 155,
    "counter.status.200.mappings": 1,
    "counter.status.200.configprops": 1
}

對 /metrics 接口提供的信息進行簡單分類如下表:

分類前綴報告內容
垃圾收集器gc.*已經發生過的垃圾收集次數,以及垃圾收集所耗費的時間,適用於標記-清理垃圾收集器和並行垃圾收集器(數據源自java.lang.management. GarbageCollectorMXBean)
內存mem.*分配給應用程序的內存數量和空閒的內存數量(數據源自java.lang. Runtime)
heap.*當前內存用量(數據源自java.lang.management.MemoryUsage)
類加載器classes.*JVM類加載器加載與卸載的類的數量(數據源自java.lang. management.ClassLoadingMXBean)
系統processors、instance.uptime、uptime、systemload.average系統信息,例如處理器數量(數據源自java.lang.Runtime)、運行時間(數據源自java.lang.management.RuntimeMXBean)、平均負載(數據源自java.lang.management.OperatingSystemMXBean)
線程池thread.*線程、守護線程的數量,以及JVM啓動後的線程數量峯值(數據源自 java.lang .management.ThreadMXBean)
數據源datasource.*數據源連接的數量(源自數據源的元數據,僅當Spring應用程序上下文裏存在 DataSource Bean 的時候纔會有這個信息)
Tomcat 會話httpsessions.*Tomcat的活躍會話數和最大會話數(數據源自嵌入式Tomcat的Bean,僅在使用嵌入式Tomcat服務器運行應用程序時纔有這個信息)
HTTPcounter.status.、gauge.response.多種應用程序服務HTTP請求的度量值與計數器

請注意,這裏的一些度量值,比如數據源和Tomcat會話,僅在應用程序中運行特定組件時纔有數據。你還可以註冊自己的度量信息。
  HTTP的計數器和度量值需要做一點說明。counter.status 後的值是HTTP狀態碼,隨後是所請求的路徑。舉個例子,counter.status.200.metrics 表明/metrics端點返回 200(OK) 狀態碼的次數。
  HTTP的度量信息在結構上也差不多,卻在報告另一類信息。它們全部以gauge.response 開頭,,表明這是HTTP響應的度量信息。前綴後是對應的路徑。度量值是以毫秒爲單位的時間,反映了最近處理該路徑請求的耗時。
  這裏還有幾個特殊的值需要注意。root路徑指向的是根路徑或/。star-star代表了那些Spring 認爲是靜態資源的路徑,包括圖片、JavaScript和樣式表,其中還包含了那些找不到的資源。這就是爲什麼你經常會看到 counter.status.404.star-star,這是返回了HTTP 404 (NOT FOUND) 狀態的請求數。  
  /metrics 接口會返回所有的可用度量值,但你也可能只對某個值感興趣。要獲取單個值,請求時可以在URL後加上對應的鍵名。例如,要查看空閒內存大小,可以向/metrics/mem.free發一 個GET請求。

2.2 追蹤 Web 請求

/trace 接口能報告所有Web請求的詳細信息,包括請求方法、路徑、時間戳以及請求和響應的頭信息。

[
    {
        "timestamp": 1491279254447,
        "info": {
            "method": "GET",
            "path": "/metrics",
            "headers": {
                "request": {
                    "host": "localhost:8080",
                    "connection": "keep-alive",
                    "upgrade-insecure-requests": "1",
                    "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36",
                    "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
                    "accept-encoding": "gzip, deflate, sdch, br",
                    "accept-language": "zh-CN,zh;q=0.8,en;q=0.6",
                    "cookie": "JSESSIONID=24CCB83195B2A35F5193C97D2CD51D69"
                },
                "response": {
                    "X-Application-Context": "application",
                    "Content-Type": "application/vnd.spring-boot.actuator.v1+json;charset=UTF-8",
                    "Transfer-Encoding": "chunked",
                    "Date": "Tue, 04 Apr 2017 04:14:14 GMT",
                    "status": "200"
                }
            }
        }
    }
]
2.3 導出線程活動

在確認應用程序運行情況時,除了跟蹤請求,瞭解線程活動也會很有幫助。/dump 接口會生成當前線程活動的快照。

2.4 監控應用程序健康狀況

如果你想知道自己的應用程序是否在運行,可以直接訪問/health 接口。在最簡單的情況下,該端點會顯示一個簡單的JSON,內容如下:

{
    "status": "UP",
    "diskSpace": {
        "status": "UP",
        "total": 48978722816,
        "free": 8812167168,
        "threshold": 10485760
    }
}

二、定製 Actuator

雖然Actuator提供了很多運行中Spring Boot應用程序的內部工作細節,但難免和你的需求有所偏差。也許你並不需要它提供的所有功能,想要關閉一些也說不定。或者,你需要對Actuator 稍作擴展,增加一些自定義的度量信息,以滿足你對應用程序的需求。

1. 修改接口 ID

每個Actuator 接口都有一個ID用來決定接口的路徑,比方說,/beans接口的默認ID就是beans。比如要修改 /beans 爲 /instances,則設置如下:

endpoints.beans.id = instances
2. 啓用和禁用接口

雖然Actuator的接口都很有用,但你不一定需要全部這些接口。默認情況下,所有接口(除 了/shutdown)都啓用。比如要禁用 /metrics 接口,則可以設置如下:

endpoints.metrics.enabled = false

如果你只想打開一兩個接口,那就先禁用全部接口,然後啓用那幾個你要的,這樣更方便。

endpoints.enabled = false
endpoints.metrics.enabled = true

3. 添加自定義度量信息

Actuator 自動配置有兩個實例 CounterService 和 GaugeService 可以用來計數使用,我們所要做的就是把它們的實例注入所需的 bean 然後調用相應的方法。除此之外,我們還可以實現 PublicMetrics 接口,提供自己需要的度量信息。

4. 創建自定義跟蹤倉庫

默認情況下,/trace 接口報告的跟蹤信息都存儲在內存倉庫裏,100個條目封頂。一旦倉庫滿了,就開始移除老的條目,給新的條目騰出空間。在開發階段這沒什麼問題,但在生產環境中,大流量會造成跟蹤信息還沒來得及看就被丟棄。我們可以將那些跟蹤條目存儲在其他地方——既不消耗內存,又能長久保存的地方。只需實現Spring Boot的TraceRepository接口即可。

5. 插入自定義的健康指示器

實現 HealthIndicator 接口則可以實現自定義的健康指示器。

6. 保護 Actuator 接口

很多Actuator端點發布的信息都可能涉及敏感數據,還有一些端點,(比如/shutdown)非常危險,可以用來關閉應用程序。因此,保護這些端點尤爲重要,能訪問它們的只能是那些經過授權的客戶端。



作者:FlySheep_ly
鏈接:https://www.jianshu.com/p/af9738634a21
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章