才疏学浅,欢迎大家提出意见或问题一起讨论
想要监控Java应用,JMX永远是第一选择。在prometheus监控体系中,jmx_exporter是使用范围十分广的工具。本文对jmx的配置进行一个讲解,主要是对社区文档进行翻译并解释说明。
简单说一下启动,官方给出的 jmx_exporter启动命令是:
java -javaagent:./jmx_prometheus_javaagent-0.13.0.jar=8080:config.yaml -jar yourJar.jar
启动完成后即可在 http://localhost:8080/metrics 查看到指标数据。
jmx_exporter是以java agent的模式启动的,那些与JMX远程输出相关的配置(如-Dcom.sun.management.jmxremote.port=1234)其实是没有必要的。jmx_exporter也支持独立启动,然后配置JMX远程通讯端口。
像一些大型项目,启动的形式肯定不是 java -jar,我们需要找到传入执行参数的入口,一般是一些环境配置文件。
下面是官方给出的jmx_exporter的配置样例:
---
startDelaySeconds: 0
hostPort: 127.0.0.1:1234
username:
password:
jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:1234/jmxrmi
ssl: false
lowercaseOutputName: false
lowercaseOutputLabelNames: false
whitelistObjectNames: ["org.apache.cassandra.metrics:*"]
blacklistObjectNames: ["org.apache.cassandra.metrics:type=ColumnFamily,*"]
rules:
- pattern: 'org.apache.cassandra.metrics<>Value: (\d+)'
name: cassandra_$1_$2
value: $3
valueFactor: 0.001
labels: {}
help: "Cassandra metric $1 $2"
type: GAUGE
attrNameSnakeCase: false
这里给出官方配置项解释的翻译,加入了一点我自己的描述:
名称 | 描述 |
---|---|
startDelaySeconds | 在处理请求前的启动延迟,单位为秒。在延迟期间,也就是启动前,任何的请求都只会返回空的指标集 |
hostPort | 远程JMX接入的主机与端口号。如果此配置项和jmxurl都没有被设置,则会与本地JVM会话。(以推荐的-javaagent 模式启动,并且没有配置远程JMX,则不用填此配置项。) |
username | 远程JMX身份认证的用户名 |
password | 远程JMX身份认证的密码 |
jmxUrl | 完整的 JMX URL,若配置了主机和端口则不应配置此项。 |
ssl | 是否开启与JMX的SSL通讯。要配置此项前必须设置一些系统属性:-Djavax.net.ssl.keyStore=/home/user/.keystore -Djavax.net.ssl.keyStorePassword=changeit -Djavax.net.ssl.trustStore=/home/user/.truststore -Djavax.net.ssl.trustStorePassword=changeit |
lowercaseOutputName | 是否把指标名称转换为小写,默认为false。 |
lowercaseOutputLabelNames | 是否把标签名称转换为小写,默认为false |
whitelistObjectNames | 查询对象白名单,默认是所有mBeans对象。不在白名单则不会被查询。支持正则匹配。 |
blacklistObjectNames | 查询对象黑名单,默认无。支持正则匹配。 |
rules | 一个按顺序引用的规则列表,处理过程会在第一条规则匹配上时停止。未匹配上的atrributes则不会被收集。默认以默认格式收集所有指标 |
pattern | 匹配每一个bean attribute(属性)的正则样式。该样式不是锚定的。可以设置正则捕获组用与其他配置项(如上面的样例 name: cassandra_$1_$2)。默认匹配所有格式。 |
attrNameSnakeCase | 将attribute名称 转换为蛇形格式。例如 anAttrName 转换为 an_attr_name。默认为false |
name | 指标名。可以引用 pattern中设置的捕获组。如果没有指定则使用默认格式。如果为空,此attribute的处理会停止且没有输出。 |
value | 指标值。静态值和引用pattern捕获组均可。如果没指定则抓取mBean attribute对应的value值。 |
valueFactor | 指标值(或 mBean value)的乘数。多用于秒和毫秒等单位转化 |
labels | 标签名:标签值 形式的键值对。可引用捕获组。使用时必须配置 name 项。如果没有指定并且没有使用默认格式,则不会输出标签。 |
help | 指标的帮助信息,可引用捕获组 。使用时必须配置 name 项。默认为mBean attribute的描述和全名。 |
type | 指标格式,值为 GAUGE, COUNTER 或 UNTYPED. 使用时必须配置 name项,默认为 UNTYPED |
输入格式:
domainattrName: value
Part | Description |
---|---|
domain | Bean对象名. JMX object name 冒号之前的部分。 |
beanProperyName/Value | Bean属性. JMX object name 冒号后的key/values 对。 |
keyN | 如果 Bean有多层嵌套,嵌套的字段会写入这里。 |
attrName | attribute名. 如果是表格式数据,attrName为列名。 如果attrNameSnakeCase 已设置, 会转化为 snake 模式。 |
value | attribute 值 |
默认的输出格式:
domain_beanPropertyValue1_key1_key2_...keyN_attrName{beanpropertyName2="beanPropertyValue2", ...}: value
rules的主要功能是进行指标的过滤和清洗。还有一个功能是对value进行转化。prometheus无法接受字符数据,但有时候我们确实需要这个字符串信息,这时候就可以用rules进行配置转化。
下面以一个案例来介绍rules的使用。
jmx的格式为一个json对象,里面是一个包含多个bean对象的数组:
{
"beans":[
{bean},
{bean}
]
}
下文为我配置hadoop监控时的一个bean对象,实际省略了部分内容
{
"name" : "Hadoop:service=NameNode,name=FSNamesystemState",
"modelerType" : "org.apache.hadoop.hdfs.server.namenode.FSNamesystem",
"PendingReplicationBlocks" : 0,
"PendingReconstructionBlocks" : 0,
"UnderReplicatedBlocks" : 0,
"LowRedundancyBlocks" : 0,
"ScheduledReplicationBlocks" : 0,
"PendingDeletionBlocks" : 0,
"BlockDeletionStartTime" : 1591347343145,
"FSState" : "Operational",
},
其中 "FSState"是HDFS文件系统的状态,有两个值 Safemode(安全模式)和Operational(可使用)。我希望我的监控可以监测到文件系统的状态。可jmx_exporter中确找不到这个指标。因为我的配置文件是空的,jmx_exporter会过滤到所有字符串value,因为prometheus无法接收。因此我需要配置rules将字符串转化为数值型。
首先是需要根据pattern import的格式把指标的输入格式写出来:
Hadoop
然后用正则表达式进行判断,value含有Safemode 为 0, 含有Operational为1
为了与其他指标统一,我的name的写法与默认输出相同。
最后的配置为:
---
rules:
- pattern: 'Hadoop<>FSState:.*?Safemode.*?'
name: Hadoop_NameNode_FSState
value: 0
- pattern: 'Hadoop<>FSState:.*?Operational.*?'
name: Hadoop_NameNode_FSState
value: 1
- pattern: '.*'
注意到这里我最后加了一个匹配所有指标的正则表达。如果不加的话,最后exporter除了jvm的指标,只会输出在rules中匹配成功的指标。
**还有一个十分tricky的点!- pattern: ‘.*’ 必须放在最后。**我们回头看看rules的描述,是顺序执行的,每个指标而且完成匹配后就会停止继续匹配。如果把全局匹配放在最前,那所有的指标都会被匹配上,匹配就结束了。但带字符串的被过滤掉了,而且后面的规则也不会生效。那这条指标还是不会出现在jvm_exporter的httpserver上。
此指标在jmx_exporter上的呈现:
# HELP Hadoop_NameNode_FSState Attribute exposed for management (Hadoop<>FSState)
# TYPE Hadoop_NameNode_FSState untyped
Hadoop_NameNode_FSState 1.0
在Grafana里我们可以 用Gauge或 Singlestat试图,使用ValueMapping将数值表达的文字含义呈现出来。