最开始准备是在zabbix上直接使用 jmx
做 tomcat
监控的,但是在使用过程中发现添加了 zabbix
自带的模板后并无法正常使用,然后参考西门飞冰博客 手动添加,添加完成后发现个问题,不能重复添加监控项,可能是我菜吧,毕竟 zabbix
用的少没什么经验。 为了能够实现监控同一服务器上多个不同的 tomcat
并且在一劳永逸,开始了折腾之路。在查阅了大量资料后说干就干。
准备工作
编写脚本 tomcat自动发现脚本 获取 tomcats
存放路径下多个不同命名的 tomcat
、tomcat JMX
端口,IP这个后面没用到(狗头),输出为 json
格式提供给 zabbix
获取使用。
jmx_tomcat_discovery.py >folded 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 import os, json, socket, fcntl, struct, redef get_ip_address (ifname) : s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) return socket.inet_ntoa(fcntl.ioctl( s.fileno(), 0x8915 , struct.pack('256s' , ifname[:15 ]))[20 :24 ]) def get_tomcat_info (tomcats_path, key_file, network_card) : tomcats = [] for root, _, files in os.walk(tomcats_path, topdown=False ): for file_name in files: if key_file == file_name: tomcat = {} name = root.split("/" )[2 ] tomcat['{#TOMCAT_NAME}' ] = name file_path = os.path.join(root, file_name) pattern = re.compile('[0-9]{1,5}' ) with open(file_path, "r" ) as f: lines = f.readlines() for line in lines: if "Dcom.sun.management.jmxremote.port" in line: try : port = pattern.findall(line)[0 ] except : port = 0 tomcat['{#TOMCAT_PORT}' ] = port tomcat['{#SERVER_IP}' ] = get_ip_address(network_card) tomcats.append(tomcat) return tomcats if __name__ == "__main__" : tomcats_path = "/data" key_file = "setenv.sh" network_card = "eth0" tomcats = get_tomcat_info(tomcats_path, key_file, network_card) print(json.dumps({'data' :tomcats},indent=4 ,separators=(',' ,':' )))
脚本编写好后存放于 zabbix_agent
服务器上你认为维护方便的地方 测试脚本,取值正常
shell 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 # ./jmx_tomcat_discovery.py { "data":[ { "{#SERVER_IP}":"192.168.1.132", "{#TOMCAT_NAME}":"tomcat_02", "{#TOMCAT_PORT}":"20020" }, { "{#SERVER_IP}":"192.168.1.132", "{#TOMCAT_NAME}":"tomcat_03", "{#TOMCAT_PORT}":"20030" }, { "{#SERVER_IP}":"192.168.1.132", "{#TOMCAT_NAME}":"tomcat_01", "{#TOMCAT_PORT}":"20010" } ] }
tomcat_jmx监控数据源脚本 监控模板参考zabbix监控自动发现监控tomcat(V1) 修改而来,原模板中有部分监控项无法获取数据。
tomcat_monitor.sh >folded 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 #!/usr/bin/env bash source /etc/profile[ $# -ne 3 ] && echo 'The scripts need 3 parameters' && exit 1 TOMCAT_NAME=$1 JMX_PORT=$2 ITEM=$3 jmx_user="akiya" jmx_password="akiya_password" authenticate="-" if [ -n "$jmx_user " ] && [ -n "$jmx_password " ]; then authenticate="$jmx_user :$jmx_password " fi xml=/data/$1 /conf/server.xml PORT=$(sed -n '69' p $xml | awk -F '[= " ]+' '{print $4}' ) cmd=/opt/zabbix/cmdline-jmxclient-0.10.3.jar logdir=/tmp/zabbix_tmp [ ! -d "$logdir " ] && mkdir -p $logdir && chmod 644 $logdir cd $logdir function HeapMemoryUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =Memory HeapMemoryUsage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function EdenSpaceUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =MemoryPool,name=PS\ Eden\ Space Usage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function SurvivorSpaceUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =MemoryPool,name=PS\ Survivor\ Space Usage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function TenuredGenUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =MemoryPool,name=PS\ Old\ Gen Usage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function NonHeapMemoryUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =Memory NonHeapMemoryUsage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function MetaspaceUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =MemoryPool,name=Metaspace Usage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function CodeCacheUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =MemoryPool,name=Code\ Cache Usage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function CompressedClassSpaceUsage () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =MemoryPool,name=Compressed\ Class\ Space Usage 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function TotalLoadedClassCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =ClassLoading TotalLoadedClassCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function LoadedClassCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =ClassLoading LoadedClassCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function UnloadedClassCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =ClassLoading UnloadedClassCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function TotalStartedThreadCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =Threading TotalStartedThreadCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function ThreadCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =Threading ThreadCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function PeakThreadCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =Threading PeakThreadCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function maxThreads () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =ThreadPool maxThreads 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function currentThreadCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =ThreadPool currentThreadCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function currentThreadsBusy () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =ThreadPool currentThreadsBusy 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function GlobalRequestProcessor_bytesReceived () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =GlobalRequestProcessor bytesReceived 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function GlobalRequestProcessor_bytesSent () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =GlobalRequestProcessor bytesSent 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function requestCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =GlobalRequestProcessor requestCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function errorCount () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT Catalina:name=\"http-nio-$PORT \",type =GlobalRequestProcessor errorCount 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } function jvmUptime () { java -jar $cmd $authenticate 127.0.0.1:$JMX_PORT java.lang:type =Runtime Uptime 2>$TOMCAT_NAME .$ITEM .$JMX_PORT } case $ITEM in HeapMemoryUsage.max) HeapMemoryUsage sed -n '4p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; HeapMemoryUsage.used) HeapMemoryUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; HeapMemoryUsage.committed) HeapMemoryUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; EdenSpaceUsage.max) EdenSpaceUsage sed -n '4p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; EdenSpaceUsage.used) EdenSpaceUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; EdenSpaceUsage.committed) EdenSpaceUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; SurvivorSpaceUsage.max) SurvivorSpaceUsage sed -n '4p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; SurvivorSpaceUsage.used) SurvivorSpaceUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; SurvivorSpaceUsage.committed) SurvivorSpaceUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; TenuredGenUsage.max) TenuredGenUsage sed -n '4p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; TenuredGenUsage.used) TenuredGenUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; TenuredGenUsage.committed) TenuredGenUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; NonHeapMemoryUsage.used) NonHeapMemoryUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; NonHeapMemoryUsage.committed) NonHeapMemoryUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; MetaspaceUsage.used) MetaspaceUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; MetaspaceUsage.committed) MetaspaceUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; CodeCacheUsage.max) CodeCacheUsage sed -n '4p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; CodeCacheUsage.used) CodeCacheUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; CodeCacheUsage.committed) CodeCacheUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; CompressedClassSpaceUsage.max) CompressedClassSpaceUsage sed -n '4p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; CompressedClassSpaceUsage.used) CompressedClassSpaceUsage sed -n '5p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; CompressedClassSpaceUsage.committed) CompressedClassSpaceUsage sed -n '2p' $TOMCAT_NAME .$ITEM .$JMX_PORT | awk '{print $2}' ;; ClassLoading.TotalLoadedClassCount) TotalLoadedClassCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; ClassLoading.LoadedClassCount) LoadedClassCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; ClassLoading.UnloadedClassCount) UnloadedClassCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; Threading.TotalStartedThreadCount) TotalStartedThreadCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; ThreadCount) ThreadCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; PeakThreadCount) PeakThreadCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; maxThreads) maxThreads awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; currentThreadCount) currentThreadCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; currentThreadsBusy) currentThreadsBusy awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; bytesReceived) GlobalRequestProcessor_bytesReceived awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; bytesSent) GlobalRequestProcessor_bytesSent awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; requestCount) requestCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; errorCount) errorCount awk '{print $6}' $TOMCAT_NAME .$ITEM .$JMX_PORT ;; jvmUptime) jvmUptime [ $? -eq 0 ] && awk '{print $6/1000}' $TOMCAT_NAME .$ITEM .$JMX_PORT || echo 0 ;; esac
同样,编写好脚本后和上面 python
脚本放在一起。 测试脚本,取值正常
1 2 # ./tomcat_monitor.sh tomcat_02 20020 HeapMemoryUsage.max 1070071808
配置zabbix zabbix_agent
修改 /etc/zabbix/zabbix_agentd.conf
中 AllowRoot=1
由于我们是使用的自定义脚本去自动发现相关的服务器并添加到 item
,需要先添加到 zabbix_agent.conf
/etc/zabbix/zabbix_agentd.d/userparameter_tomcat.conf 1 2 UserParameter =tomcat.discovery,/usr/bin/python /opt/zabbix/jmx_tomcat_discovery.pyUserParameter =tomcat.status[*],/bin/bash /opt/zabbix/tomcat_monitor.sh $1 $2 $3
添加/修改完成后,停止并重启 zabbix_agent
(我试过直接restart,有可能会出现无数据情况)
shell 1 2 # service zabbix-agent stop # service zabbix-agent start
测试,在 zabbix_server
端上使用 zabbix_get
测试 如果报权限错误无数据,请参考记一次zabbix_get远程执行取值为空问题
tomcat自动发现:zabbix_get -s 192.168.1.132 -p 10050 -k tomcat.discovery
tomcat_jmx监控数据源:zabbix_get -s 192.168.1.132 -p 10050 -k tomcat.status[mfa-rst,20020,jvmUptime]
zabbix_server 添加自动发现模板 在 zabbix web
上新增一个模板 并且新增一个发现规则 然后添加监控项目 按shell脚本 分组添加图表 详细内容触发器按个人需求自行添加
监控host 在host中导入模板 现在,可以在 configuration->hosts->ubuntu->items
中看到,已经自动添加了多个 tomcat
的监控项目
在 monitoring->screens
中添加图表后我们就可以看到相关信息了
参考文章: