【fswatch 的介绍】
fswatch 一个跨平台文件变化监测器,当指定的文件或目录的内容被修改时接收通知。fswatch是一个工具, 通过检测文件的变化,并触发指定的命令。总之,fswatch是一个跨平台的文件更改监视,获取通知警报在指定的文件或目录的内容被改变或修改。
它在不同的操作系统上执行四种类型的监视器,例如:
- 基于Apple OS X的文件系统事件API的监视器构建。
- 基于kqueue的显示器,目前在FreeBSD的4.1通知接口还支持许多* BSD系统,OS X的包容性。
- 基于Solaris内核的文件事件通知API的监视器及其附加功能。
- 基于inotify的监视器,一个显示文件系统对应用程序修改的内核子系统。
- 基于ReadDirectoryChangesW的监视器,它是记录更改为目录的Windows API。
- 定期检查文件系统状态,在内存中保存文件修改时间,以及手动确定文件系统更改(可在任何地方使用stat)的监视器。
fswatch的特点
- 支持几种特定于OS的API
- 允许递归目录监视
- 使用包含和排除正则表达式执行路径过滤
- 支持自定义记录格式
- 此外,它支持周期性空闲事件
fswatch地址:https://github.com/emcrisostomo/fswatch(原版) https://github.com/codeskyblue/fswatch(改过)
使用场景:
当服务器文件夹的文件内容有改动的时候通知管理员或者执行某些操作,如easyswoole框架,启动的时候是先加载到内存的,有文件更新了,需要重启服务器才能生效,每次更改文件都重启web服务,开发效率会大大降低,所以需要监控文件夹的改动,如果有文件发生变化,自动停止服务器,然后启动服务器,不需要每次更新代码都手动重启。
同类工具对比:
目前拿这个fswatch替代bee, 实时的去编译运行c,cpp,java,golang等等, 应该都不是问题. 但是和bee比有什么优势呢?
既然大神问了,我就列举下:
- bee只适合Go语言; 而fswatch可以适用各种语言, 甚至是文件的远程同步
- bee可以通过配置指定监控的文件夹; fswatch可以配置监控的文件夹并指定监控的深度(0代表当前目录)
- bee可以指定监控文件的后缀; fswatch支持使用正则表达式, 来过滤监控到的文件.
- bee.json需要重其他地方拷贝;但是fswatch.json可以自动生成出来.
- fswatch支持group-kill. 这样可以确保fswatch停止后,不会有垃圾进程的存在.
- fswatch会根据程序的运行时间自动判断, 是否为服务端程序, 并适当的修改重启策略.
- bee功能庞大; fswatch的代码精简.
fswatch的安装
重要提示 :请确保您已经GNU GCC(C和C ++编译器)和开发工具( 编译必须在Debian / Ubuntu的 )安装在系统上,你从源代码编译fswatch之前。 如果没有,请使用以下命令在相应的Linux发行版上安装它。
# yum group install 'Development Tools' [On CentOS/RHEL]
# dnf group install 'Development Tools' [On Fedora 22+ Versions]
$ sudo apt-get install build-essential [On Debian/Ubuntu Versions]
wget https://github.com/emcrisostomo/fswatch/releases/download/1.11.2/fswatch-1.11.2.tar.gz
tar -xvzf fswatch-1.11.2.tar.gz
cd fswatch-1.11.2
sudo ./configure
sudo make
sudo make install sudo ldconfig
fswatch的使用
运行fswatch的一般语法是:
$ fswatch [option] [path]
在Linux上,我们建议您使用默认的inotify的显示器,你可以列出采用现有的显示器-M
或- list-monitors
选项:
$ fswatch -M
$ fswatch --list-monitors
fswatch - 列表监视器
下面的命令让您观看在当前目录(变动/home/howtoing
),与事件传递到每4秒标准输出。
该-l
或- -latency
选项允许您设置在几秒钟的等待时间,默认是1秒。
$ fswatch -l 4 .
接下来的命令监控更改为每5秒/var/log/auth.log文件:
$ fswatch -l 5 /var/log/auth.log
使用-t
或--timestamp
选项可以打印时间戳每个事件,要打印UTC格式的时间,使用-u
或--utf-time
选项。 您可以使用以及格式化时间-f
或--format-time
格式选项:
$ fswatch --timestamp /var/log/auth.log
接下来, -x
或--event-flags
告诉fswatch打印的事件标志的旁边事件路径。 您可以使用-event-现场分隔符选项,打印使用特定的分离活动。
$ fswatch --events-flags ~ /var/log/auth.log
要打印显示在你的主目录,并/var/log/auth.log文件更改事件的数值,使用-n
或--numeric
选项如下:
$ fswatch --numeric ~ /var/log/auth.log
也许你可以通过看详细用法选项和信息fswatch手册页:
$ man fswatch
欲了解更多信息和用法,请访问fswatch Github上库: https://github.com/emcrisostomo/fswatch
脚本案例
vim fswatch.sh
chmod 755 fswatch.sh 赋予脚本执行权限,copy内容到 fswatch.sh#!/bin/bash
DIR=$1if [ ! -n "$DIR" ] ;thenecho "you have not choice Application directory !"exit
fiphp easyswoole stop
php easyswoole start --dfswatch $DIR | while read file
doecho "${file} was modify" >> ./Temp/reload.log 2>&1php easyswoole reload
done运行脚本监听/easyswoole/App文件夹的改动./fswatch.sh /easyswoole/App
【企业应用—使用inotify/fswatch构建自动监控脚本】
自动告警脚本
最近项目上有这样一个需求:系统中有一个后台服务会不断的生成监控日志,根据系统的运行情况,它每天会在目录/var/alarms
下生成一个文件,文件名带有时间戳,其中内容格式如下:
1 | $ cat /var/alarms/alarms-20150228130522.csv node,summary,occurrence,proiority VIQ002,heartbeat failure,2/12/2015 01:23 AM,critical VIQ002,packages are rejected,2/12/2015 01:22 AM,major VIQ002,connection cannot be established,2/11/2015 01:23 AM,medium VIQ001,packages are rejected,2/11/2015 01:23 AM,warning VIQ001,connection cannot be established,2/09/2015 01:23 AM,medium ...
|
运维团队需要监控这个目录,如果里边的文件发生了变化,就要及时的发送邮件给工程团队解决。我们当然不可能人工的监控该目录,然后编写邮件,再拷贝粘贴,所以需要编写一个脚本来自动化这个任务。
处理方法有两种:
- 编写一个crontab的任务,每隔五分钟轮询一下,然后编写脚本来探测变化,发送邮件
- 使用操作系统提供的
inotify
相关API探测变化,编写脚本发送邮件
不过作为程序员,第二种方法显然更高级一些。另外相对于检测文件变化(对比目录树,检查时间戳,而且还要记录上一次变更的状态等),编写一个发送邮件的脚本要简单得多。
使用inotify
如果在Linux
下,我们可以使用inotify
相关的工具,你可以使用你正在使用的系统下的包管理工具来安装。也可以直接从源码包编译安装。
安装之后,系统中就有了一个叫做inotifywait
的命令,这个命令提供多个参数。默认的inotifywait
在接收到指定的事件(文件变化)后,会打印信息并退出。可以使用-m
参数让inotifywati
处于监听状态。-e
参数指定需要监听的事件类型,下面是几个常见的事件类型:
CREATE
,创建MODIFY
,修改CLOSE_WRITE,CLOSE
,写入成功
还可以通过--format
来指定事件的输出,%w
表示监控的文件名,%f
表示如果被监控的对象是目录,则当发生事件时返回文件名。比如下面的命令:
1 | $ inotifywait -m -e close_write /var/alarms --format "%w%f"
|
表示以监控模式(事件发生后不退出,继续监听),监听close_write
事件,在/var/alarms
目录上,并且输出的格式为%w%f
。
这样我们在另一个窗口上模拟事件发生:
1 | $ touch /var/alarms/alarms-20150228130522.csv
|
当前的窗口就会出现/var/alarms/alarms-20150228130522.csv
这样的输出。有了这个功能,我们只需要编写一段简单的脚本就可以完成上一小节中的问题了:
1 | #!/bin/bash DIR=$1inotifywait -m -e close_write $DIR --format "%w%f" | while read FILE docat ${FILE} | mail -s "Alarm: $FILE" juntao.qiu@gmail.com done
|
命令mail
是Linux下默认的邮件客户端,可以完成邮件的发送功能。将上边的脚本命名为monitor.sh
,添加可执行权限,并启动监控:
1 2 | $ chmod +x monitor.sh $ ./monitor.sh /var/alarms
|
这样,当目标目录/var/alarms
发生变化后,我们就可以收到告警邮件了!
Mac OSX下使用fswatch
如果是在Mac OSX
下,虽然没有了inotify
相关的API,但是我们可以使用fswatch
来完成同样的工作。
使用brew
安装fswatch
:
即可。fswatch
也有很多选项,我们这里仅使用-0
(表示以传统的NUL作为字符串终结符,因为*nix下文件名可以包含任意字符,比如空格)。我们可以很容易的用xargs
将检测到的事件进行进一步的处理:
1 | fswatch -0 /var/alarms | xargs -0 -n 1 ~/bin/send-notify.sh
|
其中,-0
的意思与fswatch
的命令中的-0
一致,-n 1
表示每条NUL
结尾的字符串都执行一次脚本。脚本send-notify.sh
的内容如下:
1 | #!/bin/bashFILE=$1 cat $FILE | mail -s "Alarm: $FILE" baiducloud@gmail.com
|
这样,当文件发生变化时,脚本就会发送一封邮件到指定邮箱了(由于我自己的laptop的hostname不像是一个合理的主机名,所以Gmail会把这封邮件放到垃圾邮件列表中,这里只是用作示例而已)。
当然,由于脚本是我们自己可以编写的,所以理论上当检测到变化之后,我们可以做任何事情,比如说几句话,播放一段音乐等。