NAS数据的自动采集
一、设计
公司设备较多,有时需要匹配一些设备之间的关系。这里以NAS存储和主机之间的关联关系。存储都分了那些lun,给了哪些主机使用?理清这些关系如果全靠纯手工来做是比较繁琐的。这时候可以借助自动化工具+采集脚本,自动完成入库操作即可。定期的跑下任备就行了。
使用df -t nfs输出并排除首行的说明,内容如下:
1192.168.7.252:/HYMANAGER 197G 130G 68G 66% /logs
2192.168.7.253:/fs_hymanager 493G 241G 252G 49% /home/hymanager/share_files
数据库表设计:
1CREATE TABLE `nas` (
2 `id` int(11) NOT NULL AUTO_INCREMENT,
3 `hostname` varchar(30) NOT NULL,
4 `ipaddr` varchar(20) NOT NULL,
5 `nasip` varchar(30) NOT NULL,
6 `naslun` varchar(100) NOT NULL,
7 `size` varchar(40) NOT NULL,
8 `used` varchar(40) NOT NULL,
9 `avail` varchar(40) NOT NULL,
10 `usepercent` varchar(10) NOT NULL,
11 `mounted` varchar(100) NOT NULL,
12 `upday` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
13 PRIMARY KEY (`id`)
14) ENGINE=InnoDB DEFAULT CHARSET=utf8;
表结构如下:
二、web api
表设计好了,也可以通过从主机上取数据了。接下来就写个API 主动可以接受入库数据。代码如下:
1package main
2import (
3 "bytes"
4 "database/sql"
5 "fmt"
6 "net/http"
7 "github.com/gin-gonic/gin"
8 _ "github.com/go-sql-driver/mysql"
9)
10func main() {
11 db, err := sql.Open("mysql", "root:password@tcp(127.0.0.1:3306)/gotest")
12 if err != nil {
13 fmt.Print(err.Error())
14 }
15 defer db.Close()
16 // make sure connection is available
17 err = db.Ping()
18 if err != nil {
19 fmt.Print(err.Error())
20 }
21 router := gin.Default()
22 // POST new person details
23 router.POST("/nfs", func(c *gin.Context) {
24 hostname := c.PostForm("hostname")
25 ipaddr := c.PostForm("ipaddr")
26 nasip := c.PostForm("nasip")
27 naslun := c.PostForm("naslun")
28 size := c.PostForm("size")
29 used := c.PostForm("used")
30 avail := c.PostForm("avail")
31 usepercent := c.PostForm("usepercent")
32 mounted := c.PostForm("mounted")
33 stmt, err := db.Prepare("insert into nas (hostname,ipaddr,nasip,naslun,size,used,avail,usepercent,mounted) values(?,?,?,?,?,?,?,?,?);")
34 if err != nil {
35 fmt.Print(err.Error())
36 }
37 _, err = stmt.Exec(hostname, ipaddr, nasip, naslun, size, used, avail, usepercent, mounted)
38 if err != nil {
39 fmt.Print(err.Error())
40 }
41 // Fastest way to append strings
42 defer stmt.Close()
43 c.JSON(http.StatusOK, gin.H{
44 "message": fmt.Sprintf("successfully created"),
45 })
46 })
47 router.Run(":3000")
48}
此时通过curl 入库时会报错:error on parse multipart form array: invalid URL escape “%” ,查看发现是使用百分比一项,由于有特殊符号%号导致无法成功入库该项的值。
三、解决入库报错
这里有几种方法可借操作:1、将百分号去掉;2、使用xxd就是进行URLencode转换;3、使用curl自身的转码方式进行URLencode转码。
第一种方式实现代码如下:
1ipaddr=`curl http://10.212.149.204/myip`
2df -t nfs -hP|sed 's/[:%]/ /g'|awk 'NR>1{print $0}' | while read nasip naslun size used avail usepercent mounted
3do
4 curl -d "hostname=$HOSTNAME&ipaddr=$ipaddr&nasip=$nasip&naslun=$naslun&size=$size&used=$used&avail=$avail&usepercent=$usepercent&mounted=$m
5ounted" http://10.212.52.14:3000/nfs
6done
第二种方式代码类似如下:
1ipaddr=`curl http://10.212.149.204/myip`
2df -t nfs -hP|sed 's/:/ /g'|awk 'NR>1{print $0}' | while read nasip naslun size used avail usepercent mounted
3do
4 percent=`echo "$usepercent" | tr -d '\n' | xxd -plain | sed 's/\(..\)/%\1/g'`
5 echo $percent
6 echo "hostname=$HOSTNAME&ipaddr=$ipaddr&nasip=$nasip&naslun=$naslun&size=$size&used=$used&avail=$avail&usepercent=$percent&mounted=$mounted"
7 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
8done
第三种方式具体可以参考:
三种方式了我选择了第一种,好处就是便于进行百分比使用率查询。比如使用select 语名查询时,想要查询百分比使用大于多少或少于多少的,直接使用比较运算符就可以了。
结合现网的自动化工具,5分钟内就可以完成几千台数据的采集入库。入库完成后,再配合python pandas模块分容易的就可以通过查询数据库输出为excel文件
1from sqlalchemy import create_engine
2import time
3import pandas as pd
4today = time.strftime("%Y%m%d", time.localtime())
5engine = create_engine('mysql+pymysql://root:passwd@localhost:3306/gotest')
6sql = "select * from nas where upday=today";
7dsql=pd.read_sql(sql,con = engine)
8dsql.to_excel("nfs.xlsx",index=False)
再通过邮件定时更新该数据表。具体结果如下(点击图片看大图):
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/nasmount-collect/6398.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.