
自从prometheus监控oracle的文章发出后,好多朋友留言咨询讨论oracle监控的技术知识,这里也汇总整理了一期资料,作为对读者朋友的回馈,本文主要介绍oracle exporter的无侵入部署,部署过oracle exporter的朋友都知道,当前的exporter是不支持11G,12C数据库环境的,部署时需要替换成18C的库文件,这个小小的操作在生产环境通常是不被允许的,经过深入学习,发现我们是可以通过另外一种方式去取代的,数据库上仅需要开放监控用户即可,实现无需数据库其他操作,提升了安全保险性。
这里核心用到的一个环境变量是DSN,该环境变量的作用是告诉exporter往哪里链接,如下配置。
DATA_SOURCE_NAME=username/password@tcps://dbhost:port/service
在默认部署版本中,我们将该环境变量添加到.bash_profile文件中。如果我们将exporter部署到其他机器,不在数据库服务器部署,那么同样,仅需要将DSN告诉exporter即可。这里我推荐将exporter部署到prometheus服务器,管理方便。
如果在prometheus服务器部署oracle exporter,则我们需要需要在该服务器部署oracle客户端,供exporter调用。不同数据库对应的exporter,我们通过给exporter指定不同的端口即可做区分。
简单介绍安装oracle客户端:
准备如下三个安装包,通过rpm -ivh安装即可。
[root@Prometheus oracle]# lltotal 104900-rw-r--r-- 1 oracle oracle 51434432 Oct 25 11:13 oracle-instantclient18.3-basic-18.3.0.0.0-3.x86_64.rpm-rw-r--r-- 1 root root 610364 Oct 25 11:23 oracle-instantclient18.3-devel-18.3.0.0.0-3.x86_64.rpm-rw-r--r-- 1 root root 709700 Oct 25 11:12 oracle-instantclient18.3-sqlplus-18.3.0.0.0-3.x86_64.rpm[root@Prometheus oracle]#
添加环境变量,这里如果创建oracle用户,就加入到oracle用户家目录的.bash_profile文件,如果用root,则加入到root用户家目录下的.bash_profile。
export ORACLE_HOME=/usr/lib/oracle/18.3/client64export PATH=$PATH:/usr/lib/oracle/18.3/client64/binexport LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib
测试使用sqlplus是否正常执行:
[oracle@Prometheus ~]$ sqlplussqlplus: error while loading shared libraries: libnsl.so.1: cannot open shared object file: No such file or directory[oracle@Prometheus ~]$
如上图,就是缺包报错,这里推荐使用ldd查看缺少的具体是哪个文件,然后针对性安装缺少的包。
[oracle@Prometheus ~]$ ldd sqlplusldd: ./sqlplus: No such file or directory[oracle@Prometheus ~]$ ldd usr/lib/oracle/18.3/client64/bin/sqlpluslinux-vdso.so.1 (0x00007ffcee967000)libsqlplus.so => /usr/lib/oracle/18.3/client64/lib/libsqlplus.so (0x00007f78c6b8d000)libclntsh.so.18.1 => /usr/lib/oracle/18.3/client64/lib/libclntsh.so.18.1 (0x00007f78c2c1b000)libclntshcore.so.18.1 => /usr/lib/oracle/18.3/client64/lib/libclntshcore.so.18.1 (0x00007f78c2639000)libmql1.so => /usr/lib/oracle/18.3/client64/lib/libmql1.so (0x00007f78c23d9000)libipc1.so => /usr/lib/oracle/18.3/client64/lib/libipc1.so (0x00007f78c1f6a000)libnnz18.so => /usr/lib/oracle/18.3/client64/lib/libnnz18.so (0x00007f78c1815000)libdl.so.2 => /lib64/libdl.so.2 (0x00007f78c1611000)libm.so.6 => /lib64/libm.so.6 (0x00007f78c128f000)libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f78c106f000)libnsl.so.1 => not foundlibrt.so.1 => /lib64/librt.so.1 (0x00007f78c0e66000)libaio.so.1 => /lib64/libaio.so.1 (0x00007f78c0c63000)libresolv.so.2 => /lib64/libresolv.so.2 (0x00007f78c0a4c000)libc.so.6 => /lib64/libc.so.6 (0x00007f78c0688000)libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f78c0470000)libnsl.so.1 => not foundlibons.so => /usr/lib/oracle/18.3/client64/lib/libons.so (0x00007f78c0220000)lib64/ld-linux-x86-64.so.2 (0x00007f78c6e81000)libnsl.so.1 => not foundlibnsl.so.1 => not found[oracle@Prometheus ~]$ yum repolist */libnsl.so.1
如上报错,我们单独安装libns1.so.1即可
yum -y install libnsl.so.1
此时,我们在prometheus安装oracle exporter后,就可以声明一个DSN,然后启动。如下:
export DATA_SOURCE_NAME=....nohup /app/monitor/exporter/oracledb_exporter -default.metrics /app/monitor/exporter/single-metrics.toml -web.listen-address :9161 -query.timeout 10 1>9161.log 2>&1 &"
如上,我们启动大量的exporter可能非常费时间,管理也不方便。这里我自己写了一个脚本进行集中管理,包含一个脚本,和一个DSN记录文件。
这里分享给大家:
#Oracle exporter 参数文件#配置说明:# 每行代表一个exporter的参数# DSN: 被监控数据库连接信息# Port: exporter 启动端口,每个exporter唯一,建议从9161开始使用# SQLTIMEOUT: SQL执行查询超时时间设置,建议10s# RAC?: 数据库是否为rac环境,1表示是,0表示不是。根据此状态自动选择对应采集项文件# YEWU: 是否启用业务监控脚本,1表示启用,0表示不启用##Exporter List:## DSN Port SQLTIMEOUT RAC? YEWU#---------------------------------------- ----- ----------- ----- -----dbsnmp/dbsnmp@192.168.100.100:1521/dbname 9161 10 1 1
管理脚本:
#!/bin/bash## 创建日期: 2021-10-27# 创建人员:Kevin YAN# 当前版本: 1.3## 脚本说明:# 该脚本实现无侵入部署oracle exporter的日常启停及查看功能## 更新日志记录######################################################################################################### 变更日期 变更人员 变更内容#------------------ ------------ -----------------------------------------------------------------------# 2021/11/21 Kevin YAN 增加过滤参数文件exporter.ini中空行及注释行,解决存在空行时脚本报错问题;# 2021/11/26 Kevin YAN 增加oracle单机,rac调用不同metrics文件,增加是否启用业务metrics;# 2021/12/23 Kevin YAN 增加参数目录,使兼容mysql exporter无侵入部署;###########################################################################################################声明ORACLE Client环境变量export ORACLE_HOME=/usr/lib/oracle/18.3/client64export PATH=$PATH:/usr/lib/oracle/18.3/client64/binexport LD_LIBRARY_PATH=/usr/lib/oracle/18.3/client64/lib#配置相关路径,如果部署路径发生改变,仅修改路径即可init_dir='/app/monitor/scripts'log_dir='/app/monitor/log'#配置oracle相关路径oracledb_exporter='/app/monitor/exporter/oracledb_exporter'rac_metrics_path='/app/monitor/exporter/rac-metrics.toml'single_metrics_path='/app/monitor/exporter/single-metrics.toml'yewu_metrics_path='/app/monitor/exporter/yewu-metrics.toml'#过滤配置文件中空行及注释行if [ -f $init_dir/exporter-oracle.ini ]; thenegrep -v '^#|^$' $init_dir/exporter-oracle.ini > tmp/.exporter-oracle.inioracle_init_file='/tmp/.exporter-oracle.ini'fi#全局声明位置变量arg1=$1arg2=$2arg3=$3#定义帮助函数usage(){cat <<EOFUsage: $0 [Options] [Options]-list List all oracle exporter in exporter-oracle.ini-start-ip Specify you will start oracle exporter of ip;-port Specify you will start oracle exporter of port;all start all instance in exporter.ini-stop-ip Specify you will stop oracle exporter of ip;-port Specify you will stop oracle exporter of port;all stop all instance in exporter-oracle.iniEOFexit 1}#定义展示函数#展示当前配置文件中配置的数据源exporter状态list_active_exporter(){printf "\n%-28s %-6s %-9s %-6s %-6s %-15s %-30s\n" "Instance" "Port" "Timeout" "Rac?" "Yewu" "Status" "Log"echo "--------------------------- ------ --------- ------ ------ -------- -----------------------------------------------"while read linedodsn=$(echo "${line}" |awk '{print $1}')port=$(echo "${line}" |awk '{print $2}')query_timeout=$(echo "${line}" |awk '{print $3}')rac=$(echo "${line}" |awk '{print $4}')yewu=$(echo "${line}" |awk '{print $5}')status=$(ps -ef | grep oracledb| grep $port | wc -l )instance=$(echo "$dsn" | awk -F"@" '{print $2}')if [ "$status" -eq 1 ]; thenprintf "%-28s %-9s %-8s %-6s %-4s %-7s %-30s\n" "$instance" "$port" "$query_timeout" "$rac" "$yewu" "Active" "$log_dir/$port.log"elseprintf "%-28s %-9s %-8s %-6s %-4s %-7s %-30s\n" "$instance" "$port" "$query_timeout" "$rac" "$yewu" "Dead" "$log_dir/$port.log"fidone < $oracle_init_fileecho "-------------------------------------------------------------------------------------------------------------------"}#定义全部exporter启动函数#启动exprter.ini文件中配置的所有exporterall_exporter_start(){while read linedodsn=$(echo "${line}" |awk '{print $1}')port=$(echo "${line}" |awk '{print $2}')query_timeout=$(echo "${line}" |awk '{print $3}')instance=$(echo "$dsn" | awk -F"@" '{print $2}')rac=$(echo "${line}" |awk '{print $4}')yewu=$(echo "${line}" |awk '{print $5}')status=$(ps -ef | grep oracledb | grep $port | wc -l )if [ "$status" -eq 1 ]; thenprintf "$instance Started,not need to be executed again.\n"elseprintf "Starting $instance ...\n"echo "echo env racvalue:"$racif [ "$rac" -eq 2 ]; thendefault_metrics="-default.metrics $rac_metrics_path"elsedefault_metrics="-default.metrics $single_metrics_path"fiif [ "$yewu" -eq 1 ]; thencustom_metrics="-custom.metrics $yewu_metrics_path"elsecustom_metrics=""fiexport DATA_SOURCE_NAME=$dsneval "nohup $oracledb_exporter $default_metrics $custom_metrics -web.listen-address :$port -query.timeout $query_timeout 1>$log_dir/$port.log 2>&1 &"if [ $? -eq 0 ]; thenprintf "Success started $instance \n"elseprintf "Fail started, For more information, please see file: $log_dir/$port.log\n"fifidone < $oracle_init_file}#定义启动单一exporter函数#启动exprter.ini文件中配置的某一个exporter,支持ip和端口两种方式启动single_exporter_start(){instance_info=$(grep $arg3 $oracle_init_file)dsn=$(echo "${instance_info}" |awk '{print $1}')query_timeout=$(echo "${instance_info}" |awk '{print $3}')rac=$(echo "${instance_info}" |awk '{print $4}')yewu=$(echo "${instance_info}" |awk '{print $5}')instance=$(echo "$dsn" | awk -F"@" '{print $2}')if [ -z "$instance_info" ]; thenecho "$arg3 not exist in $init_dir/exporter-oracle.ini"break;elseport=$(echo "${instance_info}" |awk '{print $2}')status=$(ps -ef | grep oracledb | grep $arg3 | wc -l )if [ "$status" -eq 1 ]; thenprintf "$instance Started,not need to be executed again.\n"elseprintf "Starting $instance ... \n"if [ "$rac" -eq 1 ]; thendefault_metrics="-default.metrics $rac_metrics_path"elsedefault_metrics="-default.metrics $single_metrics_path"fiif [ "$yewu" -eq 1 ]; thencustom_metrics="-custom.metrics $yewu_metrics_path"elsecustom_metrics=""fiexport DATA_SOURCE_NAME=$dsneval "nohup $oracledb_exporter $default_metrics $custom_metrics -web.listen-address :$port -query.timeout $query_timeout 1>$log_dir/$port.log 2>&1 &"if [ $? -eq 0 ]; thenprintf "Success started $instance \n"elseprintf "Fail started, For more information, please see file: $log_dir/$port.log\n"fififi}#定义关闭exporter函数#关闭exprter.ini文件中配置的全部exporterall_exporter_stop(){pkill oracledb}#定义关闭单一exporter函数#关闭exprter.ini文件中配置的某一个exporter,支持ip和端口两种方式关闭single_exporter_stop(){instance_info=$(grep $arg3 $oracle_init_file)dsn=$(echo "${instance_info}" |awk '{print $1}')instance=$(echo "$dsn" | awk -F"@" '{print $2}')if [ -z "$instance_info" ]; thenecho "$arg3 not exist in $init_dir/exporter-oracle.ini"break;elseport=$(echo "${instance_info}" |awk '{print $2}')status=$(ps -ef | grep oracledb | grep $arg3 | wc -l )if [ "$status" -eq 1 ]; thenps -ef | grep oracledb | grep $port | awk '{print $2}'| xargs kill -9if [ $? -eq 0 ]; thenprintf "Success stop $instance \n"fielseecho "Instance $instance is not started,not need stop."fifi}#定义主函数#实现脚本输入不同参数实现不同功能case $arg1 in-list|-l|-LIST|-L)list_active_exporter;;;-start|-START)case $arg2 in-ip|-IP)single_exporter_startlist_active_exporter;;-port|-p|-PORT|-P)single_exporter_startlist_active_exporter;;all)all_exporter_startlist_active_exporter;;*)exit;;;esac;;-stop|-STOP)case $arg2 in-ip|-IP)single_exporter_stoplist_active_exporter;;-port|-p|-PORT|-P)single_exporter_stoplist_active_exporter;;all)all_exporter_stoplist_active_exporter;;*)exit;;;esac;;*)usage;;esac
脚本逻辑为,自动解析DSN文件,然后针对行启动或停止。
脚本目前支持查看列表,启动/停止单个exporter,启动/停止所有exporter。
使用方式:
sh exporter_manager.sh -list --查看列表,来源DSN记录文件sh exporter_manager.sh -start -ip 192.168.100.100 --启动单个sh exporter_manager.sh -start -port 9161 --启动单个sh exporter_manager.sh -start all --启动所有sh exporter_manager.sh -stop -ip 192.168.100.100 --停止单个sh exporter_manager.sh -stop -port 9161 --停止单个sh exporter_manager.sh -stop all --停止所有
如上启动完成后,prometheus配置文件需将db的监控ip,修改为prometheus服务器IP,端口同样修改,保证prometheus能链接到修改后的exporter服务上。
如上,便实现了oracle exporter的外迁,避免了在数据库服务器的改动。核心原理便是理解DSN的作用,然后进行外迁,通过不同端口来区分不同的DB,实现整体的无侵入部署。
值得一提的是,mysql的监控同样支持该方法。本文仅提供一个思路,该思路方案,已经在大量客户环境实际使用。感兴趣的朋友可以自己测试,也可找作者交流。
更多技术细节,欢迎关注公众号联系作者交流。

关注更多精彩




