暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

【ORACLE】在plsql中通过几条简单的命令生成运维可视化图表html页面

原创 DarkAthena 2021-12-02
1137

前言

其实本来不想写这篇的,因为这对于前端的入门开发者再简单不过了,只是因为最近看到一位DBA老哥为了生成图表各种折腾,又联想起我原来所在公司的DBA经常找我请教一些自动化流程如何用sql或者plsql实现,实在是忍不住了。

业务报表或者运维报表的自动生成,在一些公司应该是基本操作,开发语言用java的、php的、python的,五花八门,甚至还有直接bat或者shell写静态html的。至于优秀的可视化报表图表平台,更是数不胜数了。只要找个开发问问,没准他几分钟内就帮你搞定了,甚至还可以自动发邮件、企业微信、钉钉等。

找不到开发人员?自己也不会其他开发语言?没关系,HTML总会吧?在数据库里用字符串拼出一个html页面不难吧?

直接上代码

--生成测试数据 create table TEST_AREA_CHART2 ( sample_time VARCHAR2(8), metric_name VARCHAR2(23), value NUMBER ); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('12:00:00', 'Instance Foreground CPU', 1); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('12:00:00', 'Instance Background CPU', 4); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('12:00:00', 'Non-Database Host CPU', 7); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('12:00:00', 'Load Average', 10); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('11:00:00', 'Instance Foreground CPU', 2); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('11:00:00', 'Instance Background CPU', 5); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('11:00:00', 'Non-Database Host CPU', 8); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('11:00:00', 'Load Average', 11); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('10:00:00', 'Instance Foreground CPU', 3); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('10:00:00', 'Instance Background CPU', 6); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('10:00:00', 'Non-Database Host CPU', 9); insert into test_area_chart2 (SAMPLE_TIME, METRIC_NAME, VALUE) values ('10:00:00', 'Load Average', 12); commit; --创建一个HTML生成函数 create function test_area_chart_func return clob is l_clob clob; l_legend varchar2(32000); l_xAxis varchar2(32000); l_series varchar2(32000); begin l_clob := q'{ <!DOCTYPE html> <html style="height: 100%"> <head><meta charset="utf-8"></head> <body style="height: 100%; margin: 0"> <div id="container" style="height: 100%"></div> <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/echarts@5.2.2/dist/echarts.min.js"></script> <script type="text/javascript"> var dom = document.getElementById("container"); var myChart = echarts.init(dom); var app = {}; var option; option = {title: {text: 'Stacked Area Chart'}, tooltip: { trigger: 'axis', axisPointer: {type: 'cross',label: {backgroundColor: '#6a7985'}}}, legend: {data: [##legend##]}, toolbox: {feature: {saveAsImage: {}}}, grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true}, xAxis: [{type: 'category',boundaryGap: false,data: [##xAxis##]}], yAxis: [{type: 'value'}], series: [##series##] }; if (option && typeof option === 'object') { myChart.setOption(option); } </script> </body> </html>}'; select listagg(distinct '''' || a.sample_time || '''', ',') within GROUP(order by sample_time) g into l_xAxis from test_area_chart2 a; select listagg(distinct '''' || a.METRIC_NAME || '''', ',') into l_legend from test_area_chart2 a; select listagg(a) into l_series from (select q'{ {name: '}' || METRIC_NAME || q'{',type: 'line',stack: 'Total',areaStyle: {},data: [}' || listagg(value, ',') within GROUP(order by sample_time)|| q'{]} ,}' a from test_area_chart2 where metric_name <> 'Load Average' group by METRIC_NAME union all select q'{ {name: '}' || METRIC_NAME || q'{',type: 'line',stack: 'Total',data: [}' || listagg(value, ',') within GROUP(order by sample_time)|| q'{]} }' from test_area_chart2 where metric_name = 'Load Average' group by METRIC_NAME); l_clob := replace(l_clob, '##legend##', l_legend); l_clob := replace(l_clob, '##xAxis##', l_xAxis); l_clob := replace(l_clob, '##series##', l_series); return l_clob; end; / --获取函数返回的html页面 select test_area_chart_func from dual;

页面效果

https://www.darkathena.top/test/test_area_chart.html
image.png
实现原理就是调用开源的图表js组件echarts,手动拼个html。

上面这个函数也就随手一写,主要是验证其可行性,没有针对特殊场景做兼容开发。如果功能要更加全面的话,完全可以把各种选项参数化,封装成一个具有完整功能的plsql包。而且在12c以后也不需要使用字符串拼接json了,直接可以用json语法操作,甚至在21c版本还可以用dbms_mle功能调用js直接返回对应的图片。就算不是21c版本,在ORACLE的apex里写写简单的代码也是可以实现的,甚至还能直接做成动态刷新的页面。最后再搞个大屏显得高大上。

最后提个问题

DBA是否应该至少掌握一门除plsql以外的开发语言?

严格来说,我不是DBA,也不是开发岗位,在之前公司主要是做erp软件运维及业务咨询。由于遇到了和Tim Hall老哥类似的原因

You end up spending loads of time doing things that you are crap at, because your “crap” is better than other people’s “good”

我尝试自己开发各种工具来补齐IT部门工作中的短板,当时的确是没有开发人员,只能自己上(吐槽一下,近十万员工的公司连开发都找不到。。。),所以咨询、设计、开发、运维一个人“全栈”了。而实践证明,懂运维的人开发的运维工具,会比不经常运维的开发人员开发出来的工具用起来更顺手。

所以我对这个问题的回答是,DBA们利用空闲时间去多掌握一门对自己工作有帮助的技能,何乐而不为呢?

最后修改时间:2021-12-02 21:18:27
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论