Python

Python Script to Monitor Network Connection

The need to have our devices always connected to the internet is becoming more of a basic need than an added privilege.

Having applications and devices that need to log, send, and receive data to the outside world is critical. Thus, having a tool that allows you to monitor when your network goes down can help you troubleshoot the network or stop the applications before sending a bunch of log errors.

In today’s tutorial, we will build a simple network monitor that continually monitors your internet connectivity by sending ping requests to an external resource. The script we shall create shall also keep logs of when the internet is down and the duration of the downtime:

Project Requirements

For this project, we are only going to need:

  • Python Programming Basics
  • Basic understanding of computer networks.
  • Be Comfortable using the terminal.

Project Logic

Before we dive into the coding part, let’s discuss and understand what we are trying to achieve:

What is Network Up and Downtime?

When we talk about network up and downtime, we mean the period where the network connection is entirely unavailable, and thus, we cannot communicate with devices outside our network. The longer the internet is unavailable, the longer the downtime.

How to Determine Downtime

Now that we know what internet downtime is, you may be wondering, “how do we go about determining it?”

Without complicating our code, we can go with ping. A ping is a method where we continuously ping a reliable server—perhaps Cloudflare or Google DNS—and then wait for a response.

If we ping the server and there’s no response, we note that specific time and continue to ping until we receive a ping and note the time.

Having the time difference, we can note when the internet was down and for how long.

We also have to be careful when pinging a single server because we can have the ping falsely mistaken as a DDoS attack, which might cause our IP address to get blocked, which would produce negative results.

Here’s a flow chart explaining this concept:

Talk is cheap; let’s now dive into the code showing how to implement this logic:

Now Show Me The Code

As usual, in Python, we start by importing the required libraries. Next, we create a log file in the current working directory.

We use the socket library to send a request to an external IP address in the first function. For this example, we use Cloudflare public DNS address, which has a very high uptime. We also pass the port, and since it’s a DNS server, use port 53.

We then verify that we have access to the log file directory and quit if we do not have access.

The next step is to calculate the time the network connection is down. Finally, we wrap the entire functionality in a loop, as shown in the code below.

    import socket
    import time
    import datetime
    import os
    import sys
     
    LOG_FNAME = "network.log"
    FILE = os.path.join(os.getcwd(), LOG_FNAME)
    def send_ping_request(host="1.1.1.1", port=53, timeout=3):
        try:
            socket.setdefaulttimeout(timeout)
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((host,port))
        except OSError as error:
            return False
        else:
            s.close()
            return True
    def write_permission_check():
        try:
            with open(FILE, "a") as file:
                pass
        except OSError as error:
            print("Log file creation failed")
            sys.exit()
        finally:
            pass
    def calculate_time(start, stop):
        time_difference = stop - start
        seconds = float(str(time_difference.total_seconds()))
        return str(datetime.timedelta(seconds=seconds)).split(".")[0]
    def mon_net_connection(ping_freq=2):
        monitor_start_time = datetime.datetime.now()
        motd = "Network connection monitoring started at: " + str(monitor_start_time).split(".")[0] + " Sending ping request in " + str(ping_freq) + " seconds"
        print(motd)
     
        with open(FILE, "a") as file:
            file.write("\n")
            file.write(motd + "\n")
        while True:
            if send_ping_request():
                time.sleep(ping_freq)
            else:
                down_time = datetime.datetime.now()
                fail_msg = "Network Connection Unavailable at: " + str(down_time).split(".")[0]
                print(fail_msg)
                with open(FILE, "a") as file:
                    file.write(fail_msg + "\n")
                    i = 0
                while not send_ping_request():
                    time.sleep(1)
                    i += 1
                    if i >= 3600:
                        i = 0
                        now = datetime.datetime.now()
                        continous_message = "Network Unavailabilty Persistent at: " + str(now).split(".")[0]
                        print(continous_message)
                        with open(FILE, "a") as file:
                            file.write(continous_message + "\n")
                up_time = datetime.datetime.now()
                uptime_message = "Network Connectivity Restored at: " + str(up_time).split(".")[0]
     
                down_time = calculate_time(down_time, up_time)
                _m = "Network Connection was Unavailable for " + down_time
     
                print(uptime_message)
                print(_m)
     
                with open(FILE, "a") as file:
                    file.write(uptime_message + "\n")
                    file.write(_m + "\n")
    mon_net_connection()

If you run this script, you will get an output similar to the one shown below:

Conclusion

Using the above script, we can monitor when the network connection is lost and constantly log it until it is available. This simple script is open to improvements. Feel free to adjust the code to fit your needs and expand on it.

About the author

John Otieno

John Otieno

My name is John and am a fellow geek like you. I am passionate about all things computers from Hardware, Operating systems to Programming. My dream is to share my knowledge with the world and help out fellow geeks. Follow my content by subscribing to LinuxHint mailing list