0

I have a strange issue with my python monitoring script:- I've written a script with a number of alerts for any server. In that I have a function that gathers Network bytes/sec in and out. Now the issue is when I print the alert outside my mail function it prints the current output, but for some reason when it triggers the mail for the alert, the mail body is empty. If I trigger the mail with another alert which isn't in the Network function it works properly. Also is there a way to get smtplib to use port 587 instead of 465, any pointers on formatting the alert would be appreciated too. Please find my script below:-

#!/usr/bin/env python3
#Module psutil needs to be installed via pip3 first.
#Python script to Monitor Server Resources.

import time
import psutil
import smtplib
from email.message import EmailMessage

project_and_instance_name = 'test-stage' #Edit the name of the project name and environment
sender = '<sender email>' #Email Address of the sender
receivers = ['recepient email'] #comma seperated list of recipients enclosed in ''

cpu_thresh = 50.0
cpu_pct = psutil.cpu_percent(interval=1)

if cpu_pct >= cpu_thresh:
    cpu_alert = "CPU Warning, CPU at ",cpu_pct, "percent"
else:
    cpu_alert = ""

mem = psutil.virtual_memory()
mem_thresh = 1024 * 1024 * 1024 #change the end value to choose the amount of MB

if mem_thresh >= mem.available:
    mem_alert = "Memory Usage Warning only", round((mem.available /1024 /1024), 2), "MB available"
else:
    mem_alert = ""
partition1 = '/'
disk1 = psutil.disk_usage(partition1)
disk_thresh = 85.0

if disk_thresh <= disk1[3]:
    disk_alert = f"Root volume usage warning {disk1[3]} % used"
else:
    disk_alert = ""

def net_usage(inf = "eth0"):   #change the inf variable according to the interface
  global net_in_alert
  global net_out_alert
  net_in_ps1 = psutil.net_io_counters(pernic=True, nowrap=True)[inf]
  net_in_1 = net_in_ps1.bytes_recv
  net_out_1 = net_in_ps1.bytes_sent
  time.sleep(1)
  net_in_ps2 = psutil.net_io_counters(pernic=True, nowrap=True)[inf]
  net_in_2 = net_in_ps2.bytes_recv
  net_out_2 = net_in_ps2.bytes_sent
  net_in_res = round((net_in_2 - net_in_1) /1024 /1024, 2)
  net_out_res = round((net_out_2 - net_out_1) /1024 /1024, 2)
  net_in_thresh = 1.5
  net_out_thresh = 1.5
  if net_in_res >= net_in_thresh:
      net_in_alert = f"Current net-usage:IN: {net_in_res} MB/s"
  else:
      net_in_alert = ""
  if net_out_res <= net_out_thresh:
     net_out_alert = f"Current net-usage:OUT: {net_out_res} MB/s"
  else:
      net_out_alert = ""
net_usage()

message_list = []

if cpu_alert == "" :
    pass
else:
    message_list.append(cpu_alert)
if mem_alert == "" :
    pass
else:
    message_list.append(mem_alert)
if disk_alert == "" :
    pass
else:
    message_list.append(disk_alert)
if net_in_alert == "" :
    pass
else:
    message_list.append(net_in_alert)
if net_out_alert == "" :
    pass
else:
    message_list.append(net_out_alert)

msg = '\n'.join(message_list)
print(msg)

def alerts():
  server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
  server.login(sender, "<password>")
  server.sendmail(sender,receivers,msg)

if msg == "":
  pass
else:
  alerts()
Firdaus Aga
  • 27
  • 2
  • 6

2 Answers2

0

Got the answer by changing the SMTP format for any who are stuck here's the code:-

#!/usr/bin/env python3
#Module psutil needs to be installed via pip3 first.
#Python script to Monitor Server Resources.

import time
import psutil
import smtplib, ssl
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText

project_and_instance_name = 'test-stage' #Edit the name of the project name and environment
sender = '<senders email>' #Email Address of the sender
receivers = ['recepient email'] #comma seperated list of recipients enclosed in ''

cpu_thresh = 50.0
cpu_pct = psutil.cpu_percent(interval=1)

if cpu_pct >= cpu_thresh:
    cpu_alert = "CPU Warning, CPU at ",cpu_pct, "percent"
else:
    cpu_alert = ""

mem = psutil.virtual_memory()
mem_thresh = 1024 * 1024 * 1024 #change the end value to choose the amount of MB

if mem_thresh >= mem.available:
    mem_alert = "Memory Usage Warning only", round((mem.available /1024 /1024), 2), "MB available"
else:
    mem_alert = ""
partition1 = '/'
disk1 = psutil.disk_usage(partition1)
disk_thresh = 85.0

if disk_thresh <= disk1[3]:
    disk_alert = f"Root volume usage warning {disk1[3]} % used"
else:
    disk_alert = ""

def net_usage(inf = "eth0"):   #change the inf variable according to the interface
  global net_in_alert
  global net_out_alert
  net_in_ps1 = psutil.net_io_counters(pernic=True, nowrap=True)[inf]
  net_in_1 = net_in_ps1.bytes_recv
  net_out_1 = net_in_ps1.bytes_sent
  time.sleep(1)
  net_in_ps2 = psutil.net_io_counters(pernic=True, nowrap=True)[inf]
  net_in_2 = net_in_ps2.bytes_recv
  net_out_2 = net_in_ps2.bytes_sent
  net_in_res = round((net_in_2 - net_in_1) /1024 /1024, 2)
  net_out_res = round((net_out_2 - net_out_1) /1024 /1024, 2)
  net_in_thresh = 1.5
  net_out_thresh = 1.5
  if net_in_res >= net_in_thresh:
      net_in_alert = f"Current net-usage:IN: {net_in_res} MB/s"
  else:
      net_in_alert = ""
  if net_out_res >= net_out_thresh:
     net_out_alert = f"Current net-usage:OUT: {net_out_res} MB/s"
  else:
      net_out_alert = ""
net_usage()

message_list = []

if cpu_alert == "" :
    pass
else:
    message_list.append(cpu_alert)
if mem_alert == "" :
    pass
else:
    message_list.append(mem_alert)
if disk_alert == "" :
    pass
else:
    message_list.append(disk_alert)
if net_in_alert == "" :
    pass
else:
    message_list.append(net_in_alert)
if net_out_alert == "" :
    pass
else:
    message_list.append(net_out_alert)

msg = '\n'.join(message_list)
print(msg)

def alerts():
  msg_template = MIMEMultipart()
  msg_template['From'] = sender
  msg_template['To'] = ', '.join(receivers)
  msg_template['Subject'] = f"{project_and_instance_name} Alert"
  msg_template.attach(MIMEText(msg, 'plain'))
  server = smtplib.SMTP('smtp.gmail.com', 587)
  server.ehlo()
  server.starttls()
  server.ehlo()
  server.login(sender, "<password>")
  server.sendmail(sender,receivers,msg_template.as_string())
  server.quit()

if msg == "":
  pass
else:
  alerts()
Firdaus Aga
  • 27
  • 2
  • 6
  • For additional reference use the following answer by Omkar:- (https://stackoverflow.com/questions/38151440/can-anyone-tell-my-why-im-getting-the-error-attributeerror-list-object-has) – Firdaus Aga Jul 09 '20 at 04:15
0

Something helpful for me in understanding this answer -

receivers is a list of emails

receivers = ['email1', 'email2']



message template ["To"] is a joined string

msg_template['To'] = ', '.join(receivers)



server.sendmail() is the list of emails

server.sendmail(sender,receivers,msg_template.as_string())
  • Correct, receivers is a comma separated list. msg_template['To'] join converts the list to a comma separated string. server.sendmail is the method smtplib uses to actually send the email in the format sender, receivers and whatever the message is(has to be a string). – Firdaus Aga Jul 28 '20 at 07:21