C: “мониторинг” NGINX с помощью AF_INET

Автор: | 08/08/2017
 

В продакшене мы будем использовать что-то вроде Monit, а для Dev – решил написать маленькую утилиту, которая проверяет доступность NGINX и отправляет письмо при проблемах.

Программа содержит две рабочие функции – socket_get(), которая с помощью connect()  пытается подключиться к порту NGINX (AF_INET сокету), и send_alarm(), которая с помощью system() выполняет mailx для отправки сообщений.

Отправку можно было бы реализовать через libcurl, пример тут>>>.

Код:

#include <stdio.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

// удобнее было бы вынести адрес и порт в аргументы main()
#define HOST_ADDR "127.0.0.1"
#define HOST_PORT 80

int socket_get(int i_addr, int i_port) {

    int socket_desc;
    struct sockaddr_in server;

    socket_desc = socket(AF_INET , SOCK_STREAM , 0);

    if (socket_desc == -1) {
        return 1;
    }

    server.sin_addr.s_addr = inet_addr(HOST_ADDR);
    server.sin_family = AF_INET;
    server.sin_port = htons(HOST_PORT);

    // пробуем подключиться к HOST_ADDR:HOST_PORT, переданных через структуру server
    if (connect(socket_desc , (struct sockaddr *)&server , sizeof(server)) < 0) {
        return -1;
    }

    return 0;
}

void send_alarm() {

    char cmd[100];
    char to[20] = "[email protected]";

    char hostname[1024], from_host[24];
    gethostname(hostname, 1024);

    // у нас два сервера с NGINX, определяем $HOSTNAME и задаём имя
    if (strcmp(hostname, "hostname1") ==0) {
         strncpy(from_host, "Master", 24);
    } else if (strcmp(hostname, "hostname2") ==0) {
        strncpy(from_host, "Secondary", 24);
    } else {
        exit(1);
    }

    // конкатенируем всю команду в одну строку
    sprintf(cmd, "echo NGINX is in DOWN state on the host %s! | /usr/bin/mailx -s \"ALARM from %s\" %s", from_host, from_host, to);
    // и передаём её system()
    system(cmd);

}

int main(int argc , char *argv[]) {

    if (socket_get(atoi(HOST_ADDR), HOST_PORT) != 0) {
        printf("Can't connect to local NGINX service!\n");
        send_alarm();
    }
}

Собираем:

[simterm]

# gcc monit.c -o monit

[/simterm]

Добавляем в крон:

[simterm]

# crontab -l
* * * * * /root/scripts/monit

[/simterm]

Выполняется каждую минуту, и в случае проблем с подключением к NGINX – отправляет уведомление на почту:

[simterm]

# cat /var/log/mail.log
Aug  7 15:11:39 hostname1 postfix/pickup[7503]: 898CBFCA55: uid=0 from=<root@hostname1.asgaqmzoya1ebbq1oirk0uw30g.ax.internal.cloudapp.net>
Aug  7 15:11:39 hostname1 postfix/cleanup[11752]: 898CBFCA55: message-id=<20170807151139.898CBFCA55@hostname1.asgaqmzoya1ebbq1oirk0uw30g.ax.internal.cloudapp.net>
Aug  7 15:11:39 hostname1 postfix/qmgr[1561]: 898CBFCA55: from=<root@hostname1.asgaqmzoya1ebbq1oirk0uw30g.ax.internal.cloudapp.net>, size=562, nrcpt=1 (queue active)
Aug  7 15:11:40 hostname1 postfix/smtp[11755]: 898CBFCA55: to=<[email protected]>, relay=mail.domain.kiev.ua[77.***.***.20]:25, delay=0.54, delays=0.04/0.01/0.16/0.33, dsn=2.0.0, status=sent (250 OK id=1dejgx-0006gE-QF)
Aug  7 15:11:40 hostname1 postfix/qmgr[1561]: 898CBFCA55: removed

[/simterm]

Готово.