Linux:在磁盘空间不足的情况下触发实时报警

我想订阅守护进程,inotify风格,以接收通知时,给定的文件系统上的空闲空间低于一定的百分比。 这可能吗?

这是一个基于事件的机制。 我没有跑很长时间,所以不能保证它的稳定性。

这使用了一个名为fanotify的非常新的系统调用API。 运行它可能需要2.6.37或更高的内核(例如,EL5是不可能的)。 如果你接到投诉,它不会编译,它可能太老的内核。

它编译与:

gcc -o notifier notifier.c

它的工作方式是这样的:

./notifier / home / file / dev / shm / monit 10

参数如下:

  1. 您要监视的文件系统上的文件。
  2. 如果超过阈值,将创build一个文件的path(如果在下面的话将被删除)
  3. 可用空间的百分比应该低于阈值。

这将设置显示器。 文件系统上的每个已closures的文件句柄都会启动事件检查。

#include <stdio.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <limits.h> #include <linux/fanotify.h> #include <sys/stat.h> #include <sys/statvfs.h> #include <fcntl.h> int main(const int argc, const char **argv) { if (argc < 4) { fprintf(stderr, "Supply a path to a file on the mountpoint to listen to, a monitor file and a free %% threshold..\n"); exit(1); } if (access(argv[1], R_OK) < 0) { fprintf(stderr, "Unable to read file: %s\n", strerror(errno)); exit(1); } int len, rc; unsigned char donestat = 0, alerted = 0; const char *path = argv[1]; const char *monpath = argv[2]; int threshold = atoi(argv[3]); char buf[4096]; struct fanotify_event_metadata *fem = NULL; int fan_fd = -1; uint64_t mask = FAN_CLOSE_WRITE; struct statvfs sfs; float bfree; memset(&sfs, 0, sizeof(sfs)); unlink(monpath); if (threshold <= 0 || threshold >= 100) { fprintf(stderr, "Incorrect threshold provided"); rc = 1; goto end; } fan_fd = fanotify_init(FAN_CLASS_NOTIF, FAN_CLOEXEC); if (fan_fd < 0) { perror("fanotify_init"); rc = 1; goto end; } rc = fanotify_mark(fan_fd, FAN_MARK_ADD|FAN_MARK_MOUNT, mask, AT_FDCWD, path); if (rc < 0) { perror("fanotify_mark"); rc = 1; goto end; } while ((len = read(fan_fd, buf, sizeof(buf))) > 0) { fem = (void *)buf; donestat = 0; while (FAN_EVENT_OK(fem, len)) { if (fem->vers < 2) { fprintf(stderr, "fanotify is too old\n"); goto end; } if (!donestat) { rc = fstatvfs(fem->fd, &sfs); if (rc < 0) { perror("fstatvfs"); rc = 1; goto end; } bfree = 100 - (((float)(sfs.f_blocks - ((sfs.f_blocks - sfs.f_bfree))) / (float)(sfs.f_blocks)) * 100); if ((bfree < (float)threshold)) { if (!alerted) { creat(monpath, S_IRUSR|S_IWUSR); alerted = 1; } } else { if (alerted) { unlink(monpath); alerted = 0; } } } donestat = 1; close(fem->fd); fem = FAN_EVENT_NEXT(fem, len); } } if (len < 0) { perror("Read fan_fd"); rc = 1; goto end; } end: close(fan_fd); exit(rc); } 

从那里你可以使用inotify来监视要创build/删除的文件,以了解结果。

要进行testing,请将阈值设置为您知道现在违反的阈值,然后触摸受影响的文件系统上的文件。 你应该得到你的监视器文件创build。

显然它最好把监视器文件放在不同的文件系统上(/ dev / shm是个好地方)。

你可以使用Monit实用程序来做到这一点。 您可以设置这个检查的时间间隔,但60秒是轮询的标准。

文件系统监视的configuration将如下所示:

 check device root with path / if SPACE usage > 80% then alert check device var with path /var if SPACE usage > 80% then alert 

既然会有更多的东西要监控,那么你可能要花一些时间来学习nagios。 这听起来像是你遇到了空间不足的情况,而且你不希望这种特殊的失败再次发生。 但系统可能以意想不到的方式失败,所有的服务都应该被监视。

在捏,你可以只使用插件。 他们很容易安装,并做他们所说的(check_disk检查磁盘空间)。 他们在失败时返回“不是0”。 失败可能是警告,危急或未知。

 apt-get install nagios-plugins 

向crontab添加这样的内容会导致$ send_error失败。 如果使用分区“/”的50%以上,它将被触发。

 send_error="command you want to run on failure" */5 * * * * /usr/lib/nagios/plugins/check_disk -w 50% -c 25% -p / || $send_error