
很多用户来问,这个指标是什么意思,那个指标是什么意思,解释半天也解释不明白,核心原因是,用户对他要监控的目标本身就缺乏知识。比如Nightingale里的一个net.in.dropped指标,表示入方向的网卡每秒丢包量,如果你从来没有执行过ifconfig命令,对网络丢包不知道是咋回事,真的就很难理解这个指标的意思了。
下面会分别讲解一些常见指标的获取方式,让大家有个感性的认识,会带出部分Linux基础知识。坐好扶稳~
Linux相关指标举例
Linux下很多指标都是来自/proc目录下的一些信息,这个目录很特殊,从网上摘抄一段话给大家:
Linux系统上的/proc目录是一种文件系统,即proc文件系统。与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。
基于/proc文件系统如上所述的特殊性,其内的文件也常被称作虚拟文件,并具有一些独特的特点。例如,其中有些文件虽然使用查看命令查看时会返回大量信息,但文件本身的大小却会显示为0字节。此外,这些特殊文件中大多数文件的时间及日期属性通常为当前系统时间和日期,这跟它们随时会被刷新(存储于RAM中)有关。
为了查看及使用上的方便,这些文件通常会按照相关性进行分类存储于不同的目录甚至子目录中,如/proc/scsi目录中存储的就是当前系统上所有SCSI设备的相关信息,/proc/N中存储的则是系统当前正在运行的进程的相关信息,其中N为正在运行的进程(可以想象得到,在某进程结束后其相关目录则会消失)。
大多数虚拟文件可以使用文件查看命令如cat、more或者less进行查看,有些文件信息表述的内容可以一目了然,但也有文件的信息却不怎么具有可读性。不过,这些可读性较差的文件在使用一些命令如apm、free、lspci或top查看时却可以有着不错的表现。
我们挑一类简单的指标:最近1min、5min、15min的负载数据,这3个指标我们平时用的比较多,执行uptime命令就能看到,比如:
[root@10-255-0-103 ~]# uptime
10:49:34 up 10 days, 16:54, 1 user, load average: 0.09, 0.14, 0.18
监控系统去采集的时候,并非是执行uptime命令,那就太low了,效率也差,实际上我们是从/proc/loadavg文件读取的,因为/proc的读取不涉及真实的硬盘IO所以效率是非常高的。看一眼这个文件的内容哈:
[root@10-255-0-103 ~]# cat /proc/loadavg
0.09 0.14 0.18 3/271 9043
看完了负载的指标,再看个内存利用率,我们经常用free -h来看内存使用情况,实际内存数据是在/proc/meminfo文件,我们来看一眼:
[root@10-255-0-103 ~]# cat /proc/meminfo
MemTotal: 8008856 kB
MemFree: 208368 kB
MemAvailable: 3421636 kB
Buffers: 0 kB
Cached: 1499772 kB
SwapCached: 0 kB
Active: 4085356 kB
Inactive: 622092 kB
Active(anon): 3322972 kB
Inactive(anon): 73668 kB
Active(file): 762384 kB
Inactive(file): 548424 kB
Unevictable: 0 kB
Mlocked: 0 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 3312 kB
Writeback: 0 kB
AnonPages: 3207724 kB
Mapped: 155608 kB
Shmem: 188964 kB
Slab: 2948432 kB
SReclaimable: 2208352 kB
MemTotal、MemFree、MemAvailable都有。
最后再看一下磁盘使用情况,这个要比上面两个都更难获取,不仅仅是读取/proc的内容了。Linux上面的命令就是df -h,可以看到各个挂载点的使用情况。监控系统实际在采集这个数据的时候,是分成两步。
第一步是读取/proc/mounts获取所有的挂载点,过滤掉一些虚拟挂载点,然后执行Statfs的一个系统调用才能得到这个分区的使用情况。
Redis相关指标举例
我这有一个redis实例,连上去执行一下info命令给大家看看输出:
[root@10-255-0-103 ~]# redis-cli
127.0.0.1:6379> info
# Server
redis_version:3.2.12
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:7897e7d0e13773f
redis_mode:standalone
os:Linux 3.10.0-957.27.2.el7.x86_64 x86_64
arch_bits:64
multiplexing_api:epoll
gcc_version:4.8.5
process_id:5453
run_id:9c7374106c06eaf9762b9b9c4cc5e2862507b9f7
tcp_port:6379
uptime_in_seconds:925547
uptime_in_days:10
hz:10
lru_clock:8534430
executable:/usr/bin/redis-server
config_file:/etc/redis.conf
# Clients
connected_clients:7
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:1
# Memory
used_memory:946912
used_memory_human:924.72K
used_memory_rss:7606272
used_memory_rss_human:7.25M
used_memory_peak:1167288
used_memory_peak_human:1.11M
total_system_memory:8201068544
total_system_memory_human:7.64G
used_memory_lua:37888
used_memory_lua_human:37.00K
maxmemory:0
maxmemory_human:0B
maxmemory_policy:noeviction
mem_fragmentation_ratio:8.03
mem_allocator:jemalloc-3.6.0
# Persistence
loading:0
rdb_changes_since_last_save:34
rdb_bgsave_in_progress:0
rdb_last_save_time:1619147033
rdb_last_bgsave_status:ok
rdb_last_bgsave_time_sec:0
rdb_current_bgsave_time_sec:-1
aof_enabled:0
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:-1
aof_current_rewrite_time_sec:-1
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
# Stats
total_connections_received:243702
total_commands_processed:41498406
instantaneous_ops_per_sec:43
total_net_input_bytes:1086332717
total_net_output_bytes:270616329
instantaneous_input_kbps:1.08
instantaneous_output_kbps:0.26
rejected_connections:0
sync_full:0
sync_partial_ok:0
sync_partial_err:0
expired_keys:0
evicted_keys:0
keyspace_hits:6300
keyspace_misses:86977
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:241
migrate_cached_sockets:0
# Replication
role:master
connected_slaves:0
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
# CPU
used_cpu_sys:1479.91
used_cpu_user:812.97
used_cpu_sys_children:5.35
used_cpu_user_children:0.87
# Cluster
cluster_enabled:0
# Keyspace
db0:keys=3,expires=2,avg_ttl=2283306048
看到了吧,各种指标都有,当我们谈到redis监控的时候,主要就是监控这些指标。
做得易用的监控,会允许你直接配置redis的连接地址,监控系统会自动连上去执行命令。如果没有提供页面配置方式,一般至少也会提供插件扩展方式,容许用户写脚本,用脚本去采集监控指标,然后将监控数据推给监控服务端。
应用业务层面指标监控
应用层面的监控主要是接口成功率、响应时长、QPS等,这些监控数据的采集,最好是能在统一的HTTP框架或RPC框架里搞定,或者在统一的七层接入里搞定,减少各业务接入成本。
如果要做trace监控或者业务层面的指标监控,那基本就只能埋点了,比如监控系统的数据接口模块,我想统计一下每秒接收多少个数据点,那就需要数据接收模块在代码里写相关的采集逻辑了。
通过日志提取指标,也是个典型手段,通常就是用ELK这种方案,把日志收集到中心,写查询语句去查询分析。但这种方式比较重,我们在Nightingale中引入了一种更轻量的方案供大家参考。核心逻辑是在服务端配置正则表达式,下发到agent侧,agent流式读取日志文件,每读到一行,就用正则匹配一下,看是否命中,如果命中,就可以从中提取出一些指标信息。