需求
- 一个后台Java程序启动时,可以在配置文件中配置线程数量。需要获取线程数量和线程名进行校验。
思路
- 读取配置文件,获得配置的线程数量。
- 获取该java程序的进程pid
- 通过jstack 获取该进程的线程详情并重定向至文件
- python 读取该文件并进行分析
实现
该java程序会将pid写入一个文件中,所以直接读取该文件获得pid即可。此处将上述的2、3使用shell脚本实现。
#! /bin/bash
pid=`cat tpid`
jstack $pid >> ./$pid.txt
python 读取该文件并进行分析
# -*- coding: utf-8 -*-
import re
import json
import subprocess
import sys
reload(sys)
sys.setdefaultencoding('utf8')
def get_real_threads_name_list(jstack_file): #从jstack log中获取实际的线程数及线程名
log_file = open(jstack_file, 'r')
pattern = re.compile('"(.*)"')
real_threads_name_list = pattern.findall(log_file.read())
log_file.close()
print json.dumps(real_threads_name_list, encoding='utf-8', ensure_ascii=False)
return real_threads_name_list
def is_chinese(param_list): #判断是否中文
real_threads_num = 0
for i in param_list:
if u'\u4e00' <= i <= u'\u9fff':
real_threads_num += 1
return real_threads_num
def get_application_threads_num(file_path): #从配置文件读取配置的线程数量
application_yaml = open(file_path)
application_threads_num = 0
application = yaml.load(application_yaml)
if application['frms.etl.pay']['enable']:
application_threads_num += application['frms.etl.pay']['threadSize']
if application['frms.pay.auditobj']['enable']:
application_threads_num += application['frms.pay.auditobj']['threadsize']
if application['frms.pay.ds']['enable']:
application_threads_num += application['frms.pay.ds']['threadsize']
if application['frms.pay']['streamcube.publish.enable']:
application_threads_num += application['frms.pay']['dsobj']['threadsize']
if application['frms']['pay.etl']['cloud.call']:
application_threads_num += application['frms']['etl.data.service']['threadSize']
application_threads_num += application['frms.etl.scheduled.threadSize']
application_yaml.close()
return application_threads_num
def compare(a, b): #比较
if a == b:
print 'ok'
else:
print 'not ok'
if __name__ == '__main__':
subprocess.call('pid_log.sh', shell=True) #调用shell脚本
real_threads_nums = is_chinese(get_real_threads_name_list('H:\\scripts\\jstack19666.txt'))
application_threads_nums = get_application_threads_num(
'application(1).yml')
compare(real_threads_nums, application_threads_nums)
新需求
通过jstack远程连接服务器
还没实现