基于prometheus的自定义达梦数据库监控

基于prometheus的自定义达梦数据库监控

 

 

红领巾2021-08-25编辑
407

概述

基于开源平台定制自己的达梦数据库监控产品安装及要求

责任数据库产品DBA

黄林杰 15658655447

环境要求

环境部署要求:

软件

版本

模块要求

备注

Python

Python 3.9.0

prometheus_client

dmPython

Grafana

7.4.2

页面展现平台

prometheus

prometheus-2.25

监控数据存储平台

dmdb-exporter.py

达梦数据库监控采集agent

dmdb_dashborad-v3.10.json

Grafana 页面展现dashboard模板

监控页面

目前监控项为:

Tps (每秒事务数)

会话信息(active,inactive,maxsession,idle session)

Dml 信息(select,insert,update,delete)

db load信息(db time cpu time,io 响应时间)

表空间信息

##监控页面:TPS,DML(select/insert/delete/update),dbtime,表空间监控

##监控页面:tps,会话状态

##监控页面:dml 页面

安装及部署

Python 环境安装:

1. 软件安装

2. Python 模块安装(prometheus_client,dmPython)

Grafana 安装及部署:

1.软件安装;

2.Dashboard 模板导入;

略;

Prometheus 安装及部署:

1.软件安装;

2.prometheus.yml 配置配置;

scrape_configs:

# The job name is added as a label `job=` to any timeseries scraped from this config.

- job_name: 'prometheus'

# metrics_path defaults to '/metrics'

# scheme defaults to 'http'.

static_configs:

- targets: ['localhost:9090']

- job_name: 'dmdb'

static_configs:

- targets: ['localhost:8000']

需要配置的内容如上

启动dmdb_exporter

各平台默认url 访问地址

#Prometheus

http://localhost:9090/

#grafana

http://127.0.0.1:3000/

#dmdb exporter:

http://127.0.0.1:8000/

修改dmdb-exporter.py 中要监控的达梦数据库连接信息:

启动dmdb_exporter

#python dmdb-exporter.py

回显信息如下:

C:\Python39\python.exe D:/python-project/workspace/dmdb-monitor/dmdb-exporter.py

### Starting dmdb_exporter v2021.3.1 --support:lixora@foxmail.com

2021-03-10 11:34:45 ***get_session_stat is done

2021-03-10 11:34:48 ***get_dml_stat is done

2021-03-10 11:34:50 ***get_load_stat is done

2021-03-10 11:34:52 ***get_tps_stat is done

2021-03-10 11:34:53 ***get_tbs_stat is done

******************work done******************

Process finished with exit code -1

产品代码

###############################################################

########  dmdb-exporter.py

###############################################################

# !usr/bin/env python
# -*- coding:utf-8 _*-
"""
@Author:huanglinjie
@phone:15658655447
@File:dmdb-exporter.py
@Time:2021/2/25 11:05

#Prometheus
http://localhost:9090/

#grafana
http://127.0.0.1:3000/


#dmdb exporter:
http://127.0.0.1:8000/


"""
import time
from prometheus_client import Counter, Gauge,start_http_server,Info
import dmPython

###lixora: debug flag
global debug
debug=0

###dmdb_info
user_name = "SYSDBA"
passwd = "sysdba_lixora"
server_name = "127.0.0.1"
server_port = 5236


dmdb_exporter_copyrights="\n ### Starting dmdb_exporter v2021.3.1 --support:lixora@foxmail.com \n"



dbtype=str(server_name)+'_'+str(server_port)
#print(dbtype)

sessionstat= Gauge('session_stat','diffferent stat session all in one',['type','DBINFO'])
dmlstat= Gauge('dml_stat','diffferent sql status all in one',['type','DBINFO'])
loadstat= Gauge('load_stat','diffferent dbtime/cputime/iotime load all in one',['type','DBINFO'])
tpsstat=Gauge('tps_stat','transaction per second',['type','DBINFO'])

# dbname=Gauge('dbname','db name',['dbname','DBINFO'])
# db_arch_mode=Gauge('db_arch_mode','db archive mode',['archmode','DBINFO'])
# db_uptime=Gauge('db_uptime','db up time',['uptime','DBINFO'])
# db_version=Gauge('db_version','db version',['dbversion','DBINFO'])



#base = Info('dmdbversion', 'Description of info')
#base.info({'数据库名':'lixora','数据库版本': '1.2.3', '数据库端口': '8888','归档模式':'N','数据库启动时间':'aaa'})

tbs = Gauge('tbs','tablespace use info',['tbsname','type','tbs_max_MB','tbs_size_MB','tbs_used_MB','tbs_free_MB','tbs_used_percent','tbs_ext_Used_percent','DBINFO'])







sql_session='''
(select para_name name,para_value value from v$dm_ini where para_name='MAX_SESSIONS')
union
(SELECT state name ,COUNT(*) value FROM SYS.V$SESSIONS group by state)
union
(SELECT 'Current SESSION',COUNT(*) SESSIONCOUNT FROM SYS.V$SESSIONS)
'''
sql_dml='''
select name,stat_val from v$SYSSTAT where name in ('select statements','insert statements','delete statements','update statements')
'''
sql_load='''
select name,stat_val from v$SYSSTAT where name in ('DB time(ms)','CPU time(ms)','io wait time(ms)')
'''
sql_tbs='''SELECT d.tablespace_name "Name",
d.contents "Type",
to_char(nvl(a.bytes / 1024 / 1024, 0), '99999999.9') "Total Ext Size (M)",
to_char(nvl(a.bytes2 / 1024 / 1024, 0), '99999999.9') "Total Size (M)",
to_char(nvl(a.bytes2 - nvl(f.bytes, 0), 0) / 1024 / 1024, '99999999.99') "Used (M)",
to_char(nvl(nvl(f.bytes, 0), 0) / 1024 / 1024, '99999999.99') "Free (M)",
to_char(nvl((a.bytes2 - nvl(f.bytes, 0)) / a.bytes2 * 100, 0),'990.99') "Used %",
to_char(nvl((a.bytes2 - nvl(f.bytes, 0)) / a.bytes * 100, 0),'990.99') "Ext_Used %"
FROM sys.dba_tablespaces d, (SELECT tablespace_name, SUM(greatest(BYTEs,MAXBYTES)) bytes,SUM(BYTES) bytes2 FROM dba_data_files GROUP BY tablespace_name) a, (SELECT tablespace_name, SUM(BYTES) bytes FROM dba_free_space GROUP BY tablespace_name) f WHERE d.tablespace_name = a.tablespace_name(+) AND d.tablespace_name = f.tablespace_name(+) order by 8,7 '''
sql_tps='''
select name,stat_val from v$SYSSTAT where name in ('transaction total count')'''
sql_base='''select * from (
select name, arch_mode,last_startup_time from v$database) ,
(select para_value from v$dm_ini where para_name='PORT_NUM'),
(select product_type from v$license)'''
# sql_port='''
# select para_value from v$dm_ini where para_name='PORT_NUM'''
# sql_version='''
# select * from v$version where rownum=1'''




##直接展现结果值
def get_base_stat():
dm_conn = dmPython.connect(user=user_name, password=passwd, server=server_name, port=server_port)
dm_cursor = dm_conn.cursor()
try:
dm_cursor.execute(sql_base)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
aa = dm_cursor.fetchone()


dm_cursor.close()
dm_conn.close()
print (aa)
dblastuptime=aa[2]
print(dblastuptime)
#base = Info('dmdb_version', 'Description of info')
#base.info({'数据库名': aa[0], '数据库版本': aa[4], '数据库端口': aa[3], '归档模式': aa[1], 'DBINFO': dbtype})
# dbname.labels(dbname=i[0],DBINFO=dbtype)
# db_arch_mode.labels(archmode=i[1],DBINFO=dbtype)
# db_uptime.labels(uptime=i[2],DBINFO=dbtype)

print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "***get_base_stat is done")



def get_tps_stat():
dm_conn = dmPython.connect(user=user_name, password=passwd, server=server_name, port=server_port)
dm_cursor = dm_conn.cursor()
try:
dm_cursor.execute(sql_tps)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
aa = dict(dm_cursor.fetchall())

#定时时间间隔2秒,取差值
time.sleep(2)

try:
dm_cursor.execute(sql_tps)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
bb = dict(dm_cursor.fetchall())

dm_cursor.close()
dm_conn.close()

#print ('aa-1:',aa)
#print ('bb-2:',bb)

# 遍历字典中的每一个key
for key in bb.keys():
#print(bb[key]-aa[key])
tpsstat.labels(type=key,DBINFO=dbtype).set(bb[key]-aa[key])
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "***get_tps_stat is done")


##直接展现结果值
def get_session_stat():
dm_conn = dmPython.connect(user=user_name, password=passwd, server=server_name, port=server_port)
dm_cursor = dm_conn.cursor()
try:
dm_cursor.execute(sql_session)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
aa = dm_cursor.fetchall()
dm_cursor.close()
dm_conn.close()
#print (aa)
for i in aa:
#print (i[0])
#print(i[1])
sessionstat.labels(type=i[0],DBINFO=dbtype).set(i[1])
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),"***get_session_stat is done")

#g.labels(hostip=host_ip).set(cup_use_percent) # 本机IP传入labels,CPU使用率传入value



##取2次查询差值
def get_dml_stat():
dm_conn = dmPython.connect(user=user_name, password=passwd, server=server_name, port=server_port)
dm_cursor = dm_conn.cursor()
try:
dm_cursor.execute(sql_dml)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
aa = dict(dm_cursor.fetchall())

#定时时间间隔2秒,取差值
time.sleep(2)

try:
dm_cursor.execute(sql_dml)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
bb = dict(dm_cursor.fetchall())

dm_cursor.close()
dm_conn.close()

#print ('aa-1:',aa)
#print ('bb-2:',bb)

# 遍历字典中的每一个key
for key in bb.keys():
#print(bb[key]-aa[key])
dmlstat.labels(type=key,DBINFO=dbtype).set(bb[key]-aa[key])
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "***get_dml_stat is done")


def get_load_stat():
dm_conn = dmPython.connect(user=user_name, password=passwd, server=server_name, port=server_port)
dm_cursor = dm_conn.cursor()
try:
dm_cursor.execute(sql_load)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
aa = dict(dm_cursor.fetchall())

#定时时间间隔2秒,取差值
time.sleep(2)

try:
dm_cursor.execute(sql_load)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
bb = dict(dm_cursor.fetchall())

dm_cursor.close()
dm_conn.close()

if debug:
print ('aa-1:',aa)
print ('bb-2:',bb)

# 遍历字典中的每一个key
for key in bb.keys():
if debug:
print(key)
#print(bb[key]-aa[key])
loadstat.labels(type=key,DBINFO=dbtype).set(bb[key]-aa[key])
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), "***get_load_stat is done")

#g.labels(hostip=host_ip).set(cup_use_percent) # 本机IP传入labels,CPU使用率传入value


def get_tbs_stat():
dm_conn = dmPython.connect(user=user_name, password=passwd, server=server_name, port=server_port)
dm_cursor = dm_conn.cursor()
try:
dm_cursor.execute(sql_tbs)
except Exception as e:
print(' dm_cursor.execute(...) Error: ', e)
aa = dm_cursor.fetchall()
dm_cursor.close()
dm_conn.close()

#print (aa)
for i in aa:
# print(i[0])
# print(i[1])
# print(i)

tbs.labels(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],dbtype)

print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),"***get_tbs_stat is done")




if __name__ == '__main__':
start_http_server(8000) # 8000端口启动
print(dmdb_exporter_copyrights)
while True:
get_session_stat()
get_dml_stat()
get_load_stat()
get_tps_stat()

get_tbs_stat()
#get_base_stat()
print('******************work done******************')

#自定义性能指标采集循环周期,默认5秒
time.sleep(5)

#########################################################

######       dmdb_dashborad-v3.10.json

#########################################################

{
"annotations": {
"list": [
{
"builtIn": 1,
"datasource": "-- Grafana --",
"enable": true,
"hide": true,
"iconColor": "rgba(0, 211, 255, 1)",
"name": "Annotations & Alerts",
"type": "dashboard"
}
]
},
"description": "DMDB advanced monitor powered by huanglj",
"editable": true,
"gnetId": null,
"graphTooltip": 0,
"id": 4,
"iteration": 1615341881106,
"links": [],
"panels": [
{
"datasource": "Prometheus",
"description": "dmdb session status",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 12,
"x": 0,
"y": 0
},
"id": 2,
"options": {
"graph": {},
"legend": {
"calcs": [
"max",
"min",
"mean"
],
"displayMode": "list",
"placement": "right"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.4.2",
"targets": [
{
"exemplar": false,
"expr": "session_stat",
"format": "time_series",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "dmdb session status(per/s)",
"type": "timeseries"
},
{
"datasource": "Prometheus",
"description": "tps(per/s)",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "smooth",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 6,
"w": 12,
"x": 12,
"y": 0
},
"id": 8,
"options": {
"graph": {},
"legend": {
"calcs": [
"max",
"min"
],
"displayMode": "list",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.4.2",
"targets": [
{
"expr": "tps_stat",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "TPS(per/s)",
"type": "timeseries"
},
{
"collapsed": false,
"datasource": null,
"gridPos": {
"h": 1,
"w": 24,
"x": 0,
"y": 6
},
"id": 16,
"panels": [],
"title": "Performance ",
"type": "row"
},
{
"datasource": "Prometheus",
"description": "DML status(per/s)",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "数值",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "smooth",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": false
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 24,
"x": 0,
"y": 7
},
"id": 4,
"options": {
"graph": {},
"legend": {
"calcs": [
"max",
"min",
"mean"
],
"displayMode": "table",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.4.2",
"targets": [
{
"exemplar": false,
"expr": "dml_stat",
"instant": false,
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "DML status(per/s)",
"type": "timeseries"
},
{
"datasource": "Prometheus",
"description": "dbtime/cputime/io_wait_time(ms)",
"fieldConfig": {
"defaults": {
"color": {
"mode": "palette-classic"
},
"custom": {
"axisLabel": "",
"axisPlacement": "auto",
"barAlignment": 0,
"drawStyle": "line",
"fillOpacity": 10,
"gradientMode": "none",
"hideFrom": {
"graph": false,
"legend": false,
"tooltip": false
},
"lineInterpolation": "linear",
"lineWidth": 1,
"pointSize": 5,
"scaleDistribution": {
"type": "linear"
},
"showPoints": "never",
"spanNulls": true
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "red",
"value": 80
}
]
},
"unit": "short"
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 0,
"y": 17
},
"id": 6,
"options": {
"graph": {},
"legend": {
"calcs": [
"min",
"max",
"mean"
],
"displayMode": "table",
"placement": "bottom"
},
"tooltipOptions": {
"mode": "single"
}
},
"pluginVersion": "7.4.2",
"targets": [
{
"expr": "load_stat",
"interval": "",
"legendFormat": "{{type}}",
"refId": "A"
}
],
"timeFrom": null,
"timeShift": null,
"title": "dbtime/cputime/io_wait_time(ms)",
"type": "timeseries"
},
{
"cacheTimeout": null,
"datasource": "Prometheus",
"description": "Tablespace Use Info",
"fieldConfig": {
"defaults": {
"color": {
"mode": "thresholds"
},
"custom": {
"align": null,
"displayMode": "auto",
"filterable": true
},
"mappings": [],
"thresholds": {
"mode": "absolute",
"steps": [
{
"color": "green",
"value": null
},
{
"color": "#EAB839",
"value": 100
}
]
}
},
"overrides": []
},
"gridPos": {
"h": 10,
"w": 12,
"x": 12,
"y": 17
},
"id": 14,
"interval": null,
"links": [],
"options": {
"frameIndex": 1,
"showHeader": true,
"sortBy": [
{
"desc": false,
"displayName": "instance"
}
]
},
"pluginVersion": "7.4.2",
"targets": [
{
"exemplar": false,
"expr": "tbs",
"format": "table",
"instant": true,
"interval": "",
"intervalFactor": 1,
"legendFormat": "",
"refId": "A"
}
],
"title": "Tablespace Use Info",
"type": "table"
}
],
"refresh": "5s",
"schemaVersion": 27,
"style": "dark",
"tags": [],
"templating": {
"list": [
{
"datasource": "",
"description": "display different dmdb server status",
"error": null,
"filters": [
{
"condition": "",
"key": "DBINFO",
"operator": "=",
"value": "127.0.0.1_5236"
}
],
"hide": 0,
"label": "DBINFO",
"name": "DBINFO",
"skipUrlSync": false,
"type": "adhoc"
}
]
},
"time": {
"from": "now-30m",
"to": "now"
},
"timepicker": {},
"timezone": "",
"title": "DMDB dashboard",
"uid": "ZYKex2yMk",
"version": 44
}

普罗米修斯是一个开源的监控系统,它可以用于监控各种不同类型的数据库,包括达梦数据库。要监控达梦数据库,你需要按照以下步骤进行操作: 1. 安装和配置普罗米修斯:首先,你需要从普罗米修斯的官方网站上下载并安装普罗米修斯。然后,你需要配置普罗米修斯的配置文件,以便连接和监控达梦数据库。 2. 配置达梦数据库监控端点:在达梦数据库中,你需要启用监控端点,以便普罗米修斯可以获取数据库的运行指标和状态信息。具体的配置步骤可以参考达梦数据库的文档或官方指南。 3. 配置普罗米修斯的数据源:在普罗米修斯的配置文件中,你需要添加达梦数据库作为一个数据源。你需要提供数据库的连接信息和认证凭据等必要信息。 4. 配置监控规则和警报:一旦配置好数据源,你可以通过普罗米修斯的查询语言PromQL来定义监控规则和警报。你可以根据自己的需求,定义一些指标阈值和触发警报的条件。 5. 可视化监控数据:普罗米修斯提供了一个自带的可视化工具Prometheus Dashboard,你可以使用它来查看达梦数据库监控数据,并进行图表展示和分析。 通过以上步骤,你就可以使用普罗米修斯来监控达梦数据库了。当达梦数据库的指标超过预设的阈值或出现异常时,普罗米修斯将会触发相应的警报通知你。希望对你有所帮助!如果还有其他问题,请随时提问。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值