Скрипт за мониторинг на интернет връзка

Скрипт за мониторинг на интернет връзка

Мониторингът на интернет връзка е от съществено значение за потребителите и организациите, които зависят от непрекъснатото наличие на интернет. Стабилната връзка е основен фактор за производителността и ефективността на дейностите, извършвани в днешно време.

В тази статия ще разгледаме как да създадем Python скрипт, който автоматично проверява връзката и записва резултатите в лог файл.

Мониторинг на интернет връзка с Python скрипт

Използването на Python за автоматизиране на мониторинга на интернет връзка е мощен инструмент, който позволява на потребителите да следят непрекъснато наличието и качеството на тяхната мрежова връзка. В тази статия ще разгледаме как да създадем Python скрипт, който автоматично проверява връзката и записва резултатите в лог файл. Скриптът ще включва функции за начална проверка на връзката, автоматично възстановяване на връзката при проблеми и логика за спиране след определено време или брой проверки.

Python скриптът, който ще разгледаме, използва ping заявки към известен DNS сървър (например, 8.8.8.8 на Google) за да провери наличието на интернет връзка. Резултатите от тези проверки се записват в лог файл, което позволява на потребителя да проследява състоянието на връзката във времето.

Стъпка 1: Инсталиране на необходимите библиотеки

Първата стъпка е да инсталираме необходимите Python библиотеки. В този случай, ще се нуждаем от logging библиотеката, която ще ни помогне да записваме съобщенията в лог файла.

Можем да инсталираме logging библиотеката чрез pip, стандартния инструмент за управление на пакети в Python:

pip install logging

Стъпка 2: Създаване на Python скрипт за мониторинг

След като инсталираме необходимите библиотеки, можем да започнем създаването на Python скрипт за мониторинг на интернет връзка. В нашия скрипт ще използваме модулите subprocess, datetime и time за да извършваме ping проверки към определен IP адрес и да записваме резултатите в лог файл.



# Author     : Fedya Serafiev
# Version    : 1.3
# License    : MIT
# Copyright  : Fedya Serafiev (2024)
# Contact    : https://urocibg.eu/
import os
import sys
import subprocess
import datetime
import time
import signal
from logging.handlers import RotatingFileHandler
import logging

FILE = os.path.join(os.getcwd(), "networkinfo.log")
last_network_status = "неизвестен"

# Конфигурация на логгера с ротация на лог файловете
logger = logging.getLogger("NetworkMonitor")
logger.setLevel(logging.INFO)
handler = RotatingFileHandler(FILE, maxBytes=5000000, backupCount=5)
formatter = logging.Formatter('%(asctime)s - %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)

# Конфигурация за автоматично спиране
max_runtime_seconds = 3600  # Спиране след 1 час (3600 секунди)
max_checks = 1000  # Спиране след 1000 проверки

def ping():
    print("Проверка на връзката...")
    try:
        if os.name == 'nt':
            output = subprocess.check_output(
                ["ping", "-n", "4", "8.8.8.8"], stderr=subprocess.STDOUT, universal_newlines=True
            )
        else:
            output = subprocess.check_output(
                ["ping", "-c", "4", "8.8.8.8"], stderr=subprocess.STDOUT, universal_newlines=True
            )
        print("Резултат от ping:\n", output)
        if "0% packet loss" in output or "0% loss" in output:
            return True, output
        else:
            return False, output
    except subprocess.CalledProcessError as e:
        print("Грешка при изпълнение на ping:", e.output)
        return False, e.output

def calculate_time(start, stop):
    difference = stop - start
    seconds = difference.total_seconds()
    return str(datetime.timedelta(seconds=seconds)).split(".")[0]

def first_check():
    global last_network_status
    success, output = ping()
    if success:
        live = "КОНЕКЦИЯТА Е УСПЕШНА"
        connection_acquired_time = datetime.datetime.now()
        acquiring_message = "свързване към интернет: " + str(connection_acquired_time).split(".")[0]
        print(live)
        print(acquiring_message)
        logger.info(live)
        logger.info(acquiring_message)
        logger.info(output)
        last_network_status = "връзката е стабилна"
        return True
    else:
        not_live = "НЯМА ВРЪЗКА С ИНТЕРНЕТ"
        print(not_live)
        logger.info(not_live)
        logger.info(output)
        last_network_status = "имаше проблеми с връзката"
        return False

def handle_exit(signum, frame):
    stop_time = datetime.datetime.now()
    stop_message = "Скриптът беше принудително затворен в: " + str(stop_time).split(".")[0]
    network_status_message = "Състоянието на мрежата при затварянето: " + last_network_status
    print("\n" + stop_message)
    print(network_status_message)
    logger.info(stop_message)
    logger.info(network_status_message)
    sys.exit()

def main():
    signal.signal(signal.SIGTERM, handle_exit)
    signal.signal(signal.SIGINT, handle_exit)

    monitor_start_time = datetime.datetime.now()
    monitoring_date_time = "мониторингът започна в: " + str(monitor_start_time).split(".")[0]
    print(monitoring_date_time)
    logger.info(monitoring_date_time)

    if first_check():
        print(monitoring_date_time)
    else:
        while True:
            success, output = ping()
            if not success:
                time.sleep(1)
            else:
                first_check()
                print(monitoring_date_time)
                break

    check_count = 0
    try:
        while True:
            if max_runtime_seconds and (datetime.datetime.now() - monitor_start_time).total_seconds() > max_runtime_seconds:
                print(f"Скриптът автоматично спря след {max_runtime_seconds} секунди.")
                logger.info(f"Скриптът автоматично спря след {max_runtime_seconds} секунди.")
                handle_exit(None, None)
                
            if max_checks and check_count >= max_checks:
                print(f"Скриптът автоматично спря след {max_checks} проверки.")
                logger.info(f"Скриптът автоматично спря след {max_checks} проверки.")
                handle_exit(None, None)
            
            success, output = ping()
            check_count += 1
            if success:
                last_network_status = "връзката е стабилна"
                time.sleep(2)
            else:
                last_network_status = "имаше проблеми с връзката"
                down_time = datetime.datetime.now()
                fail_msg = "изключено от интернет в: " + str(down_time).split(".")[0]
                print(fail_msg)
                logger.info(fail_msg)
                logger.info(output)

                while not ping()[0]:
                    time.sleep(1)

                up_time = datetime.datetime.now()
                uptime_message = "връзката с интернет беше възстановена в: " + str(up_time).split(".")[0]

                down_time_duration = calculate_time(down_time, up_time)
                unavailability_time = "връзката с интернет беше недостъпна за: " + down_time_duration

                print(uptime_message)
                print(unavailability_time)
                logger.info(uptime_message)
                logger.info(unavailability_time)
    except KeyboardInterrupt:
        handle_exit(None, None)

if __name__ == "__main__":
    main()

Малко обяснение:

  1. Използване на глобална променлива last_network_status за проследяване на текущото състояние на мрежата.
  2. Добавяне на функция handle_exit, която обработва сигналите за принудително спиране (SIGTERM и SIGINT) и записва текущото състояние на мрежата в лог файла.
  3. Регистриране на обработчика на сигнали с помощта на signal.signal.
  4. Принтиране на съобщения при стартиране на проверка на връзката.
  5. Принтиране на резултата от командата ping.
  6. Принтиране на съобщения за успешна връзка и липса на връзка.
  7. Добавяне на диагностични съобщения при спиране на скрипта.

Скриптът ще записва текущото състояние на мрежата при всяко принудително спиране или спиране с Ctrl+C (SIGINT).

  1. Конфигурация за автоматично спиране:
    • max_runtime_seconds задава максималното време за изпълнение на скрипта (в секунди). В примера е настроено на 3600 секунди (1 час).
    • max_checks задава максималния брой проверки, след които скриптът автоматично ще спре. В примера е настроено на 1000 проверки.
  2. Логика за спиране:
    • В главния цикъл са добавени условия за проверка на текущото време и броя на проверките. Ако някое от условията е изпълнено, скриптът автоматично спира и извиква функцията handle_exit.

Скриптът ще спре автоматично след определен период от време или след определен брой проверки.

Федя Серафиев

Федя Серафиев

Федя Серафиев e собственик на уебсайта urocibg.eu. Той намира удовлетворение в това да помага на хората да решават и най-сложните технически проблеми. Сегашната му цел е да пише лесни за следване статии, така че подобни проблеми изобщо да не възникват.

Благодарим ви за прочитането на статията! Ако намерихте информацията за полезна, можете да дарите посредством бутоните по-долу: