weixueyuan-Nginx日志管理与监控8
https://www.weixueyuan.net/nginx/log/
Nginx访问日志配置
Nginx 的访问日志主要记录用户客户端的请求信息(见下表)。用户的每次请求都会记录在访问日志中,access_log 指令可以设置日志的输出方式及引用的日志格式。
关于 access_log 指令有以下几点需要说明:
关于 log_format 指令有以下几点需要说明:
配置样例如下:
Nginx 的 TCP/UDP 的日志处理是在连接处理阶段结束时才发生,所以 TCP/UDP 代理的访问日志只在连接关闭时才被记录。访问日志格式配置样例如下:
关于 open_log_file_cache 指令有以下几点需要说明:
名称 | 访问日志指令 |
---|---|
指令 | access_log |
作用域 | http、stream、server、location、if in location、limit except |
默认值 | logs/access.log combined; |
指令值格式 | off 或 path[format[buffer=size][gzip[=level]][flush=time][if=condition]]; |
指令说明 | 设置访问日志输出方式及引用的日志格式 |
关于 access_log 指令有以下几点需要说明:
- 在同一级别的指令域中,也可指定多个日志;
- 指令值中的第一个参数用于设置输出日志的方式,默认是输出到本地的文件中。该指令也支持输出到 syslog 或内存缓冲区中;
- 该指令在 stream 指令域中时,默认值为 off;
access_log off;
- 参数 path,设置日志输出的文件路径或 syslog 服务器地址;
access_log logs/access.log combined;
- 参数 format,设置关联 log_format 指令定义的日志格式名;
- 参数 buffer,设置日志文件缓冲区大小。当缓冲区日志数据超出该值时,缓冲区日志数据会被写到磁盘文件。默认缓冲区大小为 64KB;
- 参数 flush,设置日志缓冲区刷新的时间间隔,缓冲区日志的保护时间超过这个设定值时,缓冲区日志数据会被写到磁盘文件;
- 参数 gzip,设置缓冲区数据的压缩级别,缓冲区数据会被压缩后再写出到磁盘文件。压缩级别范围 1~9,级别越高压缩比越高,系统资源消耗也最大,默认级别为 1;
access_log logs/log.gz combined gzip flush=5m;
- 参数 if,设置是否记录日志,当参数值的条件成立,即不为 0 或空时,才记录日志。
map $status $loggable {
~^[23] 0;
default 1;
}
access_log logs/access.log combined if=$loggable;
名称 | 日志格式指令 |
---|---|
指令 | log_format |
作用域 | http、stream |
默认值 | combined"..."; |
指令值格式 | name[escape=default 或 json 或 none]string...; |
指令说明 | 设置访问日志输出方式及输出日志格式 |
关于 log_format 指令有以下几点需要说明:
- 指令值参数 name 用于设置日志格式名。该名称全局唯一,可以被 access_log 引用;
- 指令值参数 escape 用于设置日志输出字符串编码格式,json 支持中文字符内容输出;
- 指令值参数 string 用于设置日志输出格式字符串。该字符串由 Nginx 公共变量和仅在日志写入时存在的变量组成。HTTP 常用变量如下表所示。
变量名 | 变量说明 |
---|---|
$time_iso8601 | ISO 8601 时间格式 |
$time_local | 用户请求的时间和时区 |
$msec | 毫秒级别的日志记录时间 |
$remote_addr | 发起与 Nginx 建立连接的网络客户端的 IP,有时会是上层代理服务器的 IP |
$http_x_forwarded_for | 可以记录客户端 IP,通过代理服务器来记录客户端的 IP |
$remote_user | 用于记录远程客户端的用户名称 |
$http_user_agent | 用户客户端浏览器标识 |
$connection | 网络连接编号 |
$connection_requests | 当前连接的请求数 |
$request | 用户请求的 URI 及请求方法 |
$request_method | 用户请求方法 |
$request_uri | 用户请求的 URI 及请求方法 |
$server_protocol | 请求协议 |
$request_time | 请求时间 |
$request_length | 请求数据大小 |
$status | 用户请求响应状态码 |
$bytes_sent | 发送到客户端响应数据的大小 |
$body_bytes_sent | 用户请求返回的响应体字节数 |
$http_referer | HTTP 请求头中属性字段 referer |
配置样例如下:
# 普通格式日志 log_format main '$remote_addr - $connection - $remote_user [$time_local] "$request" - $upstream_addr' '$status - $body_bytes_sent - $request_time - "$http_referer" ' '"$http_user_agent" - "$http_x_forwarded_for" - '; # JSON格式日志 log_format json '{"@timestamp": "$time_iso8601", ' '"connection": "$connection", ' '"remote_addr": "$remote_addr", ' '"remote_user": "$remote_user", ' '"request_method": "$request_method", ' '"request_uri": "$request_uri", ' '"server_protocol": "$server_protocol", ' '"status": "$status", ' '"body_bytes_sent": "$body_bytes_sent", ' '"http_referer": "$http_referer", ' '"http_user_agent": "$http_user_agent", ' '"http_x_forwarded_for": "$http_x_forwarded_for", ' '"request_time": "$request_time"}';Nginx TCP/UDP 的访问日志的变量与 HTTP 的访问日志的变量是不同的,TCP/UDP 常见日志变量如下表所示。
变量名 | 变量说明 |
---|---|
$time_iso8601 | ISO 8601 时间格式 |
$time_local | 用户请求的时间和时区 |
$connection | 网络连接编号 |
$remote_addr | 发起与 Nginx 建立连接的网络客户端的 IP,有时会是上层代理服务器的 IP |
$server_addr | Nginx 服务器地址 |
$server_port | Nginx 服务器端口 |
$status | 用户请求响应状态码 |
$upstream_addr | 被代理服务器地址 |
$bytes_received | 接收字节数 |
$bytes_sent | 发送字节数 |
$session_time | 连接会话时间 |
$proxy_protocol_addr | 代理协议地址 |
$proxy_protocol_port | 代理协议端口 |
Nginx 的 TCP/UDP 的日志处理是在连接处理阶段结束时才发生,所以 TCP/UDP 代理的访问日志只在连接关闭时才被记录。访问日志格式配置样例如下:
# 普通格式日志 log_format tcp '$remote_addr - $connection - [$time_local] $server_addr: $server_port ' '- $status - $upstream_addr - $bytes_received - $bytes_sent - $session_time ' '- $proxy_protocol_addr:$proxy_protocol_port '; # JSON格式日志 log_format json '{"@timestamp": "$time_iso8601", ' '"connection": "$connection", ' '"remote_addr": "$remote_addr", ' '"server_addr": "$server_addr:$server_port" ' '"status": "$status" ' '"upstream_addr": "$upstream_addr" ' '"bytes_received": "$bytes_received" ' '"bytes_sent": "$bytes_sent" ' '"session_time": "$session_time" ' '"proxy_protocol_addr": "$proxy_protocol_addr:$proxy_protocol_port" '}'打开日志缓存指令见下表。
名称 | 打开日志缓存指令 |
---|---|
指令 | open_log_file_cache |
作用域 | http、stream、server、location |
默认值 | off |
指令值格式 | off 或 max=N [inactive=time][min_uses=N][valid=time]; |
指令说明 | 设置存储日志文件描述符(文件句柄)的缓存 |
关于 open_log_file_cache 指令有以下几点需要说明:
- 默认配置下,Nginx 每次将缓冲区日志数据保存到磁盘中,都需要先打开文件并获得文件描述符,然后向该文件描述符的文件中写入日志数据,最后关闭该文件描述符的文件。该指令把打开文件的文件描述符(文件句柄)存储在缓存中,进而提升写入日志的效率;
- 指令值 max 用于设置缓存中存储的文件描述符的最大数量,超过该值时,将按照 LRU 算法对缓存中文件描述符进行关闭;
- 指令值参数 inactive 用于设置缓存中每个文件描述符存活的时间,默认为 10s;
- 指令值参数 min_uses 用于设置可被缓存文件描述符的最小使用次数,默认为 1 次;
- 指令值参数 valid 用于设置缓存检查频率,默认为 60s;
- 指令值 off 用于关闭打开日志缓存的功能。
open_log_file_cache max=1000 inactive=20s valid=1m min_uses=2;
logs/access.log combined;
Nginx error_log:错误日志配置
Nginx 的错误日志可以帮助用户及时判断 Nginx 配置及运行时出错的原因,错误日志也可以通过 Nginx 内置指令进行配置,但不支持格式定义。配置指令如下表所示。
关于 error_log 指令有以下几点需要说明:
错误日志级别及相关说明如下表所示。
说明 | 错误日志指令组成 |
---|---|
主指令 | error_log |
作用域 | main、http、mail、stream、server、location |
默认值 | logs/error.log error; |
指令说明 | 设置错误日志输出方式及输出日志级别 |
关于 error_log 指令有以下几点需要说明:
- 在同一级别的指令域中,也可指定多个日志;
- 指令值中的第一个参数是输出日志的方式,默认是输出到本地的文件中。该指令也支持输出到 syslog 或内存缓冲区中;
error_log syslog:server=192.168.2.109 error;
error_log memory:32m debug;
error_log /dev/null;
# 访问文件不存在时,记入错误日志
log_not_found on;
错误日志级别及相关说明如下表所示。
级别 | 级别值 | 级别说明 |
---|---|---|
debug | 8 | 代码中标记为 NGX_LOG_DEBUG 的输出,输出最为详细,配合调试使用 |
info | 7 | 代码中标记为 NGX_LOG_INFO 的输出,因包括除 debug 级别的所有输出,故同样会消耗大量磁盘 IO 资源 |
notice | 6 | 代码中标记为 NGX_LOG_NOTICE 的输出 |
warn | 5 | 代码中标记为 NGX_LOG_WARN 的输出 |
error | 4 | 代码中标记为 NGX_LOG_ERROR 的输出,实际生产环境中常用的输出级别 |
crit | 3 | 代码中标记为 NGX_LOG_CRIT 的输出 |
alert | 2 | 代码中标记为 NGX_LOG_ALERT 的输出 |
emerg | 1 | 代码中标记为 NGX_LOG_EMERG 的输出 |
Nginx Logrotate:日志归档
Nginx 日志存储为文件时,同一 access_log 指令设置的日志文件是以单文件形式存储的,在日常使用中为方便维护,通常需要将日志文件按日期进行归档。虽然 Nginx 本身并没有这一功能,但实现日志归档的方法仍有很多,此处推荐使用 Logrotate 实现日志归档管理。
Logrotate 是 CentOS 操作系统内置日志管理工具,该工具可对系统中生成的大量日志文件进行归档管理,其允许对日志文件实行压缩、删除或邮寄等操作。Logrotate 可以按照每天、周、月或达到某一大小的日志文件进行归档操作,Logrotate 基于 anacrontab 实现计划任务,只需在 /etc/logrotate.d 目录下编写相关日志管理配置文件,就可以无须人工干预使用自动化方式完成日志归档操作。
关于上表有以下几点需要说明:
Logrotate 是 CentOS 操作系统内置日志管理工具,该工具可对系统中生成的大量日志文件进行归档管理,其允许对日志文件实行压缩、删除或邮寄等操作。Logrotate 可以按照每天、周、月或达到某一大小的日志文件进行归档操作,Logrotate 基于 anacrontab 实现计划任务,只需在 /etc/logrotate.d 目录下编写相关日志管理配置文件,就可以无须人工干预使用自动化方式完成日志归档操作。
1) Logrotate 安装
yum -y install logrotate
2) Logrotate 文件目录
/etc/logrotate.conf # logrotate主配置文件 /usr/sbin/logrotate # logrotate二进制文件 /etc/logrotate.d/ # 自定义logrotate配置文件 /var/lib/logrotate/logrotate.status # logrotate管理日志执行记录的状态文件
3) Logrotate 命令参数
-d, --debug # 测试归档配置文件 -f, --force # 立即执行归档操作 -m, --mail=command # 指定发送邮件的命令(默认为'/bin/mail') -s, --state=statefile # 设置logrotate.status文件路径,可用于区分在同 # 一系统下以不同用户身份运行的logrotate任务 -v, --verbose # 显示配置详细信息 -l, --log=STRING # 将Logrotate执行的详情输出到指定的文件 logrotate -v /etc/logrotate.conf # 显示配置文件详细信息 logrotate -d /etc/logrotate.d/syslog -l /var/log/logrotate.log # 配置文件,执行测试 logrotate -f /etc/logrotate.d/syslog # 立即执行当前配置文件
4) Logrotate 配置指令
Logrotate 配置指令如下表所示。指令 | 指令说明 |
---|---|
归档执行周期 | |
hourly | 日志归档周期为 1 小时,默认 Logrotate 的最小周期为 1 天,需额外调整该参数才可生效 |
daily | 日志归档周期为 1 天 |
weekly | 日志归档周期为 1 周 |
monthly | 日志归档周期为 1 月,通常为每月的第一天 |
归档执行条件 | |
include | 读取外部参数文件 |
missingok | 如果日志文件不存在,则不显示错误信息 |
nomissingok | 如果日志文件不存在,则显示错误信息。默认配置 |
size | 日志文件可被归档的最小值 |
minsize | 日志文件可被归档的最小值,没到归档周期执行时间,不会执行归档操作 |
maxsize | 日志文件超过设定值时,即使没到归档周期执行时间,也会执行归档操作 |
ifempty | 即使日志文件为空,也执行归档操作 |
notifempty | 如果日志文件为空,则不进行归档。默认设置 |
tabooext | 不对设置扩展名的日志文件执行归档操作 |
归档文件命名 | |
start count | 使用日志文件归档次数作为归档文件扩展名,count 默认值为 1,默认配置 |
dateext | 为归档文件名添加日期,默认追加到扩展名后 |
dateformat | 设置归档文件名中的日期格式,使用“%Y%m%d%H”作为说明符,默认为-%Y%m%d |
dateyesterday | 使用前一天的日期而非创建归档文件时的日期作为归档文件的文件名中的日期 |
extension | 指定日志的扩展名,并将其设置为归档文件的扩展名,启用压缩时,压缩的扩展名在最后 |
compressext | 启用压缩时,自定义归档文件扩展名,如将“.gz”改为“.ddd” |
归档文件保存方式 | |
compress | 对归档文件启用压缩,默认为 gzip 压缩 |
nocompress | 不压缩归档文件。默认设置 |
compresscmd | 指定压缩归档文件的命令,默认为 gzip 压缩 |
uncompresscmd | 指定解压归档文件的命令,默认为 gunzip 解压 |
compressoptions | 启用压缩时,设置压缩工具的命令选项 |
delaycompress | 在下一个归档周期再对当前归档文件进行压缩 |
nodelaycompress | 不延迟压缩。默认设置 |
归档执行方式 | |
copy | 为日志文件复制一个副本后再进行归档 |
nocopy | 不复制源日志文件。默认配置 |
copytruncate | 复制日志文件后清空日志文件的内容 |
nocopytruncate | 复制源日志文件后,不清空源文件。默认设置 |
create mode owner group, create owner group | 重命名日志文件,创建与日志文件同名的文件,默认 mode=0644 uid=0 gid=0,与 copy 指令不能同时使用 |
nocreate | 不创建与日志文件同名的文件。默认设置 |
olddir | 设置归档文件保存目录 |
noolddir | 归档文件与源文件在同一目录。默认设置 |
createolddir mode owner group | 如果 olddir 参数指定的目录不存在,则创建目录并指定属组,默认 mode = 0777 uid = 0 gid = 0 |
nocreateolddir | 当 olddir 参数设定目录不存在时,不创建目录。默认设置 |
prerotate ... endscript | 归档执行之前执行脚本,日志文件名为传入的第一个参数 |
postrotate ... endscript | 归档执行之后执行脚本,日志文件名为传入的第一个参数 |
firstaction ... endscript | prerotate 脚本之前,仅当第一个日志文件被开始执行归档操作时才执行脚本,日志文件名为传入的第一个参数 |
lastaction ... endscript | postrotate 脚本之后,仅当最后一个日志文件执行归档操作结束时才执行脚本,日志文件名为传入的第一个参数 |
preremove ... endscript | 删除日志文件之前执行脚本,日志文件名为传入的第一个参数 |
sharedscripts | 当匹配的日志文件为多个时,prerotate 和 postrotate 脚本会在每个日志文件执行归档操作时都执行一次,启用共享模式会让 prerotate 和 postrotate 脚本在全局只运行一次 |
nosharedscripts | 当匹配的日志文件为多个时,prerotate 和 postrotate 脚本会在每个日志文件执行归档操作时都执行一次。默认设置 |
su user group | 指定操作源文件执行归档操作的用户及属组 |
归档文件清理 | |
设置接收归档文件的邮件地址 | |
nomail | 不将归档文件发送到任何邮件地址 |
mailfirst | 将刚生成的归档文件发送到设置的邮箱 |
maillast | 将要超过 maxage 设置时间的归档文件发送到设置的邮箱 |
mахage | 设置过期归档文件的天数 |
rotate | 保留归档文件数,默认为 0 |
shred | 彻底删除 |
shredcycles count | 彻底删除时,覆盖文件的次数,默认为 3 |
noshred | 不彻底删除 |
关于上表有以下几点需要说明:
- copy 与 create 是两种互斥的归档执行方式;
- copy 方式是将日志文件复制一份后清空原日志文件的内容,并对复制的文件进行归档操作,应用程序继续向原日志文件输出日志。因日志文件复制与清空操作存在时间间隔,所以切割操作会因日志量的大小及实时产生的频率存在丢失的情况;
- create 方式是将日志文件重命名,因日志文件的 inode 编号不变,应用程序会向新命名的文件输出日志。Logrotate 新创建原日志文件名的文件后执行重启或以信号机制通知应用程序重新向新日志文件输出日志内容,完成切割操作;
- 当与同一自定义配置匹配的日志文件为多个时,会并发执行归档操作。
5) Logrotate 管理 Nginx 日志
根据 Logrotate 的功能特点,建议选择 create 方式进行日志归档管理,配置样例如下:vi /etc/logrotate.d/nginx /usr/local/nginx/logs/*.log { daily # 日志归档周期为1天 size 1 # 日志文件最小为1字节时才执行归档 minsize 1 # 日志文件最小为1字节时才执行归档 notifempty # 日志文件不为空时才执行归档 dateext # 归档文件名添加时间字符串 dateformat -%Y%m%d%H # 归档文件名时间字符串格式为-%Y%m%d%H dateyesterday # 归档文件名时间字符串以归档操作的前一天为时间戳 extension .log # 归档文件名中保留日志的扩展名 compress # 归档文件执行压缩 delaycompress # 在归档执行的下个周期再进行压缩 create # 以创建新文件方式实现日志归档 olddir /data/backup/nginx_logs # 归档文件存储目录 createolddir # 归档文件存储目录不存在时自动创建 postrotate # 归档执行后执行脚本 /usr/local/nginx/sbin/nginx -s reopen -g "pid /run/nginx.pid;" # 通知Nginx重新打开日志文件 endscript sharedscripts # 启用脚本共享模式 maxage 7 # 归档文件最多保留7天 rotate 7 # 归档文件最多保留7份 }
Nginx日志分析工具(ELK)配置
Nginx 的访问日志中可以记录用户的 IP、访问方法、访问 URI、响应状态及响应数据大小等 HTTP 请求处理中会涉及的各种信息,通过这些信息可以实现访问用户来源分布、用户请求 URI 排行、响应数据大小及并发连接的分析和统计。
图:ELK 访问逻辑
1) Elasticsearch 是一款用 Java 语言开发的,基于 Lucene 的开源搜索引擎,它提供了分布式多用户的全文搜索、分析、存储能力。Elasticsearch 的常见关键词如下表所示。
2) Logstash 是基于 C/S 架构,对日志进行收集、过滤、转发的日志收集引擎,它可以同时从多个源获取数据,动态地将客户端采集的数据进行分拣、过滤,并转发到不同存储服务器。
Logstash 是以 pipeline 方式处理每条日志信息的,在每个 pipeline 中都有输入(INPUTS)、过滤(FILTERS)、输出(OUTPUTS)3 个处理动作。每个处理动作可由一个或多个插件实现复杂的功能。输入处理是获取日志数据;过滤处理可以对日志进行分拣、修改;输出处理则是将日志数据发送给目标存储服务器。
Logstash 工作原理如下图所示。
图:Logstash 原理
3) Kibana 是 Elasticsearch 的 Web 管理工具,它提供了友好的界面化操作方式和统计分析的 Dashboard 工具,让使用者只需简单点击就可完成基本的数据搜索、分析等工作。
4) Filebeat 隶属于 Beats 工具包,是负责文件数据采集的客户端工具。Filebeat 由 pro-spector 和 harvester 两个主要组件组成。prospector 目前只支持 log 文件和 stdin 两个输入类型,是 harvester 的管理进程,负责按照配置参数 paths 的内容查找日志文件,并为每个日志文件分配一个 harvester。
harvester 负责实时读取单个日志文件,harvester 将日志内容发送给底层的 libbeat,libbeat 将日志数据发送给配置文件中指定的输出目标。Filebeat 工作原理如下图所示。
图:Filebeat 原理
图:ELK 部署示意
1、ELK 简介
ELK(Elasticsearch、Logstash、Kibana)是开源的实时日志收集分析解决方案。ELK 访问逻辑如下图所示,是由 Elasticsearch、Logstash、Kibana 这三款软件和数据采集客户端(如 Filebeat)等实现日志采集、储存、搜索分析等操作。图:ELK 访问逻辑
1) Elasticsearch 是一款用 Java 语言开发的,基于 Lucene 的开源搜索引擎,它提供了分布式多用户的全文搜索、分析、存储能力。Elasticsearch 的常见关键词如下表所示。
关键词 | 名称 | 关键词说明 |
---|---|---|
cluster | 集群 | 集群由一个主节点和多个从节点组成,主节点是通过内部选举产生的。Elastic-search 集群是一个去中心化的分布式架构,对于外部用户来讲,Elasticsearch 集群是个整体,与其中任何一个节点通信获取内容都是一致的 |
index | 索引 | Elasticsearch 是面向文档的数据库,一条数据就是一个文档,文档内容为包含多个 key,value 格式字段数据。Elasticsearch 集群可以包括多个索引,每个索引下包含多个类型,每个类型下包含多个文档。索引相当于关系型数据库中的库,类型相当于关系型数据库中的表 |
shards | 索引分片 | Elasticsearch 可以把一个完整的索引分成多个分片,该方式可以把一个大的索引拆分成多个,并分布到不同的节点,实现分布式搜索 |
replicas | 索引副本 | Elasticsearch 可以为索引设置多个副本,当集群中某个节点或某个索引的分片损坏或丢失时,可以通过副本进行恢复,同时可以为搜索请求提供负载均衡,以提高查询效率 |
recovery | 数据分配与恢复 | Elasticsearch 集群在有节点加入或退出时,会根据节点的数量变化对索引分片进行重新分配,当挂掉的节点重启后也会进行数据分配与恢复 |
gateway | 存储方式 | Elasticsearch 存储方式,Elasticsearch 会先把索引存放到内存中,当内存满了时再持久化到 gateway 配置的目标存储中。默认 gateway 配置为本地硬盘,也支持其他分布式文件系统,如 Hadoop 的 HDFS 和 Amazon 的 s3 云存储服务等 |
2) Logstash 是基于 C/S 架构,对日志进行收集、过滤、转发的日志收集引擎,它可以同时从多个源获取数据,动态地将客户端采集的数据进行分拣、过滤,并转发到不同存储服务器。
Logstash 是以 pipeline 方式处理每条日志信息的,在每个 pipeline 中都有输入(INPUTS)、过滤(FILTERS)、输出(OUTPUTS)3 个处理动作。每个处理动作可由一个或多个插件实现复杂的功能。输入处理是获取日志数据;过滤处理可以对日志进行分拣、修改;输出处理则是将日志数据发送给目标存储服务器。
Logstash 工作原理如下图所示。
图:Logstash 原理
3) Kibana 是 Elasticsearch 的 Web 管理工具,它提供了友好的界面化操作方式和统计分析的 Dashboard 工具,让使用者只需简单点击就可完成基本的数据搜索、分析等工作。
4) Filebeat 隶属于 Beats 工具包,是负责文件数据采集的客户端工具。Filebeat 由 pro-spector 和 harvester 两个主要组件组成。prospector 目前只支持 log 文件和 stdin 两个输入类型,是 harvester 的管理进程,负责按照配置参数 paths 的内容查找日志文件,并为每个日志文件分配一个 harvester。
harvester 负责实时读取单个日志文件,harvester 将日志内容发送给底层的 libbeat,libbeat 将日志数据发送给配置文件中指定的输出目标。Filebeat 工作原理如下图所示。
图:Filebeat 原理
2、ELK 安装
ELK 支持多种安装方式,鉴于 Docker 化部署的便捷性,本小节以基于 docker-compose 脚本的 Docker 化来部署 ELK 环境,部署示意如下图所示。图:ELK 部署示意
1) 初始化系统环境
首先要初始化系统环境并安装 Docker 应用。# 安装yum工具 yum install -y yum-utils # 安装Docker官方yum源 yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo # 安装docker及docker-compose应用 yum install -y docker-ce docker-compose # 设置docker服务开机自启动 systemctl enable docker # 启动docker服务 systemctl start docker # 优化内核参数,设置一个进程拥有VMA(虚拟内存区域)的最大数量为262144 sysctl -w vm.max_map_count=262144
2) 编写 docker-compose 文件
使用 docker-compose 工具进行 ELK 容器运行编排。docker-compose 文件如下:cat elk.yaml version: '2' services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.0.1 container_name: elasticsearch701 environment: - discovery.type=single-node - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 hostname: elasticsearch restart: always ports: - "9200:9200" - "9300:9300" kibana: image: docker.elastic.co/kibana/kibana:7.0.1 container_name: kibana701 hostname: kibana depends_on: - elasticsearch restart: always ports: - "5601:5601" logstash: image: docker.elastic.co/logstash/logstash:7.0.1 container_name: logstash701 hostname: logstash restart: always depends_on: - elasticsearch ports: - "5044:5044" # 运行ELK容器 docker-compose -felk.yaml up -ddocker-compose 是功能非常强的容器运行编排工具,内部含有很多配置指令可以完成容器的资源配置、运行、服务依赖、网络配置等运行时的编排配置,具体指令说明可参照 docker-compose 的官方文档。
3) 数据持久化
Docker 的镜像(Image)文件存放在一个只读层,而容器(Container)的文件则是存放在可写层,当容器删除或重建时,该容器运行时变更的文件将会丢失,所以需要通过外挂卷的方式将变更的配置和文件保存到主机系统中。ELK 容器有 Elasticsearch、Logstash 和 Kibana 3 个容器,这 3 个容器都需要实现数据持久化。cd /opt/data/apps # 创建容器外挂卷目录及数据存储目录 mkdir -p {elasticsearch/data,elasticsearch/config,elasticsearch/modules,elastic-search/plugins,kibana/config,logstash/pipeline,logstash/config} # 复制容器数据到数据存储目录 docker cp elasticsearch701:/usr/share/elasticsearch/data elasticsearch docker cp elasticsearch701:/usr/share/elasticsearch/config elasticsearch docker cp elasticsearch701:/usr/share/elasticsearch/modules elasticsearch docker cp elasticsearch701:/usr/share/elasticsearch/plugins elasticsearch docker cp logstash701:/usr/share/logstash/config logstash docker cp logstash701:/usr/share/logstash/pipeline logstash docker cp kibana701:/usr/share/kibana/config kibana # Logstash配置 cat>logstash/pipeline/logstash.conf<<EOF input { beats { port => 5044 codec =>"json" } } output { elasticsearch { hosts => ["http://10.10.4.37:9200"] index => "logstash-nginx-%{[@metadata][version]}-%{+YYYY.MM.dd}" } } EOF # 配置目录权限 chown -R 1000:1000 elasticsearch/* chown -R 1000:1000 logstash/* # 配置docker-compose脚本,挂载数据存储目录 cat elk.yaml version: '2' services: elasticsearch: image: docker.elastic.co/elasticsearch/elasticsearch:7.0.1 container_name: elasticsearch701 environment: - discovery.type=single-node - bootstrap.memory_lock=true - "ES_JAVA_OPTS=-Xms512m -Xmx512m" ulimits: memlock: soft: -1 hard: -1 volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - /opt/data/apps/elasticsearch/modules:/usr/share/elasticsearch/modules - /opt/data/apps/elasticsearch/plugins:/usr/share/elasticsearch/plugins - /opt/data/apps/elasticsearch/data:/usr/share/elasticsearch/data - /opt/data/apps/elasticsearch/config:/usr/share/elasticsearch/config hostname: elasticsearch restart: always ports: - "9200:9200" - "9300:9300" kibana: image: docker.elastic.co/kibana/kibana:7.0.1 container_name: kibana701 hostname: kibana volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - /opt/data/apps/kibana/config:/usr/share/kibana/config depends_on: - elasticsearch restart: always ports: - "5601:5601" logstash: image: docker.elastic.co/logstash/logstash:7.0.1 container_name: logstash701 hostname: logstash volumes: - /etc/localtime:/etc/localtime:ro - /etc/timezone:/etc/timezone:ro - /opt/data/apps/logstash/pipeline:/usr/share/logstash/pipeline - /opt/data/apps/logstash/config:/usr/share/logstash/config restart: always depends_on: - elasticsearch ports: - "5044:5044" # 运行ELK容器 docker-compose -f elk.yaml up -d
4) Nginx 配置
在运行 Nginx 的主机上把 Nginx 日志定义为 json 格式,编辑 nginx.conf 文件并在 http 指令域添加如下指令:log_format json '{"@timestamp": "$time_iso8601", ' '"connection": "$connection", ' '"remote_addr": "$remote_addr", ' '"remote_user": "$remote_user", ' '"request_method": "$request_method", ' '"request_uri": "$request_uri", ' '"server_protocol": "$server_protocol", ' '"status": "$status", ' '"body_bytes_sent": "$body_bytes_sent", ' '"http_referer": "$http_referer", ' '"http_user_agent": "$http_user_agent", ' '"http_x_forwarded_for": "$http_x_forwarded_for", ' '"request_time": "$request_time"}';
5) Filebeat 安装
在 Nginx 服务器安装 Filebeat 进行 Nginx 日志采集。# 安装Filebeat rpm -ivh https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.0.1 -x86_64.rpm # 设置输出数据到Logstash及Logstash地址 sed -i "s/#output.logstash:/output.logstash:/g" /etc/filebeat/filebeat.yml sed -i "s/#hosts: \[\"localhost:5044\"\]/ hosts: \[\"10\.10\.4\.37:5044\"\]/g" /etc/filebeat/filebeat.yml # 关闭直接输出数据到Elasticsearch sed -i "s/output.elasticsearch/#output.elasticsearch/g" /etc/filebeat/filebeat.yml sed -i "s/hosts: \[\"localhost:9200\"\]/#hosts: \[\"localhost:9200\"\]/g" /etc/filebeat/filebeat.yml # 安装Filebeat Nginx模块 filebeat modules enable nginx # 配置Filebeat Nginx模块 cat >/etc/filebeat/modules.d/nginx.yml<<EOF - module: nginx access: enabled: true var.paths: ["/usr/local/nginx/logs/*access.log"] error: enabled: true var.paths: ["/usr/local/nginx/logs/*error.log"] EOF # 检查配置 filebeat test config filebeat test output # 启动Filebeat systemctl restart filebeat # 设置为自启动 systemctl enable filebeat
6) Kibana 展示
在浏览器中打开 http://10.10.4.37:5601,在右侧菜单栏中选择 management → index_patterns → Create index pattern,然后输入 logstash-nginx-*,接着点击Next Step添加Nginx日志索引。在左侧菜单栏中点击Discover选择logstash-nginx-就可以实时查看Nginx输出的访问或错误日志了。Nginx监控工具(Prometheus)配置
Nginx 的 ngx_http_stub_status_module 模块及第三方的主机状态监控模块都提供了自身状态数据的统计和输出功能,但作为监控管理,仍需要进一步实现对各种状态数据的收集、存储、统计展示、阈值报警等工作。为实现监控管理的完整性,需要使用更专业的监控工具来实现后续的工作。
其中,Exporter 可以由用户自行开发,只需输出符合 Prometheus 的规范数据即可;Prometheus Server 提供了 api 接口并支持自定义的 PromQL 查询语言对外实现监控数据查询输出,结合 Grafana 强大的图形模板功能,可以非常直观地以监控数据统计图表的形式进行展示。Prometheus 结构如下图所示。
图:Prometheus 结构
关于上图有以下几点需要说明。
图:Prometheus 部署
在服务器 10.10.4.38 上部署 Prometheus 的基础服务和 Grafana 服务;在服务器 10.10.4.39 上部署 Prometheus 的推送网关服务和 Prometheus 的告警服务。
图:Grafana 数据源配置
在左侧菜单点击Create→Import,在标题为Grafana.com Dashboard的输入框输入模板ID 2949后,点击任意位置进入模板导入页,如下图所示。
图:Grafana模板导入
类型声明与注释行间的文本为 Metric 数据,每行结构如下图所示。
图:Metric 数据行结构
1、Prometheus简介
Prometheus 是由 SoundCloud 开源的监控告警解决方案,其在 GitHub 上的 Star 数已经超过 3.1 万,已成为很多大公司首选的监控解决方案。Prometheus 由 Prometheus Server、PushGateway、Alertmanager、Exporter 等 4 个组件共同组成。其中,Exporter 可以由用户自行开发,只需输出符合 Prometheus 的规范数据即可;Prometheus Server 提供了 api 接口并支持自定义的 PromQL 查询语言对外实现监控数据查询输出,结合 Grafana 强大的图形模板功能,可以非常直观地以监控数据统计图表的形式进行展示。Prometheus 结构如下图所示。
图:Prometheus 结构
关于上图有以下几点需要说明。
- Prometheus Server:Prometheus 的基础服务,其从配置文件中 job 配置的 tagrets 目标服务器拉取监控数据,拉取数据周期由配置参数 scrape_interval 设置,同时开放 api 接口提供监控数据的对外查询和聚合分析功能;
- PushGateway:Prometheus 的推送网关服务。Prometheus 默认都是从被监控服务器上拉取监控数据的,但由于网络原因无法直接访问目标服务器时,可在被监控服务器上通过脚本或工具采集监控数据,然后推送给推送网关服务(PushGateway),Prometheus 的基础服务则实时地从推送网关服务提供的端口 9091 拉取监控数据,完成监控操作;
- Alertmanager:Prometheus 的告警服务,其对外开放端口 9093 接收 Prometheus Server 发送的告警信息,并按照告警规则将告警信息发送给接收目标;
- Exporter:监控数据采集接口服务,该服务可由用户按照 Prometheus 的数据规范自行开发,只需提供对外访问接口,并能输出 Prometheus 数据格式的监控数据即可。
2、Prometheus部署
Prometheus 支持多种方式部署,鉴于 Docker 化部署的便捷性,此处选择基于 docker-compose 脚本部署 Docker 化的 Prometheus 环境,部署示意如下图所示。图:Prometheus 部署
在服务器 10.10.4.38 上部署 Prometheus 的基础服务和 Grafana 服务;在服务器 10.10.4.39 上部署 Prometheus 的推送网关服务和 Prometheus 的告警服务。
1) 安装Prometheus和Grafana
在服务器 10.10.4.38 上初始化 Prometheus 和 Grafana 的 docker-compose 脚本。cat>prometheus.yaml<<EOF version: '3.5' services: prometheus: hostname: prometheus container_name: prometheus restart: always image: prom/prometheus ports: - "9090:9090" stop_grace_period: 1m grafana: hostname: grafana container_name: grafana restart: always image: grafana/grafana ports: - "3000:3000" stop_grace_period: 1m EOF # 启动镜像 docker-compose -f prometheus.yaml up -d
2) 配置Prometheus
配置 Prometheus 并持久化 Prometheus 及 Grafana 数据。cd /opt/data/apps mkdir -p {prometheus,grafana} # 复制配置文件 docker cp prometheus:/etc/prometheus prometheus/prometheus # 复制监控数据文件 docker cp prometheus:/prometheus prometheus/prometheus_data # 配置Alertmanager服务器地址 sed -i "s/# - alertmanager:9093/ - 10.10.4.39:9093/g" prometheus/prometheus/prometheus.yml # 配置告警规则文件目录 sed -i "/rule_files:/a\ - /etc/prometheus/*.rules" prometheus/prometheus/prometheus.yml # 配置PushGateway地址 cat>>prometheus/prometheus/prometheus.yml<<EOF - job_name: pushgateway # 监控job名称,全局唯一 static_configs: - targets: ['10.10.4.39:9091'] # 被监控主机的IP及Exporter的端口 labels: instance: pushgateway # 被监控主机的标识,多为主机名或docker实例名称 EOF # 设置目录权限 chown -R 65534:65534 prometheus/* # 复制Grafana配置文件 docker cp grafana:/etc/grafana grafana/config # 复制Grafana数据文件 docker cp grafana:/var/lib/grafana grafana/data # 设置目录权限 chown -R 472:472 grafana/* # 修改docker-compose脚本 cat>prometheus.yaml<<EOF version: '3.5' services: prometheus: hostname: prometheus container_name: prometheus restart: always image: prom/prometheus ports: - "9090:9090" volumes: - /etc/localtime:/etc/localtime:ro - /opt/data/apps/prometheus/prometheus:/etc/prometheus - /opt/data/apps/prometheus/prometheus_data:/prometheus stop_grace_period: 1m grafana: hostname: grafana container_name: grafana restart: always image: grafana/grafana ports: - "3000:3000" volumes: - /etc/localtime:/etc/localtime:ro - /opt/data/apps/grafana/config:/etc/grafana - /opt/data/apps/grafana/data:/var/lib/grafana stop_grace_period: 1m EOF # 重建并运行镜像 docker-compose -f prometheus.yaml up -d通过浏览器访问 http://10.10.4.38:9090/targets,就可以看到 Prometheus 和 PushGateway 这两个 Endpoint。然后通过浏览器访问 Grafana Web 管理页面 http://10.10.4.38:3000,初始用户名和密码都是 admin。
3) 安装Alertmanager和PushGateway
在服务器 10.10.4.39 上初始化 Alertmanager 和 PushGateway 的 docker-compose 脚本。cat>prometheus.yaml<<EOF version: '3.5' services: alertmanager: hostname: alertmanager container_name: alertmanager restart: always image: prom/alertmanager ports: - "9093:9093" stop_grace_period: 1m pushgateway: hostname: pushgateway container_name: pushgateway restart: always image: prom/pushgateway ports: - "9091:9091" stop_grace_period: 1m EOF # 运行镜像 docker-compose -f prometheus.yaml up -d
4) 配置Alertmanager
配置 Alertmanager 并持久化 Alertmanager 及 PushGateway 数据。cd /opt/data/apps mkdir -p prometheus # 复制Alertmanager配置文件 docker cp alertmanager:/etc/alertmanager prometheus/alertmanager # 复制Alertmanager数据文件 docker cp alertmanager:/alertmanager prometheus/alertmanager_data # 配置目录权限 chown -R 65534:65534 prometheus/alertmanager chown -R 65534:65534 prometheus/alertmanager_data # 配置prometheus.yaml cat>prometheus.yaml<<EOF version: '3.5' services: alertmanager: hostname: alertmanager container_name: alertmanager restart: always image: prom/alertmanager ports: - "9093:9093" volumes: - /etc/localtime:/etc/localtime:ro - /opt/data/apps/prometheus/alertmanager:/etc/alertmanager - /opt/data/apps/prometheus/alertmanager_data:/alertmanager stop_grace_period: 1m pushgateway: hostname: pushgateway container_name: pushgateway restart: always image: prom/pushgateway ports: - "9091:9091" volumes: - /etc/localtime:/etc/localtime:ro EOF # 重建并运行镜像 docker-compose -f prometheus.yaml up -d通过浏览器访问 http://10.10.4.39:9093,可以查看 Alertmanager 的告警信息及配置;通过浏览器访问 http://10.10.4.39:9091,可以查看 PushGateway 的相关信息。
3、监控HTTP主机状态
Prometheus 针对被监控主机,是通过轮询 Exporter 接口的形式获取监控数据的,nginx-module-vts 模块虽然也提供 Prometheus 数据格式输出,但数据并不详细,推荐使用 nginx-vts-exporter 实现 Prometheus 数据输出。nginx-vts-exporter 是由Go语言开发的,不仅提供了针对信息的监控数据,还提供了配套的 Grafana 模板。1) 在Nginx服务器上安装nginx-vts-exporter
# 获取nginx-vts-exporter二进制文件 wget https://github.com/hnlq715/nginx-vts-exporter/releases/download/v0.10.3/nginx-vts-exporter-0.10.3.linux-amd64.tar.gz tar zxmf nginx-vts-exporter-0.10.3.linux-amd64.tar.gz cp nginx-vts-exporter-0.10.3.linux-amd64/nginx-vts-exporter /usr/local/nginx/sbin/ # 运行测试 nginx-vts-exporter -nginx.scrape_timeout 10 -nginx.scrape_uri http://127.0.0.1: 8080/vts/format/json curl http://127.0.0.1:9913/metrics
2) 将nginx-vts-exporter配置为进程服务
# 安装supervisor yum install supervisor # 配置nginx-vts-exporter服务管理配置 cat>/etc/supervisord.d/nginx-vts-exporter.ini<<EOF [program:nginx-vts-exporter] ;配置进程运行命令 command=/usr/local/nginx/sbin/nginx-vts-exporter -nginx.scrape_timeout 10 -nginx.scrape_uri http://127.0.0.1:8080/vts/format/json directory=/usr/local/nginx/sbin ;进程运行目录 startsecs=5 ;启动5秒后没有异常退出表示进程正常启动,默认为1秒 autostart=true ;在supervisord启动的时候也自动启动 autorestart=true ;程序退出后自动重启 EOF # 启动supervisord并配置为开机运行 systemctl start supervisord systemctl enable supervisord # nginx-vts-exporter进程服务管理 # 查看nginx-vts-exporter进程服务状态 supervisorctl status nginx-vts-exporter # 重启nginx-vts-exporter进程服务 supervisorctl restart nginx-vts-exporter # 启动nginx-vts-exporter进程服务 supervisorctl start nginx-vts-exporter # 停止nginx-vts-exporter进程服务 supervisorctl stop nginx-vts-exporter # 访问测试 curl http://10.10.4.8:9913/metrics
3) 在Prometheus上配置监控job
cd /opt/data/apps cat>>prometheus/prometheus/prometheus.yml<<EOF # nginx-vts-exporter job - job_name: nginx_exporter static_configs: - targets: ['10.10.4.8:9913'] labels: instance: nginx-1 EOF docker restart prometheus
4) 导入Grafana模板实现图表化展示
登录 Grafana 后,在左侧菜单点击 Configuration→Add data source,选择 Prometheus 图标后进入数据源配置页面,配置如下图所示。图:Grafana 数据源配置
在左侧菜单点击Create→Import,在标题为Grafana.com Dashboard的输入框输入模板ID 2949后,点击任意位置进入模板导入页,如下图所示。
图:Grafana模板导入
4、监控TCP/UDP主机状态
TCP/UDP 主机状态模块 nginx-module-sts 虽然也提供了 Prometheus 格式数据输出,但仍然不够详细,同时也没有可用的开源 Exporter。为实现 Nginx TCP/UDP 主机状态数据的采集,可以按照 Prometheus 的数据规范编写一个 Exporter。1) Prometheus的数据类型
- 计数类型(Counter):计数类型用于累加值,一直增加或一直减少,重启进程后,会被重置。如记录请求次数、错误发生次数等;
- 计量类型(Gauge):计量类型用于常规数值,用以表示瞬间状态的数值,可大可小,重启进程后,会被重置,如硬盘空间、内存使用等;
- 直方图(Histogram):直方图可以理解为柱状图,常用于表示一段时间内数据的采样,能够对其指定区间及总数进行统计;
- 合计统计(Summary):合计统计和直方图相似,常用于表示一段时间内数据采样的结果。Histogram需要通过_bucket计算quantile(按百分比划分跟踪的结果),而Summary直接存储了quantile的值。
2) Exporter数据输出格式
Exporter 输出的数据是以 Metric 行为单位的文本数据,数据输出格式规范如下。- Exporter 输出数据的 Content-Type 必须是text类型(text/plain);
- Exporter 输出内容以行为单位,空行将被忽略,文本内容最后一行为空行;
- 每个输出监控数据的行被称为Metric行,每一行文本的最后不能有空格,否则会不被识别;
- 以“# HELP”开头的行为注释行,表示帮助信息;
- 以“# TYPE”开头的行为类型声明行,用以声明至下一个注释行间 Metric 数据的数据类型。
类型声明与注释行间的文本为 Metric 数据,每行结构如下图所示。
图:Metric 数据行结构
3) 编写Exporter脚本
Python 下的 prometheus_client 模块可以实现 Prometheus Exporter 的快速开发,因 Prome-theus 是采用拉取方式获取监控数据的,所以还需要用 flask 实现 Web 框架和访问路由功能。脚本代码如下:import prometheus_client from prometheus_client import Counter,Gauge import requests import sys import json import time from flask import Response, Flask # 初始化监控项 nginx_info = Gauge("nginx_info", "nginx_info nginx info",['hostName','nginxVersion']) nginx_server_info = Gauge("nginx_server_info", "nginx_server_info nginx server info",['host','port','protocol']) nginx_server_connections = Gauge("nginx_server_connections", "nginx connections", ['status']) nginx_server_bytes = Counter("nginx_server_bytes","request/response bytes", ['direction','host']) nginx_upstream_responses = Counter("nginx_upstream_requests","requests counter", ['backend','code','upstream']) app = Flask(__name__) @app.route("/metrics") def requests_metrics(): metrics="" url = "http://127.0.0.1:8080/sts/format/json" res = requests.get(url) all_data = json.loads(json.dumps(res.json())) # server_info nginx_info.labels(hostName=all_data["hostName"],nginxVersion=all_data["nginx-Version"]).set(time.time()) metrics+=prometheus_client.generate_latest(nginx_info) # connections connections=["accepted","active","handled","reading","requests","waiting", "writing"] for con in connections: nginx_server_connections.labels(status=con).set(all_data["connections"][con]) metrics+=prometheus_client.generate_latest(nginx_server_connections) # streamServerZones for k,streamServer in all_data["streamServerZones"].items(): nginx_server_bytes.labels(direction="in",host=k).inc(streamServer["inBytes"]) nginx_server_bytes.labels(direction="out",host=k).inc(streamServer["outBytes"]) nginx_server_info.labels(host=k,port=streamServer["port"],protocol=stream-Server["protocol"]).set(1) metrics+=prometheus_client.generate_latest(nginx_server_bytes) metrics+=prometheus_client.generate_latest(nginx_server_info) # streamUpstreamZones status_code=["1xx","2xx","3xx","4xx","5xx"] for ups,stream in all_data["streamUpstreamZones"].items(): for v in stream: for code in status_code: nginx_upstream_responses.labels(backend=v["server"],code=code,up-stream=ups).inc(v["responses"][code]) metrics+=prometheus_client.generate_latest(nginx_upstream_responses) return Response(metrics,mimetype="text/plain") @app.route('/') def index(): html='''<html> <head><title>Nginx sts Exporter</title></head> <body> <h1>Nginx sts Exporter</h1> <p><a href="/metrics">Metrics</a></p> </body> </html>''' return html if __name__ == "__main__": app.run( host="0.0.0.0", port= 9912, debug=True )在此处只选了几个监控项做样例,感兴趣的读者可继续补充完整。
4) Exporter脚本部署
将 Exporter 脚本保存为 /usr/local/nginx/sbin/nginx-sts-exporter.py。 # 配置运行环境 yum install python2-pip pip install prometheus_client requests flask # 运行Exporter python /usr/local/nginx/sbin/nginx-sts-exporter.py # 测试 curl http://127.0.0.1:9912/metrics
5) 在 Prometheus 上配置监控 job
具体配置样例如下:cd /opt/data/apps cat>>prometheus/prometheus/prometheus.yml<<EOF # nginx-vts-exporter && nginx-sts-exporter job - job_name: nginx_exporter_8 static_configs: - targets: ['10.10.4.8:9913','10.10.4.8:9912'] labels: instance: nginx-8 EOF # 重启Prometheus,使配置生效 docker restart prometheus
5、Prometheus监控告警
Prometheus 监控告警是通过 Alertmanager 组件实现的。Alertmanager 提供标准的 RESTful api 接口接收警报信息,其将告警信息按照规则重定向给接收者,接收者可以是邮箱、webhook 和微信等。Alertmanager 会对已发送的告警进行智能记录并做延时、去重等处理,从而有效避免告警风暴的产生。1) Prometheus监控告警处理流程如下:
- Prometheus Server 根据配置参数 evaluation_interval 的时间间隔按照告警规则进行计算;
- 当不满足 expr 设定计算规则的阈值时,该告警规则被置为 inactive 状态;
- 当满足 expr 设定计算规则的阈值并小于 for 设定的持续时间时,该告警规则被置为 pending 状态;
- 当满足 expr 设定计算规则的阈值并大于 for 设定的持续时间时,该告警规则被置为 firing 状态,并发送告警信息给 Alertmanager 处理;
- Alertmanager 接收到告警信息后,根据 labels 进行路由分拣,告警信息会根据 group_by 配置进行分组,如果分组不存在,则新建分组;
- 新创建的分组将等待 group_wait 指定的时间(等待时如收到同一分组的告警信息,将其进行合并),然后发送通知;
- 已有分组时将等待 group_interval 指定的时间,当上次发送通知到现在的间隔大于 repeat_interval 或者分组有更新时会发送通知。
2) 告警规则格式
ALERT <alert name> # 告警标识符,可以不唯一 IF <expression> # 触发告警阈值规则 [ FOR <duration> ] # 触发告警通知的持续时间 [ LABELS <label set> ] # 分组标签,用以Alertmanager进行分拣路由 [ ANNOTATIONS <label set> ] # 告警描述信息
3) Prometheus Server配置告警规则格式
cat>prometheus/prometheus/nginx.rules<<EOF groups: - name: NginxAlert # 规则组名称 rules: - alert: ResponseTimeAlert # 规则的名称 # 告警阈值计算规则为响应时间大于1000ms并持续10s的发送告警 expr: (nginx_upstream_responseMsec > 1000) for: 10s # 持续时间为10s labels: # 定义告警路由标签 severity: critical service: nginx annotations: # 告警信息 summary: “Nginx响应大于1000ms” description: “Nginx {{ $labels.instance }}后端集群{{ $labels.upstream }} 中{{ $labels.backend }}的响应时间大于1000ms。当前值为:{{ $value }} ms” EOF # 重启Prometheus docker restart prometheus其中,$labels 是 Metric 行数据的 labels 内容。labels 的内容可用对象数据类型方法引用;$value 是 Metric 行的 value;$labels 是多条时,会自动遍历内容,每条记录生成一个 annotations 信息。
4) Alertmanager配置
cd /opt/data/apps # 配置Alertmanager cat>prometheus/alertmanager/alertmanager.yml<<EOF # 全局配置,配置smtp信息 global: resolve_timeout: 5m # 处理超时时间,默认为5min smtp_smarthost: 'smtp.exmail.qq.com:465' # 邮箱smtp服务器代理,请替换自己的smtp # 服务器地址 smtp_from: 'monitor@nginxbar.org' # 发送告警信息的邮箱地址,请替换自己的 # 邮箱地址 smtp_auth_username: 'monitor@nginxbar.org' # 邮箱账号,请替换自己的邮箱账号 smtp_auth_password: '12345678' # 邮箱密码,请替换自己的邮箱密码 smtp_require_tls: false # 定义发送邮件的模板信息 templates: - 'template/*.tmpl' # 定义发送告警邮件的路由信息,这个路由不仅可以接收所有的告警,还可以配置多个路由 route: group_by: ['alertname'] # 告警信息分组依据,按照同类alertname # 进行分组 group_wait: 10s # 最初等待10s发送告警通知 group_interval: 60s # 在发送新告警前的等待时间 repeat_interval: 1h # 发送重复告警的等待周期为1小时,避免产 # 生邮件风暴 receiver: 'email' # 全局默认告警接收者的名称,与receivers # 的name对应 routes: - match: # 匹配labels存在如下标签的告警信息 severity: critical service: nginx receiver: nginx_email #Nginx服务器警报接收者的名称 # 定义默认警报接收者信息 receivers: - name: 'email' # 路由中对应的receiver名称 email_configs: # 告警接收者邮箱配置 - to: 'xiaodong.wang@freemud.com' # 告警接收者的邮箱配置 - name: 'nginx_email' # 路由中对应的receiver名称 email_configs: # 告警接收者邮箱配置 - to: 'xiaodong.wang@freemud.com' # 告警接收者的邮箱配置 EOF # 重启alertmanager docker restart alertmanagerNginx 监控项的阈值触发设置的告警规则时,Prometheus 就会自动发送告警到目标邮箱。