- Saved searches
- Use saved searches to filter your results more quickly
- License
- jamesoff/simplemonitor
- Name already in use
- Sign In Required
- Launching GitHub Desktop
- Launching GitHub Desktop
- Launching Xcode
- Launching Visual Studio Code
- Latest commit
- Git stats
- Files
- README.md
- About
- Topics
- Resources
- License
- Code of conduct
- Stars
- Watchers
- Forks
- Releases 9
- Sponsor this project
- Contributors 41
- Languages
- Footer
- Python Script to Monitor Network Connection
- Project Requirements
- Project Logic
- What is Network Up and Downtime?
- How to Determine Downtime
- Now Show Me The Code
- Conclusion
- About the author
- John Otieno
- Network usage monitor using Python
- Goal
- Requirements.txt
- Coding Python
- Get network usage
- Set threshold
- Separate the config and code
- Prepare for the Email
- Generate SendGrid API Key
- Copy the Key and paste to monitor.conf
- Write python script
- Improvement
Saved searches
Use saved searches to filter your results more quickly
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session. You switched accounts on another tab or window. Reload to refresh your session.
A Python-based network and host monitor
License
jamesoff/simplemonitor
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
Sign In Required
Please sign in to use Codespaces.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching GitHub Desktop
If nothing happens, download GitHub Desktop and try again.
Launching Xcode
If nothing happens, download Xcode and try again.
Launching Visual Studio Code
Your codespace will open once ready.
There was a problem preparing your codespace, please try again.
Latest commit
Git stats
Files
Failed to load latest commit information.
README.md
SimpleMonitor is a Python script which monitors hosts and network connectivity. It is designed to be quick and easy to set up and lacks complex features that can make things like Nagios, OpenNMS and Zenoss overkill for a small business or home network. Remote monitor instances can send their results back to a central location.
About
A Python-based network and host monitor
Topics
Resources
License
Code of conduct
Stars
Watchers
Forks
Releases 9
Sponsor this project
Contributors 41
Languages
Footer
You can’t perform that action at this time.
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
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
Network usage monitor using Python
We have built a 4G/LTE router but how do I know its network usage? How much will it cost me?
Goal
We are now going to write a Python script to send Email notificatoin for network usage and set a threshold for it.
I assume you know the basic pattern how to code in Python
Requirements.txt
psutil
python_http_client
sendgrid
You can install them by typing in terminal:
$ pip3 install psutil python_http_client sendgrid
You may need to specify pip3 in Raspbian as both Python 2.x and Python 3.x were installed.
Coding Python
$ mkdir network-monitor
$ cd network-monitor
$ nano monitor.py
Get network usage
import psutil
NETWORK_INTERFACE = ‘ppp0’
netio = psutil.net_io_counters(pernic=True)
net_usage = netio[NETWORK_INTERFACE].bytes_sent + netio[NETWORK_INTERFACE].bytes_recv
print(net_usage, «bytes»)
It will show you how many bytes it has transfered for upload and download.
If it shows zero, change NETWORK_INTERFACE to wwan0 .
Set threshold
import psutil
NETWORK_INTERFACE = ‘wwan0’
NETWORK_LIMIT = 5000000 # 5GB in SI standard
while True:
netio = psutil.net_io_counters(pernic=True)
net_usage = netio[NETWORK_INTERFACE].bytes_sent + netio[NETWORK_INTERFACE].bytes_recv
if net_usage > NETWORK_LIMIT:
print(«Meets network limit!»)
print(net_usage, «bytes has been used»)
Once it over the NETWORK_LIMIT it will print a lot of lines of “Meets network limit!”. We can add a timer to check the network limit every X second.
Separate the config and code
Try to separate the cnofiguratoin and the Python script so we can reuse this project on other devices.
configparser is really a good helper on this.
Create a file monitor.conf
[Email]
SENDGRID_API_KEY = Your.Keyfrom_SendGrid
from = helper@raspberry.pi
to = your@email.address
subject = From your Raspberry Pi
[Network]
INTERFACE = wwan0
LIMIT = 45000000000
[Misc]
TIME_INTER = 36
Now we can load the configuration in Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import time
import psutil
import configparser
config = configparser.ConfigParser()
config.optionxform = str #reference: http://docs.python.org/library/configparser.html
config.read(‘monitor.conf’)
NETWORK_INTERFACE = config.get(‘Network’, ‘INTERFACE’) # Define interface to check
NETWORK_LIMIT = int(config.get(‘Network’, ‘LIMIT’)) # Define network limit
SENDGRID_API_KEY = config.get(‘Email’, ‘SENDGRID_API_KEY’) # Define the API key for SendGrid
TIME_INTER = config.get(‘Misc’, ‘TIME_INTER’) # Define time interval 36 seconds
while True:
time.sleep(TIME_INTER) # Check every 36 seconds
netio = psutil.net_io_counters(pernic=True)
net_usage = netio[NETWORK_INTERFACE].bytes_sent + netio[NETWORK_INTERFACE].bytes_recv
if net_usage > NETWORK_LIMIT:
print(«Meets network limit!»)
print(net_usage, «bytes has been used»)
Prepare for the Email
We use SendGrid to send the Email notification in this tutorial.
You may need to sign up on SendGrid. I choose it because of 100 free email quota every day.
Generate SendGrid API Key
The option is in Setting -> API Keys -> Create API Key Creating an API key
Copy the Key and paste to monitor.conf
[Email]
SENDGRID_API_KEY = Your.Keyfrom_SendGrid
Write python script
Refer to their official guide SendGrid GitHub repo
import time
import psutil
import sendgrid
from sendgrid.helpers.mail import *
import configparser
config = configparser.ConfigParser()
config.optionxform = str #reference: http://docs.python.org/library/configparser.html
config.read(‘netio-mon.conf’)
NETWORK_INTERFACE = config.get(‘Network’, ‘INTERFACE’)
NETWORK_LIMIT = int(config.get(‘Network’, ‘LIMIT’))
NETWORK_MAX = int(config.get(‘Network’, ‘MAX’))
SENDGRID_API_KEY = config.get(‘Email’, ‘SENDGRID_API_KEY’)
TIME_INTER = config.get(‘Misc’, ‘TIME_INTER’)
I would like to have some loggings too so I added this line
import logging
loggingFile = logging.FileHandler(‘my.log’, ‘w’, ‘utf-8’)
logging.basicConfig(level=logging.DEBUG,
format=‘%(asctime)s %(levelname)s %(message)s’,
datefmt=‘%Y-%m-%d %H:%M’,
handlers=[loggingFile, ])
Declare two methods for sending Email
def create_message(sender, to, subject, message_text):
logging.info(«send email::» + message_text)
from_email = Email(sender)
to_email = To(to)
subject = subject
content = Content(«text/plain», message_text)
return Mail(from_email, to_email, subject, content)
def send_message(service, message):
return service.client.mail.send.post(request_body=message.get())
Now the mean loop to check the network usage periodically.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# Initialize the SendGrid API
service = sendgrid.SendGridAPIClient(api_key=SENDGRID_API_KEY)
# A flag to make sure only send one notification
have_sent = False
while True:
time.sleep(TIME_INTER)
netio = psutil.net_io_counters(pernic=True)
net_usage = netio[NETWORK_INTERFACE].bytes_sent + netio[NETWORK_INTERFACE].bytes_recv
if net_usage > NETWORK_LIMIT and not have_sent:
message = create_message(
config.get(‘Email’, ‘from’),
config.get(‘Email’, ‘to’),
config.get(‘Email’, ‘subject’),
‘The network have used %s bytes’ %net_usage)
send_message(service, message)
have_sent = True
Improvement
- Prevent network usage lost, save the usage in the last email with pickle
- In order to monitoring network usage continuously, set one more NETWORK_MAX for reseting the flag after first email notification
See my GitHub Repo