一、设计
公司设备较多,有时需要匹配一些设备之间的关系。这里以NAS存储和主机之间的关联关系。存储都分了那些lun,给了哪些主机使用?理清这些关系如果全靠纯手工来做是比较繁琐的。这时候可以借助自动化工具+采集脚本,自动完成入库操作即可。定期的跑下任备就行了。
使用df -t nfs输出并排除首行的说明,内容如下:
192.168.7.252:/HYMANAGER 197G 130G 68G 66% /logs
192.168.7.253:/fs_hymanager 493G 241G 252G 49% /home/hymanager/share_files
数据库表设计:
CREATE TABLE `nas` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`hostname` varchar(30) NOT NULL,
`ipaddr` varchar(20) NOT NULL,
`nasip` varchar(30) NOT NULL,
`naslun` varchar(100) NOT NULL,
`size` varchar(40) NOT NULL,
`used` varchar(40) NOT NULL,
`avail` varchar(40) NOT NULL,
`usepercent` varchar(10) NOT NULL,
`mounted` varchar(100) NOT NULL,
`upday` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构如下:
二、web api
表设计好了,也可以通过从主机上取数据了。接下来就写个API 主动可以接受入库数据。代码如下:
package main
import (
"bytes"
"database/sql"
"fmt"
"net/http"
"github.com/gin-gonic/gin"
_ "github.com/go-sql-driver/mysql"
)
func main() {
db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/gotest")
if err != nil {
fmt.Print(err.Error())
}
defer db.Close()
// make sure connection is available
err = db.Ping()
if err != nil {
fmt.Print(err.Error())
}
router := gin.Default()
// POST new person details
router.POST("/nfs", func(c *gin.Context) {
hostname := c.PostForm("hostname")
ipaddr := c.PostForm("ipaddr")
nasip := c.PostForm("nasip")
naslun := c.PostForm("naslun")
size := c.PostForm("size")
used := c.PostForm("used")
avail := c.PostForm("avail")
usepercent := c.PostForm("usepercent")
mounted := c.PostForm("mounted")
stmt, err := db.Prepare("insert into nas (hostname,ipaddr,nasip,naslun,size,used,avail,usepercent,mounted) values(?,?,?,?,?,?,?,?,?);")
if err != nil {
fmt.Print(err.Error())
}
_, err = stmt.Exec(hostname, ipaddr, nasip, naslun, size, used, avail, usepercent, mounted)
if err != nil {
fmt.Print(err.Error())
}
// Fastest way to append strings
defer stmt.Close()
c.JSON(http.StatusOK, gin.H{
"message": fmt.Sprintf("successfully created"),
})
})
router.Run(":3000")
}
此时通过curl 入库时会报错:error on parse multipart form array: invalid URL escape “%” ,查看发现是使用百分比一项,由于有特殊符号%号导致无法成功入库该项的值。
三、解决入库报错
这里有几种方法可借操作:1、将百分号去掉;2、使用xxd就是进行URLencode转换;3、使用curl自身的转码方式进行URLencode转码。
第一种方式实现代码如下:
ipaddr=`curl http://10.212.149.204/myip`
df -t nfs -hP|sed 's/[:%]/ /g'|awk 'NR>1{print $0}' | while read nasip naslun size used avail usepercent mounted
do
curl -d "hostname=$HOSTNAME&ipaddr=$ipaddr&nasip=$nasip&naslun=$naslun&size=$size&used=$used&avail=$avail&usepercent=$usepercent&mounted=$m
ounted" http://10.212.52.14:3000/nfs
done
第二种方式代码类似如下:
ipaddr=`curl http://10.212.149.204/myip`
df -t nfs -hP|sed 's/:/ /g'|awk 'NR>1{print $0}' | while read nasip naslun size used avail usepercent mounted
do
percent=`echo "$usepercent" | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g'`
echo $percent
echo "hostname=$HOSTNAME&ipaddr=$ipaddr&nasip=$nasip&naslun=$naslun&size=$size&used=$used&avail=$avail&usepercent=$percent&mounted=$mounted"
curl -d "hostname=$HOSTNAME&ipaddr=$ipaddr&nasip=$nasip&naslun=$naslun&size=$size&used=$used&avail=$avail&usepercent=$percent&mounted=$mounted" http://10.212.52.14:3000/nfs
done
第三种方式具体可以参考:
三种方式了我选择了第一种,好处就是便于进行百分比使用率查询。比如使用select 语名查询时,想要查询百分比使用大于多少或少于多少的,直接使用比较运算符就可以了。
结合现网的自动化工具,5分钟内就可以完成几千台数据的采集入库。入库完成后,再配合python pandas模块分容易的就可以通过查询数据库输出为excel文件
from sqlalchemy import create_engine
import time
import pandas as pd
today = time.strftime("%Y%m%d", time.localtime())
engine = create_engine('mysql+pymysql://root:passwd@localhost:3306/gotest')
sql = "select * from nas where upday=today";
dsql=pd.read_sql(sql,con = engine)
dsql.to_excel("nfs.xlsx",index=False)
再通过邮件定时更新该数据表。具体结果如下(点击图片看大图):