Как сделать программу мониторинга

Содержание

Решил написать не сложную утили для мониторинга сети в фоновом режиме отслеживающую главные показатели и сохраняя их в логи. Все это будет работать под виндой, по этому будем изучать новый язык C#. По чему Си шарп, по тому что так проще для новичка. То есть меня )))

Задачи.

  • Пинга до заданого хоста.
  • Возможность подключиться по TCP.
  • Доступность роутера и т.п.

Так как программа будет работать в фоновом режиме, оформим ее как системный сервис (для упрощения и отладки сделал пока консольный вариант). Проверка не должна загружать канал, так что не будем флудить пингом и т.д. Будем отправлять несколько запросов раз в две — три минуты. Сохранять логи, загружать настройки будем в каком нибудь удобном формате: JSON и CSV.

Подготовка.

Я скачал Visual Studio с сайта Микрософт. Добавляем подержу .NET и C# при установке . Ну и создаем проект консольной программы для Windos на C#. Запускаем, вроде все работает.

  • Настраиваем MSI Afterburner — Мониторинг, фпс, frametime, железо в оверлее

    Для нашей программы нам потребуются настройки (IP хоста, порт, задержка и т.д.).Сделаем файл настроек из которого будем загружать данные. Составим список настроек, определимся с форматом переменных для этих значение:

    • Хост и порт для которого мы будет проверять доступность HTTP. Так же зададим и ТАЙМ-АУТ для подключения.
    • Количество пакетов Ping и их тайм-аут. Задержка между отправлениями пакетов.
    • Хост который будем пинговать.
    • IP адрес роутера. Если роутер не доступен то зачем вообще делать все остальное )
    • Максимальный уровень packet loss, при котором подключение считается нормальным.
    • Выходной файл CSV, в который будут дописываться результаты.
    • Изюминка: выходной формат строки для CSV, если ты вдруг решишь отключить вывод ненужных столбцов или изменить порядок.
    • Возможность отключить логирование.
    Читайте также:
    Как написать программу для Майнкрафта

    Сделаем все современненько, файл настроек будет в формате JSON — setting.json .

    JSON (англ. JavaScript Object Notation) — текстовый формат обмена данными, основанный на JavaScript. Как и многие другие текстовые форматы, JSON легко читается людьми. Формат JSON был разработан Дугласом Крокфордом.

    JSON-текст представляет собой (в закодированном виде) одну из двух структур:
    Набор пар ключ: значение. В различных языках это реализовано как запись, структура, словарь, хеш-таблица, список с ключом или ассоциативный массив. Ключом может быть только строка (регистрозависимая: имена с буквами в разных регистрах считаются разными), значением — любая форма.
    Упорядоченный набор значений. Во многих языках это реализовано как массив, вектор, список или последовательность.

    < «http_test_host»: «api.ipify.org», «http_test_port»: «80», «http_timeout»: «3000», «ping_count»: «10», «ping_timeout»: «3000», «ping_packet_delay»: «0», «ping_hosts»: [ «ya.ru», «1.1.1.1» ], «measure_delay»: «60000», «cui_output»: «true», «router_ip»: «192.168.0.1», «nq_max_loss»: «0,1», «out_file»: «log.csv», «w_csv»: «true», «out_format»: «FTIME;STIME;IUP;HTTP;AVGRTT;ROUTERRTT;LOSS;RN» >// RN — маркер конца строки

    Кодинг.

    Первым делом объявим переменные для настроек :

    static String HTTP_TEST_HOST; // HTTP сервер, соединение до которого будем тестировать static int HTTP_TEST_PORT; // Порт HTTP сервера static int HTTP_TIMEOUT; // Таймаут подключения static int PING_COUNT; // Количество пакетов пинга static int PING_DELAY; // Ожидание перед отправкой следующего пакета пинга static int PING_TIMEOUT; // Таймаут пинга static List PING_HOSTS; // Хосты, пинг до которых меряем static int MEASURE_DELAY; // Время между проверками static String ROUTER_IP; // IP роутера static double MAX_PKT_LOSS; // Максимально допустимый Packet loss static String OUT_FILE; // Выходной файл CSV static bool WRITE_CSV; // Писать ли CSV static String CSV_PATTERN; // Шаблон для записи в CSV // Промежуточные переменные static bool prev_inet_ok = true; static DateTime first_fail_time; static long total_time = 0; static int pkt_sent = 0; static int success_pkts = 0; static int exited_threads = 0; static Dictionary measure_results = new Dictionary();

    Теперь нам надо загрузить настройки в переменные. Для работы с форматом JSON будем использовать библиотеку Json.NET .

    Json.NET — популярная и простая библиотека для работы с JSON.

    https://www.nuget.org/packages/Newtonsoft.Json/

    Теперь загружаем данные из файла :

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System.Threading; using System.Net.Sockets; using System.Net.NetworkInformation; var config = JsonConvert.DeserializeObject>(File.ReadAllText(«setting.json»)); HTTP_TEST_HOST = (String)config[«http_test_host»]; PING_HOSTS = ((JArray)config[«ping_hosts»]).ToObject>(); ROUTER_IP = (String)config[«router_ip»]; HTTP_TEST_PORT = int.Parse((String)config[«http_test_port»]); HTTP_TIMEOUT = int.Parse((String)config[«http_timeout»]); PING_COUNT = int.Parse((String)config[«ping_count»]); PING_TIMEOUT = int.Parse((String)config[«ping_timeout»]); PING_DELAY = int.Parse((String)config[«ping_packet_delay»]); MEASURE_DELAY = int.Parse((String)config[«measure_delay»]); OUT_FILE = (String)config[«out_file»]; WRITE_CSV = bool.Parse((String)config[«w_csv»]); CSV_PATTERN = (String)config[«out_format»]; MAX_PKT_LOSS = double.Parse((String)config[«nq_max_loss»]); Console.WriteLine(«Load config complit. «);

    Теперь мы создадим понятные заголовки для файла CSV и запишем их в файл.

    Читайте также:
    Как взломать человека без программ

    String CSV_HEADER = CSV_PATTERN .Replace(«FTIME», «Data») .Replace(«IUP», «Internet up») .Replace(«AVGRTT», «Average ping (ms)») .Replace(«ROUTERRTT», «Ping to router (ms)») .Replace(«LOSS», «Packet loss, %») .Replace(«HTTP», «HTTP OK») .Replace(«STIME», «Time»); foreach (var host in PING_HOSTS) < CSV_HEADER = CSV_HEADER.Replace(«RN», $»Ping to ;RN»); > CSV_HEADER = CSV_HEADER.Replace(«RN», «rn»); if (WRITE_CSV) // Если запись включена в настройках создать файл и записать заголовки. < // Если файла нету , создать и записать заголовки. if (!File.Exists(OUT_FILE)) File.WriteAllText(OUT_FILE, CSV_HEADER); >

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

    struct net_state < public bool inet_ok; // Флаг доступности сети public bool http_ok; // Флаг теста http public Dictionaryavg_rtts; // Словарь пинга до хостов public double packet_loss; // Потеря пакетов public DateTime measure_time; // Дата, время public int router_rtt; // >

    Давайте теперь напишем функцию записи данных в лог файл:

    static void Save_log(net_state snapshot) < if (WRITE_CSV) // Если запись логов включена < String rtts = «»; int avg_rtt = 0; foreach (var ci in PING_HOSTS) < rtts += $»;»; avg_rtt += snapshot.avg_rtts[ci]; > avg_rtt = avg_rtt / PING_HOSTS.Count; File.AppendAllText(OUT_FILE, CSV_PATTERN .Replace(«FTIME», snapshot.measure_time.ToShortDateString()) .Replace(«IUP», snapshot.inet_ok.ToString()) .Replace(«AVGRTT», avg_rtt.ToString()) .Replace(«ROUTERRTT», snapshot.router_rtt.ToString()) .Replace(«LOSS», snapshot.packet_loss.ToString()) .Replace(«HTTP», snapshot.http_ok.ToString()) .Replace(«STIME», snapshot.measure_time.ToShortTimeString()) .Replace(«RN», $»rn»)); > >

    Теперь пишем основную часть кода, сам мониторинг в отдельной функции. Проверяем доступность роутера,если не доступен то записываем лог и выходим. Потом проверяем HTTP соединение, затем пингуем заданные хосты.

    static void Monit() < // Создаем экземпляр измерений. net_state snapshot = new net_state(); snapshot.inet_ok = true; snapshot.measure_time = DateTime.Now; // Проверяем доступность роутера Ping ping = new Ping(); var prr = ping.Send(ROUTER_IP, PING_TIMEOUT); // В CSV файле все поля должны быть заполнены. Если роутер не пингуется заполняем их параметром PING_TIMEOUT snapshot.router_rtt = prr.Status == IPStatus.Success ? (int)prr.RoundtripTime : PING_TIMEOUT; if (prr.Status != IPStatus.Success) < snapshot.avg_rtts = new Dictionary(); snapshot.http_ok = false; snapshot.inet_ok = false; snapshot.packet_loss = 1; foreach (var ci in PING_HOSTS) < snapshot.avg_rtts.Add(ci, PING_TIMEOUT); >Console.WriteLine(«Router was unreachable.»); Save_log(snapshot); return; > snapshot.inet_ok = true; // Проверяем доступность HTTP try < snapshot.http_ok = true; TcpClient tc = new TcpClient(); tc.BeginConnect(HTTP_TEST_HOST, HTTP_TEST_PORT, null, null); Thread.Sleep(HTTP_TIMEOUT); // Если подключиться не удалось if (!tc.Connected) < snapshot.http_ok = false; >tc.Dispose(); > catch < snapshot.http_ok = false; snapshot.inet_ok = false; >//Теперь пингуем заданные хосты exited_threads = 0; pkt_sent = 0; success_pkts = 0; total_time = 0; measure_results = new Dictionary(); // Перебираем все хосты и запускаем пинг в отдельном потоке. foreach (var ci in PING_HOSTS) < Thread thread = new Thread(new ParameterizedThreadStart(PingTest)); thread.Start(ci); >while (exited_threads < PING_HOSTS.Count) continue; //Анализируем результаты пинга snapshot.avg_rtts = measure_results; snapshot.packet_loss = (double)(pkt_sent — success_pkts) / pkt_sent; snapshot.inet_ok = !( snapshot.http_ok == false || ((double)total_time / success_pkts >= 0.75 * PING_TIMEOUT) || snapshot.packet_loss >= MAX_PKT_LOSS || snapshot.router_rtt == PING_TIMEOUT); Save_log(snapshot); if (prev_inet_ok !snapshot.inet_ok) < //Интернет был , но теперь неудачу prev_inet_ok = false; first_fail_time = DateTime.Now; >else if (!prev_inet_ok snapshot.inet_ok)

    Читайте также:
    Информатика для самых маленьких рабочая программа

    Так как хостов для пинга у нас может быть сколько угодно и количество пингов тоже. Выделим процес самого пинга в отдельную функцию PingTest()

    static void PingTest(Object arg) < String host = (String)arg; int pkts_lost_row = 0; int local_success = 0; long local_time = 0; Ping ping = new Ping(); // Запускаем пинг заданное количество раз. for (int i = 0; i < PING_COUNT; i++) < // Если потеряно 3 пакеты, записываем результаты и выходим из цикла if (pkts_lost_row == 3) < measure_results.Add(host, (int)(local_time / (local_success == 0 ? 1 : local_success))); exited_threads++; return; >try < var result = ping.Send(host, PING_TIMEOUT); // Если пинг прошел if (result.Status == IPStatus.Success) < pkts_lost_row = 0; local_success++; // RoundtripTime Возвращает количество миллисекунд, затраченных на отправку Эхо-запроса local_time += result.RoundtripTime; total_time += result.RoundtripTime; pkt_sent++; success_pkts++; >switch (result.Status) < case IPStatus.Success: break; //Already handled case IPStatus.BadDestination: measure_results.Add(host, -1); exited_threads++; return; case IPStatus.DestinationHostUnreachable: case IPStatus.DestinationNetworkUnreachable: case IPStatus.DestinationUnreachable: measure_results.Add(host, -1); exited_threads++; return; case IPStatus.TimedOut: pkts_lost_row++; pkt_sent++; break; default: measure_results.Add(host, -1); exited_threads++; return; >> catch (Exception xc) < exited_threads++; measure_results.Add(host, -1); return; >> measure_results.Add(host, (int)(local_time / (local_success == 0 ? 1 : local_success))); exited_threads++; return; >

    Теперь осталось зациклить вызов Monit() и поставить задержу между тестами.

    while (true)

    Вот такой отчет получился у меня.

  • Думаю тут будет совсем не сложно добавить любой функционал который вам нужен. Например отправку сообщение о сбое в Телеграм.

    Скачать код целиком можно с нашего сайте.

    В статье использовался материал журнала Хакер( https://xakep.ru).

    Ошибка в тексте? Выделите её и нажмите «Ctrl + Enter»

    C#. Создание приложения для отслеживания счетов. Часть 1

    От автора: программирование — очень полезный навык не только в высоких технологиях. В этом уроке Вы увидите, как создать основу для небольшого приложения по отслеживанию счетов. Чтобы сохранять приложение как можно более простым — будем использовать ASP .NET Razor Pages.

    По итогам урока Вы узнаете: как создавать шаблоны страниц с кодогенератором .NET Core; как управлять маршрутизацией; как автоматизировать некоторые операции с помощью командной оболочки Powershell.

    Профессия PHP-разработчик с нуля до PRO

    Готовим PHP-разработчиков с нуля

    Вы с нуля научитесь программировать сайты и веб-приложения на PHP, освоите фреймворк Laravel, напишете облачное хранилище и поработаете над интернет-магазином в команде. Сможете устроиться на позицию Junior-разработчика.

    Источник: webformyself.com

    Рейтинг
    ( Пока оценок нет )
    Загрузка ...
    EFT-Soft.ru