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 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.