最近收到了一个需求, 要统计一个域名在一段时间内, A记录的变化.
由于今年学了go, 所以所有的需求都优先考虑用go实现. 下面是源代码
package main import ( "flag" "fmt" "log" "net" "os" "time" ) var ( url string dns []net.IP interval int intervalTime time.Duration changeInterval int temp net.IP consolePrint bool dnsSlice []string count int Max int Min int Avg int changeSlice []int ) func removeDuplicateElement(slice []string) []string { result := make([]string, 0, len(slice)) temp := map[string]struct{}{} for _, item := range slice { if _, ok := temp[item]; !ok { temp[item] = struct{}{} result = append(result, item) } } return result } func main() { flag.IntVar(&interval, "i", 10, "dns解析地址, 时间间隔, 单位秒") flag.StringVar(&url, "d", "", "要解析的url") flag.BoolVar(&consolePrint, "p", false, "是否打印在标准输出") flag.Parse() if url == "" { flag.Usage() os.Exit(1) } file, err := os.Create("log.txt") if err != nil { fmt.Println("没有权限创建日志文件") os.Exit(1) } startTime := time.Now() intervalTime = time.Duration(interval) * time.Second var lastDns []string = nil var ipSlice []string = nil log.SetOutput(file) for { dns, err = net.LookupIP(url) if err != nil { log.Printf("解析错误: %v", err) continue } now := time.Now().Format("2006-01-02 15:04:05") //把解析的ipv4 地址构成数组 dnsSlice = []string{} for _, i := range dns { if temp = i.To4(); temp == nil { continue } dnsSlice = append(dnsSlice, i.String()) ipSlice = append(ipSlice, dnsSlice...) } if lastDns == nil { lastDns = dnsSlice if consolePrint { fmt.Printf("%s %s的解析是: %v\n", now, url, dnsSlice) } changeInterval = 0 log.Printf("%s的解析是: %v\n", url, dnsSlice) } else { var flag bool = false lastDnsLen := len(lastDns) dnsSliceLen := len(dnsSlice) if lastDnsLen != dnsSliceLen { flag = true } else { tNum := 0 for _, i := range lastDns { for _, j := range dnsSlice { if i == j { tNum += 1 break } } } if tNum != lastDnsLen { flag = true } } if flag { ipSlice = append(ipSlice, dnsSlice...) ipSlice = removeDuplicateElement(ipSlice) count += 1 if Min == 0 { Min = changeInterval } if changeInterval < Min { Min = changeInterval } if changeInterval > Max { Max = changeInterval } changeSlice = append(changeSlice, changeInterval) x := 0 for _, i := range changeSlice { x += i } Avg = x / len(changeSlice) if consolePrint { fmt.Printf("%s %s解析发生了变化: %v -> %v, 间隔了%d秒\n", now, url, lastDns, dnsSlice, changeInterval) fmt.Printf("%s 当前已经变化过的ip地址有%d个, 列表: %v\n", now, len(ipSlice), ipSlice) fmt.Printf("%s 已经监控了%d秒, 解析变化了%d次, 解析变化间隔列表:%v, 解析变化最长间隔%d秒, 最短%d秒, 平均%d秒\n", now, int(time.Since(startTime).Seconds()), count, changeSlice, Max, Min, Avg) } log.Printf("%s解析发生了变化: %v -> %v, 间隔了%d秒\n", url, lastDns, dnsSlice, changeInterval) log.Printf("当前已经变化过的ip地址有%d个, 列表: %v", len(ipSlice), ipSlice) log.Printf("已经监控了%d秒, 解析变化了%d次, 解析变化间隔列表:%v, 解析变化最长间隔%d秒, 最短%d秒, 平均%d秒\n", int(time.Since(startTime).Seconds()), count, changeSlice, Max, Min, Avg) lastDns = dnsSlice changeInterval = 0 } else { if consolePrint { fmt.Printf("%s %s的解析是: %v\n", now, url, dnsSlice) } log.Printf("%s的解析是: %v\n", url, dnsSlice) } } time.Sleep(intervalTime) changeInterval += interval } }
由于是go写的,所以可以编译成exe和二进制程序, 可以直接运行在linux和windows上, 非常方便
选项
- -d 要监控的域名 //必填
- -i 间隔 //可选, 给定一个数字, 默认10, 单位秒
- -p 输出在标准输出 // 可选, 默认不输出
基本用法
monitorDNS.exe -d 域名
运行后默认无限循环, 会在运行目录生成一个log.txt文件, 监控指定域名的A记录解析变化, 会统计A记录变化的频率,以及最大,最小,平均值, 并收集所有出现过的A记录

发表回复