优化磁盘告警

This commit is contained in:
aixiao 2024-05-23 18:12:04 +08:00
parent 2722e9b2e1
commit 3aa4d63799
6 changed files with 102 additions and 84 deletions

11
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,11 @@
{
// 使 IntelliSense
//
// 访: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
]
}

View File

@ -7,6 +7,7 @@
"clamscan.h": "c",
"libiptc.h": "c",
"stdio.h": "c",
"nginx.h": "c"
"nginx.h": "c",
"cjson.h": "c"
}
}

93
disk.c
View File

@ -1,15 +1,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mntent.h>
#include <sys/statvfs.h>
#include "disk.h"
// 获取指定路径的磁盘使用率
int get_disk_usage(const char *path, double *usage) {
struct statvfs stat;
if (statvfs(path, &stat) != 0) {
// 处理错误
perror("statvfs failed");
return -1;
}
@ -23,37 +19,100 @@ int get_disk_usage(const char *path, double *usage) {
return 0;
}
int disk_usage() {
// 第三方邮箱告警, 磁盘使用率
int QQ_mail_warning_Disk_Use(const char *recv_mail, const char *local_ip, const char *text, int current_length) {
int command_len = current_length + sizeof(QQMAIL_DISK_USE) + strlen(recv_mail) + strlen(local_ip) + 256;
char command[command_len];
// 生成邮件正文
char mail_text[command_len];
snprintf(mail_text, command_len, "Host:%s\n%s", local_ip, text);
// 生成命令字符串
snprintf(command, command_len, QQMAIL_DISK_USE, recv_mail, mail_text);
// 打印命令用于调试
printf("Command: %s %d\n", command, current_length);
// 执行命令
int ret = system(command);
if (ret == -1) {
perror("system command failed");
return -1;
}
return 0;
}
int disk_usage(conf *conf, char *local_ip, int threshold) {
FILE *mounts;
struct mntent *ent;
char *result;
size_t result_size = INITIAL_SIZE;
size_t current_length = 0;
result = (char *)malloc(result_size);
if (result == NULL) {
perror("内存分配失败");
return 1;
}
result[0] = '\0'; // 初始化为空字符串
// 打开挂载表
mounts = setmntent("/etc/mtab", "r");
if (mounts == NULL) {
perror("setmntent failed");
perror("打开挂载表失败");
free(result);
return 1;
}
while ((ent = getmntent(mounts)) != NULL)
{
// 遍历每个挂载的文件系统
while ((ent = getmntent(mounts)) != NULL) {
double usage = 0;
if (strstr(ent->mnt_fsname, "/dev/") != NULL)
{
//printf("%s %s %s\n", ent->mnt_fsname, ent->mnt_dir, ent->mnt_type);
// 检查文件系统是否为设备
if (strstr(ent->mnt_fsname, "/dev/") != NULL) {
// 获取挂载点的磁盘使用率
if (get_disk_usage(ent->mnt_dir, &usage) != 0) {
fprintf(stderr, "Failed to get disk usage for %s\n", ent->mnt_dir);
fprintf(stderr, "获取 %s 的磁盘使用率失败\n", ent->mnt_dir);
continue;
}
int threshold = 1;
// 如果使用率超过阈值则拼接字符串
if (usage > threshold) {
printf("挂载点: %s 使用率: %.2f%% 阀值: %d%%\n", ent->mnt_dir, usage, threshold);
char buffer[BUFFER_INCREMENT];
int len = snprintf(buffer, BUFFER_INCREMENT, "挂载点:%s 使用率:%.2f%% 阀值:%d%%\n", ent->mnt_dir, usage, threshold);
// 检查缓冲区大小是否足够
if (current_length + len >= result_size) {
result_size += BUFFER_INCREMENT;
result = (char *)realloc(result, result_size);
if (result == NULL) {
perror("内存重新分配失败");
endmntent(mounts);
return 1;
}
}
strcat(result, buffer);
current_length += len;
}
}
}
// 发送邮件警告
if (current_length > 0) {
if (QQ_mail_warning_Disk_Use("aixiao@aixiao.me", "127.0.0.1", result, current_length) != 0) {
fprintf(stderr, "发送邮件失败\n");
}
}
// 清理
free(result);
endmntent(mounts);
return 0;
}

8
disk.h
View File

@ -7,6 +7,12 @@
#include <mntent.h>
#include <sys/statvfs.h>
extern int disk_usage();
#include "rhost.h"
#define INITIAL_SIZE 1024
#define BUFFER_INCREMENT 512
int disk_usage(conf *conf, char *local_ip, int threshold);
#endif

64
rhost.c
View File

@ -5,6 +5,7 @@
#include "clamscan.h"
#include "ccronexpr.h"
#include "nginx.h"
#include "disk.h"
#include "./cJSON/cJSON.h"
#include "ip2region/ip2region.h"
@ -49,7 +50,6 @@ void cron_free(void *p)
// 自定义 printf 函数
void my_printf(const char *format, ...) {
va_list args;
@ -394,29 +394,6 @@ int QQ_mail_warning_Virus_files(char *local_ip, int Virus_number, conf *conf)
return system(command);
}
// 第三方邮箱告警, 磁盘使用率
int QQ_mail_warning_Disk_Use(char *local_ip, int disk_use, conf *conf)
{
char *command;
char *text;
char temp[32];
command = (char *)alloca(BUFFER + (sizeof(QQMAIL)) + 1);
text = (char *)alloca(BUFFER);
memset(command, 0, BUFFER + (sizeof(QQMAIL)) + 1);
memset(text, 0, BUFFER);
memset(temp, 0, 32);
strcpy(temp, local_ip);
temp[_strlen(local_ip) - 1] = '\0';
snprintf(text, BUFFER, "Host:%s, Disk usage reaches threshold!, Please handle!", temp);
snprintf(command, BUFFER, QQMAIL_DISK_USE, conf->RECV_MAIL, text);
return system(command);
}
// IP段白名单对比
int whitelist(char *client_ip, char (*whitelist_ip)[WHITELIST_IP_NUM])
{
@ -458,34 +435,6 @@ int isregion(char *str, char (*region_list)[WHITELIST_IP_NUM])
return 0;
}
// 磁盘使用率
int disk_waring(int threshold)
{
FILE *fp = NULL;
char buffer[BUFFER];
char command[BUFFER];
int is = 0;
#define DF "for u in `df -mh | grep -E -e \".:.\" -e \"^/dev\" | awk '{print $5}' | sed 's|%%||g'`; do if test \"$u\" -ge %d; then echo \"$u\"; fi done"
memset(buffer, 0, BUFFER);
memset(command, 0, BUFFER);
snprintf(command, BUFFER, DF, threshold);
//printf("%s\n", command);
fp = popen(command, "r");
while (fgets(buffer, BUFFER, fp) != NULL) {
printf("%s", buffer);
is = 1;
break;
}
pclose(fp);
return is;
}
char *_time()
{
char temp[BUFFER];
@ -1160,16 +1109,9 @@ goto_daemon:
// 磁盘告警
if (1 == conf->IS_DISK) {
if (disk_waring(conf->DISK_USE) == 1) {
printf("Disk usage reaches threshold!, Please handle!\n");
if (conf->IS_QQMAIL == 1) {
QQ_mail_warning_Disk_Use(public_ip, 0, conf);
sleep(3);
}
} else {
printf("Disk usage does not reach threshold!\n");
}
disk_usage(conf, public_ip, conf->DISK_USE);
}
_exit(r);
} else {

View File

@ -68,7 +68,6 @@ typedef struct now_next_time
#define CENTOS_LE_10 "grep -E \"^$(LC_ALL=\"C\" date \"+%h\")..$(LC_ALL=\"C\" date | awk '{print $3}')\" /var/log/secure | grep failure | grep rhost"
#define QQMAIL "gomail -r %s -s \"System ban IP\" -t \"%s\""
#define QQMAIL_Virus "gomail -r %s -s \"System Virus Infected\" -t \"%s\""
#define QQMAIL_DISK_USE "gomail -r %s -s \"System Disk Use\" -t \"%s\""