Итак, вы системный администратор UX-машины. Вы закончили работу в 17:00, пошли домой, поужинали и легли спать в 10:00. Все идет отлично.

До тех пор, пока вы не проснетесь утром и не получите электронное письмо от своего разгневанного босса о том, почему серверы перестали работать в 2 часа ночи.

Это обычная проблема для системного администратора, особенно когда серверы, которыми он или она управляет, должны работать круглосуточно и без выходных. Но очевидно, что вы не можете быть на ногах 24 часа в сутки 7 дней в неделю перед своим компьютером, многократно набирая «top», «vmstat» или «df -h», пока не обнаружите проблему.

Поэтому вам нужно найти способ автоматически контролировать серверы и поднимать тревогу всякий раз, когда возникает проблема. К счастью, на большинстве UX-серверов уже есть необходимые инструменты для этого.

Создание инструмента мониторинга с помощью Perl

Первоначально Perl был разработан Ларри Уоллом как язык сценариев общего назначения для Unix, чтобы упростить составление отчетов. Perl стал чрезвычайно популярным из-за его сверхъестественной обработки текста и использования регулярных выражений. Поскольку он разработан для машин Unix, он уже доступен бесплатно во всех его версиях. Это делает Perl идеальным кандидатом для разработки инструмента мониторинга.

На сервере необходимо контролировать три основные области: память, ЦП и использование диска. Для мониторинга этих трех областей на серверах Unix уже были команды:

  • df -h : проверить использование диска
[chafid@server: /]# df -h /
Filesystem Size Used Avail Use% Mounted on
/dev/sda2  901G 362G  494G  43% /
[chafid@server: /]#
  • vmstat : проверить использование памяти
[chafid@server: /]# vmstat -s
      3748832  total memory
      2818068  used memory
      1407004  active memory
      1124204  inactive memory
       930764  free memory
       175192  buffer memory
      2003580  swap cache
     16777212  total swap
         1152  used swap
     16776060  free swap
       154784 non-nice user cpu ticks
            0 nice user cpu ticks
        37720 system cpu ticks
     11149049 idle cpu ticks
       247665 IO-wait cpu ticks
            0 IRQ cpu ticks
          973 softirq cpu ticks
            0 stolen cpu ticks
      2882279 pages paged in
     45954663 pages paged out
            8 pages swapped in
          289 pages swapped out
     39730371 interrupts
     71550672 CPU context switches
   1532918357 boot time
       235420 forks
[chafid@server: /]#
  • top : проверить загрузку ЦП
[chafid@diva: /]# top -b -n 1
top - 17:43:56 up  8:04,  5 users,  load average: 0.18, 0.13, 0.10
Tasks: 216 total,   1 running, 215 sleeping,   0 stopped,   0 zombie
Cpu(s):  1.3%us,  0.3%sy,  0.0%ni, 96.2%id,  2.1%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   3748832k total,  2819060k used,   929772k free,   175268k buffers
Swap: 16777212k total,     1152k used, 16776060k free,  2004032k cached

Вы можете добавить другие команды, которые вам кажутся подходящими, но эти три команды, по моему мнению, являются обязательными.

В Perl есть возможность запускать эти команды и сохранять результаты в переменных. Это было сделано либо с помощью команды «system», либо с помощью ` (обратная кавычка). Мы будем использовать использование памяти для примеров

my $mem_cmd = "/usr/bin/vmstat -s";
my $mem_result = `$mem_cmd`;

Чтобы вычислить процент использования памяти, нам нужны первые две строки. Perl-функция «split» может разделить строку на основе указанного разделителя и поместить разделенные строки в массив. В этом случае, поскольку мы хотим разделить строки, разделителем является новая строка («\n»).

my @mem_array = split ("\n", $mem_result);

После того, как строки сохранены в массив, нам нужно получить число, представляющее используемую и общую память. Например, эта строка

3748832  total memory

Чтобы извлечь число из приведенной выше строки, мы можем использовать регулярное выражение или регулярное выражение. Регулярное выражение для извлечения чисел из строки:

my ($mem_total) = $mem_array[0] =~ /(\d+)/

$mem_array[0] сохранил указанную выше строку в общей памяти. «\d+» означает, что будет получено только число, независимо от того, сколько в нем цифр, и сохранено число в переменной $mem_total.
Как только мы повторим этот шаг для используемой памяти, мы получим как используемую память, так и общую память сервера. Поскольку мы хотим получить процент используемой памяти, мы просто делаем простой расчет, как в примере:

my ($mem_usage) = $mem_array[1] =~ /(\d+)/;
my $mem_percentage = sprintf ( "%.2f", (($mem_usage / $mem_total) * 100));

По умолчанию числа в Perl целые. Поскольку нам нужно, чтобы процентное число было плавающим, мы использовали команду «sprintf». Эта команда, как и выше, отформатирует результат деления в числа с плавающей запятой с 2 ​​цифрами после запятой.

Если мы напечатаем содержимое $mem_percentage с помощью этой команды:

print "Memory percentage: $mem_percentage" . '%' . "\n";

Результат будет таким:

Memory percentage: 91.29%

Как только мы получили информацию, все, что нам нужно сделать, это установить лимит и заставить скрипт отправлять предупреждающее письмо по электронной почте после превышения лимита. В этом примере предел или порог установлен на 70.

my $mem_threshold = 70;
if ($mem_percentage > $mem_threshold) {
 $message = "Memory usage has reached $mem_percentage%\n";
 send_email($message);

Perl-функция «send_email», определяемая пользователем. Мы создали эту функцию, чтобы составить электронное письмо с сообщением об использовании памяти. Функция «send_email» выглядела так.

sub send_email {
 my ($message) = @_;
 print "message: $message\n";
 my $to_addr = '[email protected]';
 my $from_addr = '[email protected]';
 my $subject = "Server is overworked";
 my $smtp = Net::SMTP->new('smtp.mailserver.com') or die $!;
 $smtp->mail( $from_addr);
    $smtp->to( $to_addr );
    $smtp->data();
    $smtp->datasend("To: $to_addr\n");
    $smtp->datasend("From: $from_addr\n");
    $smtp->datasend("Subject: $subject\n");
    $smtp->datasend("\n"); # done with header
    $smtp->datasend($message);
    $smtp->dataend();
    $smtp->quit();
}

Функция отправки электронной почты использовала почтовый сервер SMTP для отправки предупреждения по электронной почте. Эта функция довольно проста. Определил адреса «Кому» и «От», тему и назначил их с содержимым сообщения объекту SMTP для отправки электронной почты. Вы можете изменить эти настройки в соответствии с вашим адресом электронной почты и настройками почтового сервера. Не забудьте добавить

use Net::SMTP

в объявлении в начале скрипта. Эта строка означает, что скрипт использует библиотеку SMTP, необходимую для функции send_email.

Как только порог будет превышен, скрипт отправит электронное письмо, подобное этому

Так вот! Вы можете изменить сценарий в соответствии с вашими потребностями, но основная концепция остается неизменной. Теперь все, что вам нужно сделать, это настроить задание cron для запуска скрипта в желаемый интервал времени.

Я надеюсь, что вы все найдете это полезным.