之前前辈用 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数据的更多相关文章

  1. nGrinder对监控机器收集自定义数据及源码分析

    转载:https://blog.csdn.net/neven7/article/details/50782451 0.背景 性能测试工具nGrinder支持在无需修改源码的情况下,对目标服务器收集自定 ...

  2. 通过Python将监控数据由influxdb写入到MySQL

    一.项目背景 我们知道InfluxDB是最受欢迎的时序数据库(TSDB).InfluxDB具有 持续高并发写入.无更新:数据压缩存储:低查询延时 的特点.从下面这个权威的统计图中,就可以看出Influ ...

  3. Python收集这些视频只是单纯的想做做壁纸,大家不要误会

    首先澄清一下,我用Python收集这些视频,绝不是想做别的什么,真的只是用来做动态壁纸,大家不要误会!我不是那样的人~ 这样的不过份吧 (这个动图看不看的到就看有没有缘分了 ) 阅读本文你需要准备 1 ...

  4. 使用Python解析JSON数据的基本方法

    这篇文章主要介绍了使用Python解析JSON数据的基本方法,是Python入门学习中的基础知识,需要的朋友可以参考下:     ----------------------------------- ...

  5. python matplotlib plot 数据中的中文无法正常显示的解决办法

    转发自:http://blog.csdn.net/laoyaotask/article/details/22117745?utm_source=tuicool python matplotlib pl ...

  6. Python/Numpy大数据编程经验

    Python/Numpy大数据编程经验 1.边处理边保存数据,不要处理完了一次性保存.不然程序跑了几小时甚至几天后挂了,就啥也没有了.即使部分结果不能实用,也可以分析程序流程的问题或者数据的特点.   ...

  7. Windows下Python读取GRIB数据

    之前写了一篇<基于Python的GRIB数据可视化>的文章,好多博友在评论里问我Windows系统下如何读取GRIB数据,在这里我做一下说明. 一.在Windows下Python为什么无法 ...

  8. 为什么说Python 是大数据全栈式开发语言

    欢迎大家访问我的个人网站<刘江的博客和教程>:www.liujiangblog.com 主要分享Python 及Django教程以及相关的博客 交流QQ群:453131687 原文链接 h ...

  9. 用Python浅析股票数据

    用Python浅析股票数据 本文将使用Python来可视化股票数据,比如绘制K线图,并且探究各项指标的含义和关系,最后使用移动平均线方法初探投资策略. 数据导入 这里将股票数据存储在stockData ...

随机推荐

  1. Android——编译release版签名系统

    http://blog.csdn.net/jscese/article/details/24243171 在我的第一篇博客里面http://blog.csdn.net/jscese/article/d ...

  2. 前端之javascript的DOM对象和标签

    一 DOM对象介绍 什么是HTML DOM 1.1 HTML Document Object Model(文档对象模型) 1.2 HTML DOM 定义了访问和操作HTML文档的标准方法. 1.3 H ...

  3. Linux网桥模式配置

    Linux网关模式下将有线LAN和无线LAN共享网段实现局域网内互联: 思路其实很简单:就是将虚拟出一个bridge口,将对应的有线LAN和无线LAN都绑定在这个虚拟bridge口上,并给这个brid ...

  4. python 函数学习sys.argv[]

    sys.argv 参数 「argv」是「argument variable」参数变量的简写形式,一般在命令行调用的时候由系统传递给程序.这个变量其实是一个List列表,argv[0] 一般是“被调用的 ...

  5. 2018.12.19 atcoder Iroha and a Grid(组合数学)

    传送门 组合数学好题. 给你一个hhh行www列的网格,其中左下角aaa行bbb列不能走,问从左上角走到右下角有多少种走法(每次只能向右或者向下) 我们考虑分步计数. 我们一共能走的区域是总网格区域去 ...

  6. MySQL按日、周、月统计数据

    知识关键词:DATE_FORMAT ps:如果时间字段为时间戳则,DATE_FORMAT(from_unixtime(create_time),'%Y-%u') select DATE_FORMAT( ...

  7. 端口报错listen eaddrinuse:::xxx

    端口报错 listen eaddrinuse:::xxx 表示这个端口被占用 结束正在使用此端的程序即可.

  8. TCP粘包问题分析和解决(全)

    TCP通信粘包问题分析和解决(全) 在socket网络程序中,TCP和UDP分别是面向连接和非面向连接的.因此TCP的socket编程,收发两端(客户端和服务器端)都要有成对的socket,因此,发送 ...

  9. 构造函数的prototype和constructor属性

    Car.prototype = { name:'BMW', height:1400, long:4900 } function Car(color,owner){ this.color = color ...

  10. ng-repeat动态改变样式

    当我们使用AngularJs的ng-repeat时候动态绑定数据时,遇到遍历出来的标签样式都一样,这时候希望根据数组的下标分别对应不同的样式 解决:使用$index获取数组下标根据下标改变样式 < ...