[打造自己的监控系统]使用pandas处理数据获取Oracle系统状态趋势并格式化为highcharts需要的格式
开发环境
操作系统:CentOS 7.4 Python版本 :3.6 Django版本: 1.10.5 操作系统用户:oms 数据处理:pandas 前端展示:highcharts
通过上面我们已经知道了如何使用Django获取数据库的系统状态信息并将其存入redis数据库
这节讲如何使用pandas处理数据获取Oracle系统状态趋势
1. HighCharts格式要求
这里以官网的折线图为例
从上面代码可以看出我们可以自定义的内容有:
- title:标题
- subtitle:子标题
- yAxis: Y轴内容
- xAxis: X轴内容(图中为显示)
- series:具体的内容,是个列表,列表中的元素为字典,字典包含name和data键,键对应的值也为列表,每个name代表一条线
所以最后我们传递给template的值需要包含上面的内容,其中title,subtilt,yAxis内容我们通过赋值的方式
xAxis以及series的内容我们通过pandas处理后的数据得到
具体方法见下面讲解
2. Oracle系统状态趋势获取原理
通过前面的章节我们获取了每个小时v$sysstat视图里面的数据,这里我以DBTime=10.65.1.119=DCPROD为例,具体数据如下图
冒号左边代表时间,采用Unix时间戳的形式
冒号右边为DBTime的值
这里我们分2部分讲解
- 一个是以天为单位进行分组,计算每天的DBTime差值
- 一个是以小时为单位进行分组,计算一天中每小时之间的差值
2.1 以天/周为单位
1. 首先遍历redis中对应的Key的列表的值,将符合时间段的提取出来,之后将取出来的值处理后格式化成pandas的DataFrame格式
注意:如果有天没有监控数据则不会有该日期,解决方法下面有讲
result=pd.DataFrame({'week':dweek,'date':ddate,'time':dtime,'value':dvalue})
可以看到我们将日期和周别单独提取出来了
2. 接下来我们以date或week来进行分组
day_df=result['value'].groupby(result['date'])
3. 接下来我们将分组value的第一个值减去最后一个值得到该天的DBTime数值
day_result=(day_df.first() - day_df.last())/unit
4. 接下来将得到的差值的结果以及日期转换成列表再次格式化成DataFrame格式
series_reindex=pd.DataFrame({'date':day_result.index.values.tolist(),'value':day_result.values.tolist()})
5. 之后将dataframe的index值变为date的值
series_reindex.set_index('date',inplace=True)
6. 为防止有天数未有值导致画图不准确,需要将该dataframe重新index下
例如我要查看12/1-12/20的趋势,如果12/10监控系统故障导致没有数据,这时上面出来的结果是没有12/10这一天的,这时我们需要强制reindex下,将12/10这天的差值设为0
这里的x为根据前后时间段算出来的天数、
s=series_reindex.reindex(x,fill_value=0)
7. 最后我们将结果变成highcharts所需要的格式
series_singal['name']=key series_singal['data']= s['value'].values.tolist() series_singal['x']=s.index.values.tolist()
2.2 以小时为单位
1. 首先遍历redis中对应的Key的列表的值,将符合时间段的提取出来,之后将取出来的值处理后格式化成pandas的DataFrame格式
注意:如果有的小时没有监控数据则不会有该日期,如12/14 11:00 解决方法下面有讲
2. 接下来我们以date来进行分组
day_df=result.groupby(result['date'])
3. 之后遍历分组的名称(name)和分组值(group)
每次迭代的值代表一天的24小时,
4. 之后对每一天的24小时进行索引重新设置及填充,这里填充的是平均值
group.set_index('time',inplace=True) s=group.reindex(new_index,fill_value=group['value'].mean())
5. 接下来我们需要将这24小时计算差值(25个值)
采用的方法很简单,就是将25个值的列表错位拆分为2个列表,之后相减
j=flist[1:] k=flist[0:-1] for i in range(0,len(j)): flist1.append(j[i]-k[i])
6. 最后我们将结果变成highcharts所需要的格式
series_singal['name']=name final_series.append(series_singal)
源代码位置
欢迎访问我的github主页查看源码
https://github.com/bsbforever/oms_django
monitor/command/views_performance.py中的loadprofile_highcharts函数
monitor/command/views_oracleperformance.py中的oracle_performance_day函数
下节为如何讲如何在前端显示
- cocos2dx-v3.5 2048 (一): 项目架构
- cocos2dx-v3.5 2048 (二): GameTool的设计与实现
- cocos2dx-v3.5 2048(三):菜单实现
- 2017 LCTF WriteUp 4篇
- cocos2dx-v3.4 2048(四):单元格的设计与实现
- javascript - 闭包
- Java 反射简单实例
- [安全入门教学]如何分析海洋CMS漏洞
- Java 回调函数的使用
- Android 配置Freeline教程
- 如何用JS写一个table组件 | 作业讲解
- Mac 高效工作指南
- Jarvis OJ平台basic部分writeup
- React Native之打包
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法