Monit是一个跨平台的用来监控Unix/Linux系统(比如Linux、BSD、OSX、Solaris)的工具。Monit特别易于安装,而且非常轻量级(只有500KB大小),并且不依赖任何第三方程序、插件或者库。

Monit可以监控服务器进程状态、HTTP/TCP状态码、服务器资源变化、文件系统变动等等,根据这些变化,可以设定邮件报警、重启进程或服务。易于安装、轻量级的实现以及强大的功能,让Monit成为一个理想的后备监控工具。


安装

yum install monit


当然也可以下载源码安装。

当前使用版本:

# monit -VThis is Monit version 5.17.1Built with ssl, with pam and with large files
Copyright (C) 2001-2016 Tildeslash Ltd. All Rights Reserved.

常用命令

monit -t # 配置文件检测monit # 启动monit daemonmonit -c /var/monit/monitrc # 启动monit daemon时指定配置文件monit reload # 当更新了配置文件需要重载monit status # 查看所有服务状态monit status nginx # 查看nginx服务状态monit stop all # 停止所有服务monit stop nginx # 停止nginx服务monit start all # 启动所有服务monit start nginx # 启动nginx服务monit -V # 查看版本

配置文件

使用yum安装默认配置文件在:

/etc/monitrc # 主配置文件/etc/monit.d/ # 单独配置各项服务

为了保护控制文件和密码的安全性,monitrc必须具有读写权限不超过0700(u=xrw,g=,o=)。

主配置文件主要配置全局:
/etc/monitrc

## Global sectionset daemon 30set logfile syslog# 邮箱设置set mailserver xxx@xxx
username "xxx" password "xxx"# using sslset alert xxx@xxxset alert xxx@xxx #可以设置多个set mail-format {
from: xxx@xxx
subject: [$SERVICE] $EVENT
message:
[$SERVICE] $EVENT

Date: $DATE
Action: $ACTION
Host: $HOST
Description: $DESCRIPTION

Your faithful employee,
Monit }# 设置web服务认证set httpd port 2812 and# ssl enable# pemfile /etc/certs/monit.pem# use address all # only accept connection from localhostallow 127.0.0.1 # 允许localhost连接allow admin:monit # web登录的用户名和密码## Services## Includesinclude /etc/monit.d/*

配置文件关键字:
'if', 'and', 'with(in)', 'has', 'us(ing|e)', 'on(ly)', 'then', 'for', 'of' 。

如何监控

基本流程

1.修改主配置文件
2.在/etc/monit.d/增加指定服务的配置文件,例如/etc/monit.d/nginx。配置变写完毕,使用下列,命令检测是否正确:

monit -t

3.启动monit:

monit

4.启动所有服务或者单个服务:

monit start all

5.若修改了配置文件,重载配置:

monit reload

6.使用下面命令查看监控状态:

monit status

控制台输出:

$ monit statusThe Monit daemon 5.17.1 uptime: 4d 15h 45m 

Process 'nginx'
  status                            Running
  monitoring status                 Monitored
  pid                               20563
  parent pid                        1
  uid                               0
  effective uid                     0
  gid                               0
  uptime                            3d 22h 36m 
  threads                           1
  children                          2
  memory                            820 kB
  memory total                      7.3 MB
  memory percent                    0.0%
  memory percent total              0.2%
  cpu percent                       0.0%
  cpu percent total                 0.0%
  data collected                    Sat, 18 Feb 2017 10:09:56System 'iZ28s4jxu17Z'
  status                            Running
  monitoring status                 Monitored
  load average                      [0.03] [0.06] [0.06]
  cpu                               8.4%us 0.8%sy 0.2%wa
  memory usage                      1.5 GB [41.2%]
  swap usage                        0 B [0.0%]
  data collected                    Sat, 18 Feb 2017 10:09:56

或者浏览器输入http://localhost:2812登录网页版查看实时状态。

设置错误提醒

Monit默认情况下如果一个服务失败只发送一个通知:

alert foo@bar

如果您希望在服务保持处于失败状态时每十个周期通知一次,您可以使用:

alert foo@bar with reminder on 10 cycles

同样,如果您想在每个失败的周期获得通知,您可以使用:

alert foo@bar with reminder on 1 cycle

要禁止某些用户和服务的警报,可以在服务检查的局部配置里添加语句:

noalert mail-address

服务类型

首先需要理解在monit里什么是服务(service)。看监控语法:

check <类型> <服务名> [PATH <path>] [ADDRESS <host address>]

其中类型是monit支持的监控类型,一共有:system、file、process、fifo、filesystem、directory、host、network、program。
服务名必需是英文且唯一,不可以出现重复!
后面的带[]是根据类型需要添加的。

服务类型语法

每个服务条目由关键字组成check,后面是服务类型。每个条目需要唯一的描述性名称,可以自由选择。此名称由Monit用于在内部和与用户的所有交互中引用该服务。

目前,支持九种类型的检查语句:

进程

CHECK PROCESS <unique name> <PIDFILE <path> | MATCHING <regex>>

<path>是程序的pid文件的绝对路径。pid文件是一个包含进程唯一ID的文件。如果pid文件不存在或不包含正在运行的进程的PID编号,则Monit将调用该条目的start方法(如果已定义)。

<regex>是使用PID文件的替代方法,并使用进程名称模式匹配来查找要监视的进程。选择具有最长正常运行时间的最顶部匹配的父级,因此如果进程名称是唯一的,则此检查形式是最有用的。应该尽可能使用Pid文件,因为它定义了预期的PID。您可以测试一个进程是否匹配来自命令行使用的模式monit procmatch "regex-pattern"。这将列出匹配或不匹配的所有进程,regex模式。

文件

CHECK FILE <unique name> PATH <path>

<path>是文件的绝对路径。如果文件不存在,Monit将调用该条目的start方法(如果已定义),如果<path>不指向常规文件类型(例如目录),Monit将禁用此条目的监视。如果Monit在被动模式下运行或者没有定义start方法,Monit只会在错误时发送警报。

Fifo

CHECK FIFO <unique name> PATH <path>

<path>是fifo的绝对路径。如果fifo不存在,Monit将定义调用该条目的start方法,如果<path>没有指向fifo类型(例如目录),Monit将禁用对该条目的监视。如果Monit在被动模式下运行或者没有定义start方法,Monit只会在错误时发送警报。

文件系统

CHECK FILESYSTEM <unique name> PATH <path>

<path>是设备/磁盘,安装点,文件或作为文件系统一部分的目录的路径。建议直接使用块特殊文件(例如Linux上的/dev/hda1或Solaris上的/dev/dsk/c0t0d0s1等)如果使用挂载点(例如/data),请注意文件系统是卸载的测试仍然是真的,因为挂载点存在。

如果文件系统不可用,Monit将调用该条目的start方法(如果已定义)。如果不指向文件系统,Monit将禁用对此条目的监视。如果Monit在被动模式下运行或者没有定义start方法,Monit只会在错误时发送警报。

目录

CHECK DIRECTORY <unique name> PATH <path>

<path>是目录的绝对路径。如果目录不存在,Monit将调用该条目的start方法(如果已定义)。如果<path>不指向目录,monit将禁用对此条目的监视。如果Monit在被动模式下运行或者没有定义启动方法,Monit只会在错误时发送警报。

远程主机

CHECK HOST <unique name> ADDRESS <host address>

主机地址可以指定为主机名字符串或点分十进制格式的IP地址字符串。例如,tildeslash.com或“64.87.72.95”。

系统

CHECK SYSTEM <unique name>

的唯一的名称通常是本地主机名,而是可以使用任何描述性名称。如果使用变量$ HOST作为名称,它将扩展为主机名。此检查允许监控一般系统资源,如CPU使用率,总内存使用或负载平均。该唯一名称在邮件警报中用作系统主机名,在M/Monit中用作主机条目的初始名称。

自定义

CHECK PROGRAM <unique name> PATH <executable file> [TIMEOUT <number> SECONDS]

<path>是可执行程序或脚本的绝对路径。该状态测试允许一个检查程序的退出状态。如果程序没有在<number>秒内完成执行,Monit将终止它。默认程序超时为300秒(5分钟)。程序的输出被记录并在用户界面和警报中可用,默认情况下最大为512B。您可以使用set limits语句自定义限制。

网络

CHECK NETWORK <unique name> <ADDRESS <ipaddress> | INTERFACE <name>>

<ipaddress>是受监视网络接口的IPv4或IPv6地址。也可以在Linux上使用接口名称,例如“eth0”。

服务检测时间

可以使用every语句修改服务检查计划。

有三种变体:

1.轮询周期倍数

EVERY [number] CYCLES

2.Cron-style

EVERY [cron]# [cron]# * * * * *# 分 时 日 月 周

3.与Cron-style相反(do-not-check)

NOT EVERY [cron]

示例:
示例1:每两个周期检查一次

check process nginx with pidfile /var/run/nginx.pid
every 2 cycles

示例2:在上午8点到下午7点之间检查每个工作日

check program checkOracleDatabasewith path /var/monit/programs/checkoracle.pl
every "* 8-19 * * 1-5"

示例3:在星期日0AM到3AM之间不要在备份窗口中运行检查,否则运行具有常规轮询周期频率的检查。

check process mysqld with pidfile /var/run/mysqld.pidnot every "* 0-3 * * 0"

注意不要使用特定的分钟,因为Monit可能不会在那分钟运行。

服务重启限制

Monit提供了一种重启限制机制,用于服务在较长时间内拒绝启动或响应的情况。
超时语句的语法如下(关键字在大写):

IF <number> RESTART <number> CYCLE(S) THEN <action>

该行动值是常见的任何一个动作或超时(为向后兼容,等于取消监视行动)。

下面是一个示例,如果Monit将在3个周期内重新启动服务2次,将取消监视服务:

if 2 restarts within 3 cycles then unmonitor

要在禁用监视后使Monit再次检查服务,请从命令行运行monit monitor servicename。

超时设置自定义exec的示例:

if 5 restarts within 5 cycles then exec "/foo/bar"

停止服务的示例:

if 7 restarts within 10 cycles then stop

服务示例

一个完整的HOST监控服务语法:

check host <service> address <address or ip>if failed
xxx
then alert
alert xx@xxx

解释:
第一行是检查类型为host的服务,需要设定服务名及服务器地址;
第二行至第四行的意思是中间的预期代码xxx如果失败,则执行then alert
最后一行alert xx@xxx配置局部推送的邮箱,可选。可以多行,表示配置多个。

第二行至第四行也可以写成一行:

if failed xxx then alert

下面是示例:

/etc/monit.d/test

## systemcheck system $HOSTif loadavg (1min) > 4 then alertif loadavg (5min) > 2 then alertif cpu usage > 95% for 10 cycles then alertif memory usage > 75% then alertif swap usage > 25% then alert## filecheck file apache_bin with path /usr/local/apache/bin/httpdif failed checksum and
expect the sum 8f7f419955cefa0b33a2ba316cba3659 then unmonitorif failed permission 755 then unmonitorif failed uid root then unmonitorif failed gid root then unmonitor
alert security@foo.bar on {
checksum, permission, uid, gid, unmonitor
} with the mail-format { subject: Alarm! }
group server## processcheck process apache with pidfile /usr/local/apache/logs/httpd.pid
start program = "/etc/init.d/httpd start" with timeout 60 seconds
stop program = "/etc/init.d/httpd stop"if cpu > 60% for 2 cycles then alertif cpu > 80% for 5 cycles then restartif totalmem > 200.0 MB for 5 cycles then restartif children > 250 then restartif loadavg(5min) greater than 10 for 8 cycles then stopif failed host www.tildeslash.com port 80 protocol http
and request "/somefile.html"then restartif failed port 443 protocol https with timeout 15 seconds then restartif 3 restarts within 5 cycles then unmonitor
depends on apache_bin
group server## filesystemcheck filesystem datafs with path /dev/sdb1
start program = "/bin/mount /data"stop program = "/bin/umount /data"if failed permission 660 then unmonitorif failed uid root then unmonitorif failed gid disk then unmonitorif space usage > 80% for 5 times within 15 cycles then alertif space usage > 99% then stopif inode usage > 30000 then alertif inode usage > 99% then stop
group server## file's timestampcheck file database with path /data/mydatabase.dbif failed permission 700 then alertif failed uid data then alertif failed gid data then alertif timestamp > 15 minutes then alertif size > 100 MB then exec "/my/cleanup/script" as uid dba and gid dba## directory permissioncheck directory bin with path /binif failed permission 755 then unmonitorif failed uid 0 then unmonitorif failed gid 0 then unmonitor## remote hostcheck host myserver with address 192.168.1.1if failed ping then alertif failed port 3306 protocol mysql with timeout 15 seconds then alertif failed port 80 protocol http
and request /some/path with content = "a string"then alert## network link statuscheck network public with interface eth0if failed link then alertif changed link then alertif saturation > 90% then alertif download > 10 MB/s then alertif total upload > 1 GB in last hour then alert## custom program status outputcheck program myscript with path /usr/local/bin/myscript.shif status != 0 then alert

控制台访问验证

访问Monit Web界面主要通过ALLOW选项进行控制,ALLOW选项用于指定身份验证并仅授权特定客户端进行连接。

如果正在使用Monit命令行界面,至少需要一个明文密码(见下文),否则Monit命令行界面将无法连接到Monit Web界面。

尝试连接到Monit,但提交错误的用户名和/或密码的客户端将使用其IP地址记录。

主机和网络允许列表

Monit维护允许连接的主机和网络的访问控制列表。您可以添加任意数量的主机,但只允许具有有效域名或其IP地址的主机。

Monit将查询名称服务器以检查任何尝试连接的主机。如果主机(客户端)正在尝试连接,但无法在访问列表中找到或无法解决,Monit将立即关闭与客户端的连接。

配置文件示例:

set httpd port 2812
  allow localhost  allow my.other.work.machine.com  allow 10.1.1.1
  allow 192.168.1.0/255.255.255.0
  allow 10.0.0.0/8

在允许列表中未提及的客户端,尝试连接到Monit将被拒绝访问,并使用其IP地址记录。

明文用户和密码

如果allow语句包含用单独的“:”字符分隔的用户名和密码,Monit将使用基本认证。

注意:可以使用特殊字符,但对于非字母数字,必须引用密码。

句法:

 ALLOW <username>:<password>

PAM

在提供PAM的平台(如Linux,Mac OS X,FreeBSD,NetBSD)上支持PAM。

句法:

 ALLOW @<group>

其中group是允许访问Monit的Web界面的组名称

只读用户

最后,可以将一些用户定义为只读。只读用户可以读取Monit网页,但无法访问按钮,并且无法从Web界面更改服务。

  set httpd port 2812
      allow admin:password
      allow hauk:password read-only
      allow @admins      allow @users read-only

通过在 username:password 后使用只读关键字将用户设置为只读。在上述示例中,用户hauk被定义为只读用户,而admin用户具有所有访问权限。

实践

监听Nginx、php-fpm及API接口

/etc/monit.d/http

# check nginx processcheck process nginx with pidfile /run/nginx.pid
start program = "/usr/local/nginx/sbin/nginx " with timeout 10 seconds
stop program = "/usr/local/nginx/sbin/nginx -s stop"if changed pid then restart# check php-fpm processcheck process php-fpm with MATCHING php-fpm
start program = "/usr/local/php/sbin/php-fpm" with timeout 10 seconds
stop program = "/usr/bin/killall php-fpm" with timeout 10 secondsif failed port 9000 for 3 cycles then restart# check http statuscheck host dev_xxx_http address xxx
start program = "/usr/local/php/sbin/php-fpm ; /usr/local/nginx/sbin/nginx -s reload" with timeout 10 seconds
stop program = "/usr/bin/killall php-fpm ; /usr/local/nginx/sbin/nginx -s stop" with timeout 10 secondsif failed
port 80protocol http
and status = 200for 3 cycles
then restart#alert xxx@xxx #可以单独设置新的通知者#alert xxx@xxxif failed
port 80protocol http
request "/Api/Login/Get_Userinfo/"and status = 200for 3 cycles
then restart

监听TCP

/etc/monit.d/tcp

check host dev_xxx_swoole_xxx address xxx
start program = "/usr/local/php/bin/php Server.php" with timeout 10 seconds
stop program = "/usr/bin/kill -9 $(ps -aux|grep -E 'Server|swoole_server'|grep -v grep|awk '{print $2}')" with timeout 10 secondsif failed port xxx type tcp for 3 cycles then restart