python收集jvm数据
之前前辈用 java 写的收集 jvm 脚本, 不太方便组内小伙伴维护, 遂用 python 重写了
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Filename: jvm_monitor
# Description: collect jvm info
# Author: quke
# Date: 2018/8/22 import base64
import datetime
import json
import logging.handlers
import os
import random
import re
import socket
import time
from subprocess import Popen, PIPE import MySQLdb
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry logging.basicConfig(level=logging.INFO,
format='%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)s - %(funcName)20s() ] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
console_handler = logging.StreamHandler()
file_handler = logging.handlers.RotatingFileHandler('jvm_monitor.log', maxBytes=10485760, backupCount=5) logger = logging.getLogger(__name__)
logger.addHandler(file_handler) hostname = socket.gethostname() def run_command(cmd):
process = Popen(cmd, shell=True, stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
if stderr:
logger.error('Excepiton with run %s:%s' % (cmd, stderr))
raise SystemExit
else:
return stdout.strip('\n').split('\n') def requests_retry(
retries=3,
backoff_factor=0.3,
status_forcelist=(500, 502, 504),
session=None,
):
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session def execute_sql(sql, host='192.168.1.1', user='user', password='password', db='db'):
db = MySQLdb.connect(host, user, password, db)
cursor = db.cursor()
cursor.execute(sql)
if 'insert' in sql or 'update' in sql:
db.commit()
ret = cursor.fetchall()
cursor.close()
db.close()
return ret def get_all_mixed_info():
sql = 'select mixhost,module,alias from cmdb_mixed_relation'
db_detail = execute_sql(sql, host='192.168.1.1', user='user', password='password', db='db')
ret = {}
for obj in db_detail:
hostname, modulename, alias = obj
ret.setdefault(hostname, {}).update({modulename: alias}) return ret def get_java_module(args):
cur_dir = '/apps'
for d in os.listdir(cur_dir):
if os.path.isdir(os.path.join(cur_dir, d)):
if 'java' in d or 'boot' in d or 'tomcat' in d or 'mycat' in d:
if d in args:
return d def get_alias(module_name):
all_alias = get_all_mixed_info()
alias = all_alias.get(hostname, {}).get(module_name)
alias = alias if alias else 'null'
return alias def get_gc_collector_name(line):
for gc in ['UseParNewGC', 'UseG1GC', 'UseSerialGC', 'UseParallelGC']:
if gc in line:
ygc = gc
break
else:
ygc = 'ParNew' for gc in ['UseConcMarkSweepGC', 'UseG1GC', 'UseParallelOldGC', 'UseSerialGC']:
if gc in line:
ogc = gc
break
else:
ogc = 'CMS' return ygc, ogc def get_start_time(pid):
ret = run_command('ps -o lstart -p %s' % pid)
start_time = time.strftime('%Y-%m-%d %H:%M:%S', time.strptime(ret[1], '%a %b %d %H:%M:%S %Y'))
return start_time def get_jstat_info(pid):
ret = run_command('jstat -gc %s' % pid)
rc = re.compile(
r'(?P<s0c>[0-9.]+)\s+(?P<s1c>[0-9.]+)\s+(?P<s0u>[0-9.]+)\s+(?P<s1u>[0-9.]+)\s+(?P<ec>[0-9.]+)\s+(?P<eu>[0-9.]+)\s+(?P<oc>[0-9.]+)\s+(?P<ou>[0-9.]+)\s+(?P<pc>[0-9.]+)\s+(?P<pu>[0-9.]+)\s+(?P<jvmYgc>[0-9.]+)\s+(?P<jvmYgct>[0-9.]+)\s+(?P<jvmFgc>[0-9.]+)\s+(?P<jvmFgct>[0-9.]+)\s+(?P<jvmGct>[0-9.]+)')
gc_statistics = rc.match(ret[1]).groupdict()
return gc_statistics def get_thread_count(pid):
ret = run_command('jstat -snap %s' % pid)
active_thread_count = ret[-3].split('=')[1]
total_thread_count = ret[-1].split('=')[1]
return active_thread_count, total_thread_count def get_jvm_info():
instances = []
ret = run_command('jps -mlv')
for line in ret:
if line and 'sun.tools.jps.Jps' not in line and 'com.lagou.jmonitor.AgentWatcher' not in line:
module = get_java_module(line)
alias = hostname if module in hostname else get_alias(module) if 'null' == alias:
logger.error('[%s] can not get mixed module alias name , continue' % module)
continue ygc, ogc = get_gc_collector_name(line)
instances_list = line.split(' ')
pid = instances_list[0]
start_time = get_start_time(pid)
gc_statistics = get_jstat_info(pid)
active_thread_count, total_thread_count = get_thread_count(pid)
main_function = instances_list[1]
main_args = ' '.join(instances_list[2:])
instances.append(
dict(
pid=pid,
module=module,
alias=alias,
start_time=start_time,
gc_statistics=gc_statistics,
active_thread_count=active_thread_count,
total_thread_count=total_thread_count,
ygc=ygc,
ogc=ogc,
main_function=main_function,
main_args=main_args
)
)
return instances def push_to_oss(jvm):
modulename = jvm.get('module')
hostname = jvm.get('alias')
pid = jvm.get('pid')
mainclassname = jvm.get('main_function')
vmparam = jvm.get('main_args')
updated = jvm.get('start_time') gclist = json.dumps(
[dict(useTime=jvm['gc_statistics']['jvmYgct'], name=jvm['ygc'], times=jvm['gc_statistics']['jvmYgc']),
dict(useTime=jvm['gc_statistics']['jvmFgct'], name=jvm['ogc'], times=jvm['gc_statistics']['jvmFgc'])]) fgcygc = json.dumps(dict(jvmFgc=jvm['gc_statistics']['jvmFgc'],
jvmYgc=jvm['gc_statistics']['jvmYgc'],
jvmFgct=jvm['gc_statistics']['jvmFgct'],
jvmYgct=jvm['gc_statistics']['jvmYgct'], )) get_hostnames_sql = 'select hostname,modulename from jvmmonitordata where modulename="%s"' % modulename
ignore_hostname_ne_modulename = 'select hostname from jvmmonitordata where hostname="%s"' % hostname
logger.info('execute sql :%s' % get_hostnames_sql) is_existing = False
for obj in execute_sql(get_hostnames_sql):
if hostname in obj:
is_existing = True for obj in execute_sql(ignore_hostname_ne_modulename):
if hostname in obj:
is_existing = True if is_existing:
update_jvmmonitordata_sql = "update jvmmonitordata set pid=%d,gclist='%s',fgcygc='%s' where hostname='%s'" % (
int(pid), gclist, fgcygc, hostname)
logger.info('execute sql :%s' % update_jvmmonitordata_sql)
execute_sql(update_jvmmonitordata_sql)
else:
insert_jvmmonitordata_sql = "insert into jvmmonitordata(hostname,modulename,mainclassname,pid,vmparam,gclist,updated,fgcygc) values ('%s','%s','%s',%d,'%s','%s','%s','%s')" % (
hostname, modulename, mainclassname, int(pid), vmparam, gclist, updated, fgcygc)
logger.info('execute sql :%s' % insert_jvmmonitordata_sql)
execute_sql(insert_jvmmonitordata_sql) def get_hbase_svr():
hbase_list = ["http://192.168.100.1:8080", "http://192.168.100.2:8080", "http://192.168.100.3:8080"]
hbase_url = None
retry = 10
while retry > 0:
hbase_url = random.choice(hbase_list)
try:
r = requests.head(hbase_url, timeout=2)
except:
logger.info("connect" + hbase_url + "error, try another")
else:
if r.status_code == 200:
break
retry -= 1
if retry == 0:
logger.error("connect hbase failed with 10 times")
return hbase_url def build_hbase_data(jvm):
hostName = jvm['alias']
jvmEc = float(jvm['gc_statistics']['ec']) * 1000
jvmEu = float(jvm['gc_statistics']['eu']) * 1000
jvmOc = float(jvm['gc_statistics']['oc']) * 1000
jvmOu = float(jvm['gc_statistics']['ou']) * 1000
jvmPc = float(jvm['gc_statistics']['pc']) * 1000
jvmPu = float(jvm['gc_statistics']['pu']) * 1000
jvmSc = (float(jvm['gc_statistics']['s0c']) + float(jvm['gc_statistics']['s1c'])) * 1000
jvmSu = (float(jvm['gc_statistics']['s0u']) + float(jvm['gc_statistics']['s1u'])) * 1000
totalThreadCount = int(jvm['total_thread_count'])
activeThreadCount = int(jvm['active_thread_count']) return dict(
hostName=hostName,
jvmEc=int(jvmEc),
jvmEu=int(jvmEu),
jvmOc=int(jvmOc),
jvmOu=int(jvmOu),
jvmPc=int(jvmPc),
jvmPu=int(jvmPu),
jvmSc=int(jvmSc),
jvmSu=int(jvmSu),
totalThreadCount=totalThreadCount,
activeThreadCount=activeThreadCount,
) def jvm_hbase_constructor(jvm):
"""jvm hbase 数据构造器"""
data = build_hbase_data(jvm)
rows = []
json_rows = {"Row": rows}
row_key = base64.b64encode(data['hostName'] + ":" + datetime.datetime.now().strftime('%Y%m%d%H%M'))
cell = []
for column in ['jvmEc', 'jvmEu', 'jvmOc', 'jvmOu', 'jvmPc', 'jvmPu', 'jvmSc', 'jvmSu',
'totalThreadCount', 'activeThreadCount']:
cell.append({"column": base64.b64encode('jvm' + ":" + column), "$": base64.b64encode(str(data[column]))})
rows.append({'key': row_key, 'Cell': cell})
return row_key, json_rows def push_to_hbase(jvm):
table_name = 'jvm'
try:
row_key, json_rows = jvm_hbase_constructor(jvm)
except Exception as e:
logger.error("construct hbase data error %s" % str(e))
else:
for i in range(10):
hbase_url = get_hbase_svr()
try:
response = requests.post(hbase_url + '/' + table_name + '/' + row_key, data=json.dumps(json_rows),
headers={"Content-Type": "application/json", "Accept": "application/json"},
timeout=60)
if response.status_code == 200:
break
except:
pass
if i == 9:
logger.error("try to save hbase failed with 10 times,exit") def push_data(jvm_infos):
for jvm in jvm_infos:
push_to_oss(jvm)
push_to_hbase(jvm) if __name__ == '__main__':
jvm_infos = get_jvm_info()
push_data(jvm_infos)
python收集jvm数据的更多相关文章
- nGrinder对监控机器收集自定义数据及源码分析
转载:https://blog.csdn.net/neven7/article/details/50782451 0.背景 性能测试工具nGrinder支持在无需修改源码的情况下,对目标服务器收集自定 ...
- 通过Python将监控数据由influxdb写入到MySQL
一.项目背景 我们知道InfluxDB是最受欢迎的时序数据库(TSDB).InfluxDB具有 持续高并发写入.无更新:数据压缩存储:低查询延时 的特点.从下面这个权威的统计图中,就可以看出Influ ...
- Python收集这些视频只是单纯的想做做壁纸,大家不要误会
首先澄清一下,我用Python收集这些视频,绝不是想做别的什么,真的只是用来做动态壁纸,大家不要误会!我不是那样的人~ 这样的不过份吧 (这个动图看不看的到就看有没有缘分了 ) 阅读本文你需要准备 1 ...
- 使用Python解析JSON数据的基本方法
这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下: ----------------------------------- ...
- python matplotlib plot 数据中的中文无法正常显示的解决办法
转发自:http://blog.csdn.net/laoyaotask/article/details/22117745?utm_source=tuicool python matplotlib pl ...
- Python/Numpy大数据编程经验
Python/Numpy大数据编程经验 1.边处理边保存数据,不要处理完了一次性保存.不然程序跑了几小时甚至几天后挂了,就啥也没有了.即使部分结果不能实用,也可以分析程序流程的问题或者数据的特点. ...
- Windows下Python读取GRIB数据
之前写了一篇<基于Python的GRIB数据可视化>的文章,好多博友在评论里问我Windows系统下如何读取GRIB数据,在这里我做一下说明. 一.在Windows下Python为什么无法 ...
- 为什么说Python 是大数据全栈式开发语言
欢迎大家访问我的个人网站<刘江的博客和教程>:www.liujiangblog.com 主要分享Python 及Django教程以及相关的博客 交流QQ群:453131687 原文链接 h ...
- 用Python浅析股票数据
用Python浅析股票数据 本文将使用Python来可视化股票数据,比如绘制K线图,并且探究各项指标的含义和关系,最后使用移动平均线方法初探投资策略. 数据导入 这里将股票数据存储在stockData ...
随机推荐
- spring学习 十一 AspectJ-based的通知入门 不带参数的通知
AspectJ-Based方式的AOP,通知类不需要实现任何接口,且前置通知,后置通知,环绕通知,异常通知都可以写在一个类中,下面先实现一个简单的,不带参数的通知. 第一步定义通知类,通知类中的通知( ...
- 2018.11.05 bzoj2143: 飞飞侠(最短路)
传送门 最短路好题. 考虑对每个二维坐标建立一个高度属性. 这样每次如果在点(i,j,0)(i,j,0)(i,j,0)只能选择花费bi,jb_{i,j}bi,j跳向(i,j,ai,j)(i,j,a_ ...
- [zhuan]SQLServer查询最近一天,三天,一周,一月,一季度方法
三天 select * from T_news where datediff(day,addtime,getdate())<= 2 and datediff(day,addtime,getdat ...
- springboot 程序发布到tomcat运行
springboot 一般使用jar 的方式运行,我们需要将程序放到tomcat环境下运行. 步骤如下: 1.修改pom文件. 排除内置的tomcat <dependency> <g ...
- Mybatis之动态构建SQL语句(转)
https://www.cnblogs.com/zhangminghui/p/4903351.html
- MFC随笔
设置映射模式 Y轴改为向上 dc.SetMapMode(MM_LOENGLISH);//低精度 dc.SetMapMode(MM_HIENGLISH);//高精度 文本对齐 dc.SetTextAl ...
- VIP之FrameBuffer
2.VIP Frame Buffer 1.原来我是一直存在一个疑惑,demo上说VIP Frame Buffer输出是固定的60fps,但是在NiosII的程序中我没有找到设置输出为60fps的设置 ...
- poj 1068 Parencodings 模拟题
Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encoded in two diff ...
- SDIBT 2345 (3.2.1 Factorials 阶乘)
Description N的阶乘写作N!表示小于等于N的所有正整数的乘积.阶乘会很快的变大,如13!就必须用32位整数类型来存储,70!即使用浮点数也存不下了.你的任务是找到阶乘最后面的非零位.举个例 ...
- HTML中JavaScript调用方法
我在写web页面的时候,经常用js实现某些功能,我用的方法有两种: 1.点击调用JavaScript: <button onclick="loadXMLDoc()">b ...