【bashスクリプト実行】OSのリソース情報を取得してmysqlに取り込みする



## 背景
ZabbixやDatadogなど、エージェントをインストールすることにより、OSのリソース情報を取得することが可能です。
しかしながら、エージェントを入れるだけでリソースが枯渇する事象が発生したため、エージェントなしでのリソース情報を取得します。
（本来であれば、CPUのコア数、メモリを増やせば解消するのですが、1つのサーバに多種のミドルウェアを入れている場合、CPUやメモリ不足に陥ることがあります。）
今回、bashスクリプトオンリーでOSの統計情報を取得し、結果をデータベースに取り込みするスクリプトを作成しました。

## 実施内容

### 前提
vmstat、ss、mongodb、mysqlをインストールします。インストール済みなら不要です。

### ログ内容のMongoDBへのインポート
ログファイルをMongoDBに挿入します。
* /root/logaggregation.log、/root/tmpCountResult.txt：特に使っていないので削除してもよいです。
* /root/tmpLogList.log：mongodbへインサートするログをまとめるためのファイル
* /root/logList.conf：インサートしたいファイル（フルパス）の一覧を記載
* /root/monthList.conf：月（ローマ字3文字）から、年月を取得するための対比一覧
* /root/tmploginsertinsert.js：mongodbへインサートするためのファイル。

```[root@homeserver ~]# cat log_insert_data.sh
#!/bin/bash
allAggregationLogs=/root/logaggregation.log
tmpLogList=/root/tmpLogList.log
logListConfig=/root/logList.conf
monthListConfig=/root/monthList.conf
tmpCountResult=/root/tmpCountResult.txt
tmpLogInsertJavascriptFile=/root/tmploginsertinsert.js
tmpCronLogFile=/root/tmpCronLog.log

###Filterlizedlog
cat /var/log/cron | grep 'CMD\ ' > ${tmpCronLogFile}
for filename in `cat ${logListConfig}`
do
  grep -h "" ${filename} > ${tmpLogList}
  cat /dev/null > ${tmpLogInsertJavascriptFile}
  while read sentences
  do
    tmpMonth=`echo ${sentences} | awk -F ' ' '{print $1}'`
    tmpYearMonth=`grep ${tmpMonth} ${monthListConfig} | awk -F ',' '{print $2}'`

    tmpdatetime=`echo ${tmpYearMonth}`"-"`echo ${sentences} | awk -F ' ' '{print $2" "$3}'`
    tmphostname=`echo ${sentences} | awk -F ' ' '{print $4}'`
    tmpcontents=`echo ${sentences} | awk '{for(i=5;i<NF;++i){printf("%s ",$i)}print $NF}' | sed "s/'/''/g"`
    echo "db.logdata.update({ datetimecol: \""${tmpdatetime}"\", logfilename: \""${filename}"\", hostname: \""${tmphostname}"\", logcontent: \""${tmpcontents}"\"}, {\$inc: {hits: 1}},  {upsert:true}); " >> ${tmpLogInsertJavascriptFile}
  done < ${tmpLogList}
  mongo admin -u homeserver_ana -p <パスワードは秘密！> < ${tmpLogInsertJavascriptFile}
  rm -f ${tmpLogList}
done

####mongo admin -u homeserver_ana -p <パスワードは秘密！> < ${tmpLogInsertJavascriptFile}
rm -f ${tmpCronLogFile}
```

### 仮想メモリやCPU、ディスクI/Oの統計情報（vmstat）をMySQLのデータベースへインポート

```[root@homeserver ~]# cat os_stat_vmstat.sh
#!/bin/bash
#for urlname in `cat ${urlConfiguration} | awk -F ',' '{print $1}'`
#do
  #inputKeyword=`grep ${urlname} ${urlConfiguration} | awk -F ',' '{print $2}'`
  inputExectime=`date +%Y-%m-%d\ %H:%M:%S`
  insertVmstatCurrentData=`vmstat 1 1 | tail -2 | awk -F ' ' '{print $1","$2","$3","$4","$5","$6","$7","$8","$9","$10","$11","$12","$13","$14","$15","$16","$17}' | tail -1`
  echo \'${inputKeyword}\',\'${inputExectime}\',\'${insertVmstatCurrentData}\'
  echo "insert into os_vmstat values (current_timestamp,${insertVmstatCurrentData});"
  _password=`cat /root/.pgpassword_for_maindb `
  mysql -h 127.0.0.1 -u root -p$_password --database=maindb -e "insert into os_vmstat values (current_timestamp,${insertVmstatCurrentData});"
  #PGPASSWORD=`cat .pgpassword_for_maindb` psql -h 127.0.0.1 -U maindb -d maindb -c "insert into os_vmstat values (current_timestamp,${insertVmstatCurrentData});"
  #PGPASSWORD=`cat .pgpassword_for_maindb` psql -h 127.0.0.1 -U maindb -d maindb -c "insert into apache_bench_stat values ('${inputKeyword}',current_timestamp,${inputTimeperrequest});"
#done

[root@homeserver ~]#
```

### ディスク使用率（df -k）をMySQLのデータベースへインポート
df -kコマンドで監視し、mysqlのテーブルに挿入しています。
・/root/_tmp_diskusagecurrent.txt：df -kの内容を記載。
```[root@homeserver ~]# cat os_stat_diskusage.sh
#!/bin/bash
inputExectime=`date +%Y-%m-%d\ %H:%M:%S`
diskUsageTmpfile=/root/_tmp_diskusagecurrent.txt
cat /dev/null > ${diskUsageTmpfile}
df -k | awk -F ' ' '{print $1","$2","$3","$4","$5","$6}' | sort | head -n-1 > ${diskUsageTmpfile}
while read sentences
do
  filesystem=`echo ${sentences} | awk -F ',' '{print $1}'`
  disk1k_blocksize=`echo ${sentences} | awk -F ',' '{print $2}'`
  useamount=`echo ${sentences} | awk -F ',' '{print $3}'`
  diskavailable=`echo ${sentences} | awk -F ',' '{print $4}'`
  diskutil=`echo ${sentences} | awk -F ',' '{print $5}' | sed 's/%//g' `
  mountpoint=`echo ${sentences} | awk -F ',' '{print $6}'`
  sqlinputonesentence=`echo \'${inputExectime}\',\'${filesystem}\',${disk1k_blocksize},${useamount},${diskavailable},${diskutil},\'${mountpoint}\'`
  echo ${sqlinputonesentence}
  _password=`cat /root/.pgpassword_for_maindb `
  mysql -h 127.0.0.1 -u root -p$_password --database=maindb -e "insert into os_diskuseinfo values (${sqlinputonesentence});";
  #PGPASSWORD=`cat .pgpassword_for_maindb` psql -h 127.0.0.1 -U maindb -d maindb -c "insert into os_diskuseinfo values (${sqlinputonesentence});"
done < ${diskUsageTmpfile}
rm -fv ${diskUsageTmpfile}
echo $?
[root@homeserver ~]#
```

### ホストのネットワーク接続状態（netstat）をMySQLのデータベースへインポート
ポート番号毎に、同時接続している数を確認し、MySQLへインサートするためのスクリプトです。
* /root/netstatus.conf：netstatの状態でLISTEN、TIMEWAITなど状態を一覧化しているファイル
* /root/portnumbers.conf：監視したいポートを記載するファイル
```[root@homeserver ~]# cat os_stat_netstat.sh
#!/bin/bash
inputExectime=`date +%Y-%m-%d\ %H:%M:%S`
configureNetStatus=/root/netstatus.conf
configurePortNumbers=/root/portnumbers.conf
tmpCurrentNetstat=/root/aaaa.txt
cat /dev/null > ${tmpCurrentNetstat}
for netstatus in `cat ${configureNetStatus}`
do
  for portnumber in `cat ${configurePortNumbers} | awk -F ',' '{print $1}'`
  do
    portNumberName=`grep ${portnumber} ${configurePortNumbers} | awk -F ',' '{print $2}'`
    netstat_count_status=`netstat -an | grep ${portnumber} | grep ${netstatus} | grep -v grep | wc -l`
    insertNetstatCurrentData=`echo ${portnumber},\'${portNumberName}\',\'${netstatus}\',${netstat_count_status}`
    echo "insert into os_netstat values (current_timestamp,${insertNetstatCurrentData});"
    _password=`cat /root/.pgpassword_for_maindb `
    mysql -h 127.0.0.1 -u root -p$_password --database=maindb -e "insert into os_netstat values (current_timestamp,${insertNetstatCurrentData});"
    #PGPASSWORD=`cat .pgpassword_for_maindb` psql -h 127.0.0.1 -U maindb -d maindb -c "insert into os_netstat values (current_timestamp,${insertNetstatCurrentData});"
  done
done
[root@homeserver ~]#
```

## Metabaseでの可視化
metabaseとは、データベースを可視化するためのBIツールです。
kibana、grafanaなど、可視化ツールはさまざまありますが、metabaseはjavaさえあれば動くのと、扱えるデータベースが多岐にあること、ピボットテーブルやグラフのようにExcelで提供している機能と同じようなことが可能です。
※ zabbixのようなダッシュボードみたいに見える化できます。
※ 下の図はMetabaseで可視化したホストのネットワーク接続状態（netstat）になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/551020/7641afb2-785d-1a76-adae-e58c98a9d16d.png)



※ Metabaseのインストール方法については後述します。