一、falcon磁盘IO告警计算方法

(1)线上告警示例
【falcon】环境: prod 时间: 2018-11-10 22:29 共1条
【#主机磁盘io过高(appid)】主机hostname磁盘dfa io过高98.76>98%
(2)cat /proc/diskstats
252 0 dfa 2689642164 0 513826977162 100403006 6803204529 0 1348198360088 2893131263 0 934780608 3002409596
每项的具体含义如下:
1 252 主设备号 code:Major
2 0 次设备号 code:Minor
3 dfa 设备名称 code:Name
4 2689642164 <1>读完成次数{读磁盘的次数,成功完成读的总次数}[2689642164] code:ReadIOs
5 0 <2>合并读完成次数 code:ReadMerges
6 513826977162 <3>读扇区的次数,成功读过的扇区总次数 5.ReadSectors
7 100403006 <4>读花费的毫秒数;这是所有读操作所花费的毫秒数{从__make_request()到end_that_request_last()的测量} code:ReadTicks
8 6803204529 <5>写完成次数;写完成的次数,成功写完成的总次数 code:WriteIOs
9 0 <6>合并写完成次数。为了效率可能会合并相邻的读和写,从而两次4K的读在它最终被处理到磁盘上之前可能会变成一次8K的读,才被计数(和排队),因此只有一次I/O操作,这个域使你知道这样的操作有多频繁 code:WriteMerges
10 1348198360088 <7>写扇区次数;写扇区的次数,成功写扇区总次数 code:WriteSectors
11 2893131263 <8>写操作花费的毫秒数;写花费的毫秒数,这是所有写操作所花费的毫秒数{是从__make_request()到end_that_request_last()的测量} code:WriteTicks
12 0 <9>正在处理的输入/输出请求数;I/O的当前进度,只有这个域应该是0.当请求被交给适当的request_queue_t时增加和请求完成时减小 code:InFlight
13 934780608 <10>输入/输出操作花费的毫秒数;花在I/O操作上的毫秒数,只要field9不为0这个域就会增长 code:IOTicks
14 3002409596 <11>输入/输出操作花费的加权毫秒数;花在I/O操作上的毫秒数,在每次I/O开始,I/O结束,I/O合并或读取自动上次更新这个域以来(第<9>列正在进行的io数量乘以花费在io上的毫秒数)时这个域都会增加.这可以给I/O完成时间和存储那些可以累积的提供一个便利的测量标准 code:TimeInQueue
(3)告警计算公式
io_ticks{crt.IOTicks - last.IOTicks(上10s的值)}/100 > 98 会进行报警

二、实现代码

(1)
const diskStatPath = "/proc/diskstats" type DiskStatCollector struct {
lastDiskStats map[string]*linux.DiskStat
} func (c *DiskStatCollector) Collect() ([]*model.Metric, error) {
if c.lastDiskStats == nil {
c.lastDiskStats = make(map[string]*linux.DiskStat)
}
disks, err := linux.ReadDiskStats(diskStatPath)
if err != nil {
return nil, fmt.Errorf("collect disk stat: %v", err)
}
var metrics []*model.Metric
for _, crt := range disks {
if len(crt.Name) == 3 && (strings.HasPrefix(crt.Name, "sd") || strings.HasPrefix(crt.Name, "vd") || strings.HasPrefix(crt.Name, "df")) {
if last, ok := c.lastDiskStats[crt.Name]; ok {
metrics = append(metrics, diskStatDiff(&crt, last)...)
}
tmp := crt
c.lastDiskStats[crt.Name] = &tmp
}
}
return metrics, nil
} func diskStatDiff(crt *linux.DiskStat, last *linux.DiskStat) []*model.Metric {
var metrics []*model.Metric
if crt.IOTicks < last.IOTicks {
return metrics
}
metrics = append(metrics, &model.Metric{
Name: "disk.io",
Fields: []*model.Field{
{"read_ios", model.Gauge, crt.ReadIOs - last.ReadIOs},
{"read_merges", model.Gauge, crt.ReadMerges - last.ReadMerges},
{"read_sectors", model.Gauge, crt.ReadSectors - last.ReadSectors},
{"read_ticks", model.Gauge, crt.ReadTicks - last.ReadTicks},
{"write_ios", model.Gauge, crt.WriteIOs - last.WriteIOs},
{"write_merges", model.Gauge, crt.WriteMerges - last.WriteMerges},
{"write_sectors", model.Gauge, crt.WriteSectors - last.WriteSectors},
{"write_ticks", model.Gauge, crt.WriteTicks - last.WriteTicks},
{"in_flight", model.Gauge, crt.InFlight - last.InFlight},
{"io_ticks", model.Gauge, crt.IOTicks - last.IOTicks},
{"time_in_queue", model.Gauge, crt.TimeInQueue - last.TimeInQueue},
},
Tags: map[string]string{"name": crt.Name},
Timestamp: utils.Timestamp(),
})
return metrics
} (2) // ReadDiskStats reads and parses the file.
//
// Note:
// * Assumes a well formed file and will panic if it isn't.
func ReadDiskStats(path string) ([]DiskStat, error) {
data, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
devices := strings.Split(string(data), "\n")
results := make([]DiskStat, len(devices)-1) for i := range results {
fields := strings.Fields(devices[i])
Major, _ := strconv.ParseInt(fields[0], 10, strconv.IntSize)
results[i].Major = int(Major)
Minor, _ := strconv.ParseInt(fields[1], 10, strconv.IntSize)
results[i].Minor = int(Minor)
results[i].Name = fields[2]
results[i].ReadIOs, _ = strconv.ParseUint(fields[3], 10, 64)
results[i].ReadMerges, _ = strconv.ParseUint(fields[4], 10, 64)
results[i].ReadSectors, _ = strconv.ParseUint(fields[5], 10, 64)
results[i].ReadTicks, _ = strconv.ParseUint(fields[6], 10, 64)
results[i].WriteIOs, _ = strconv.ParseUint(fields[7], 10, 64)
results[i].WriteMerges, _ = strconv.ParseUint(fields[8], 10, 64)
results[i].WriteSectors, _ = strconv.ParseUint(fields[9], 10, 64)
results[i].WriteTicks, _ = strconv.ParseUint(fields[10], 10, 64)
results[i].InFlight, _ = strconv.ParseUint(fields[11], 10, 64)
results[i].IOTicks, _ = strconv.ParseUint(fields[12], 10, 64)
results[i].TimeInQueue, _ = strconv.ParseUint(fields[13], 10, 64)
} return results, nil
}

  

008_falcon磁盘io计算方法的更多相关文章

  1. 磁盘IO

    基本概念: 在数据库优化和存储规划过程中,总会提到IO的一些重要概念,在这里就详细记录一下,个人认为对这个概念的熟悉程度也决定了对数据库与存储优化的理解程度,以下这些概念并非权威文档,权威程度肯定就不 ...

  2. Linux下java获取CPU、内存、磁盘IO、网络带宽使用率

    一.CPU 使用proc文件系统,"proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间.它以文件系统的方式为访问系统内核数据的操作提供接口.用户和应用程序可以通过proc得 ...

  3. [系统资源攻略]IO第一篇-磁盘IO,内核IO概念

    几个基本的概念 在研究磁盘性能之前我们必须先了解磁盘的结构,以及工作原理.不过在这里就不再重复说明了,关系硬盘结构和工作原理的信息可以参考维基百科上面的相关词条--Hard disk drive(英文 ...

  4. 快速定位性能瓶颈,检查出所有资源(CPU、内存、磁盘IO等)的利用率(utilization)、饱和度(saturation)和错误(error)度量,即USE方法

    命令:uptime说明:查看机器分别在1分钟.5分钟.15分钟的平均负载情况,显示的数字表示等待cpu资源的进程和阻塞在不可中断io进程的数量,如果1分钟的平均负载很高,而15分钟的平均负载很低,说明 ...

  5. Cacti:添加监控磁盘IO

    来自:http://blog.sina.com.cn/s/blog_61c07ac50101gkzp.html 1.检查net-snmp是否支持IO监控 snmpwalk -v 1 -c public ...

  6. 【好书摘要】性能优化中CPU、内存、磁盘IO、网络性能的依赖

    系统优化是一项复杂.繁琐.长期的工作,优化前需要监测.采集.测试.评估,优化后也需要测试.采集.评估.监测,而且是一个长期和持续的过程,不 是说现在优化了,测试了,以后就可以一劳永逸了,也不是说书本上 ...

  7. MySQL 调优基础(四) Linux 磁盘IO

    1. IO处理过程 磁盘IO经常会成为系统的一个瓶颈,特别是对于运行数据库的系统而言.数据从磁盘读取到内存,在到CPU缓存和寄存器,然后进行处理,最后写回磁盘,中间要经过很多的过程,下图是一个以wri ...

  8. 降低磁盘IO使Oracle性能优化(转)

    文章转自:http://blog.chinaunix.net/uid-26813519-id-3207996.html 硬件方面虽然只占Oracle性能优化的一个方面(另一方面是软件),但是仍不可忽视 ...

  9. 巧用linux服务器的/dev/shm/,如果合理使用,可以避开磁盘IO不给力,提高网站访问速度。

    巧用linux服务器的/dev/shm/ 巧用linux服务器的/dev/shm/,如果合理使用,可以避开磁盘IO不给力,提高网站访问速度. 首先让我们认识一下,什么是tmpfs和/dev/shm/? ...

随机推荐

  1. html基本进阶知识【转】

    inline和block的区别: 网页一般是两种元素组合起来的,一种是内联元素,也就是行内显示,加上width和height没效果.一种是区块元素,可以加上对应的width和height,通常使用在网 ...

  2. Python Thrift 简单示例

    本文基于Thrift-0.10,使用Python实现服务器端,使用Java实现客户端,演示了Thrift RPC调用示例.Java客户端提供两个字符串参数,Python服务器端计算这两个字符串的相似度 ...

  3. docker之搭建私有镜像仓库和公有仓库

    一.搭建私有仓库 1.docker pull registry #下载registry镜像并启动 2. docker run -d -v /opt/registry:/var/lib/registry ...

  4. Jenkins和pipeline

    Jenkins https://jenkins.io/index.html The leading open source automation server, Jenkins provides hu ...

  5. git 完全讲解 无废话,包含在myeclipse中使用,包括解决冲突

    Git 1. Git简介 1.1 git是什么 1.1.1概念 Git:git是一款开源的分布式的版本控制软件 Github:是一个基于git的面向开源及私有软件项目的托管平台 因仅支持git 作为唯 ...

  6. IDAPython教程(二)

    继续我们的主题—使用IDAPython 让逆向工程师的生活变得更美好. 这一部分,我们将着手处理一个非常常见的问题:shellcode和恶意软件使用hash算法混淆加载的函数和链接库,这项技术被广泛使 ...

  7. 【bzoj 3786】星系探索

    Description 物理学家小C的研究正遇到某个瓶颈. 他正在研究的是一个星系,这个星系中有n个星球,其中有一个主星球(方便起见我们默认其为1号星球),其余的所有星球均有且仅有一个依赖星球.主星球 ...

  8. Myschool乱码问题 和mysql 备份还原

    show variables like 'character_set%'; alter table users modify username ) character set gbk; alter t ...

  9. UML之涉众/参与者(角色/执行者)(Actor)/业务主角(BusinessActor)/业务工人(BusinessWorker)/用户/角色辨析【图解】

    参考文档: [业务建模](http://www.baike.com/wiki/%E4%B8%9A%E5%8A%A1%E5%BB%BA%E6%A8%A1) [UML 核心元素之参与者](http://w ...

  10. Ubuntu18.04使用AndroidStudio3.2.1编译TensorFlow android demo【2018年12月】

    按照官方教程修改下面3处即可编译完成. 修改部分: 在build.gradle文件里修改以下部分: 1.原来: buildscript { repositories { jcenter() } dep ...