Le ping est envoyé à plusieurs destinations, et lorsque 90% est NG, il est considéré comme une erreur et un e-mail est envoyé (Gmail). Si le ping est OK pour le nombre spécifié de fois de suite, la récupération est jugée.
La première source est multithread, mais je ne comprends pas vraiment pourquoi cela fonctionne, donc je ne sais pas pourquoi cela fonctionne. C'est aussi la mauvaise source car il y a certainement des bugs.
Le programme qui ne devrait avoir aucun bogue est décrit dans la seconde moitié. Ce n'est pas multi-thread, mais multi-traitement dans la seconde moitié. 2016/12/29 Corrigé: Il y avait un bug, donc je l'ai corrigé. Veuillez vous référer aux commentaires dans la source pour plus de détails sur la seconde moitié du programme.
Ensuite, c'est l'explication de la mauvaise source. Pour le moment, c'est l'importation.
import pandas as pd
import smtplib
import os, platform
import threading
Vient ensuite la fonction d'envoi de Gmail. Lors de l'envoi de Gmail, vous devez activer l'accès POP dans votre compte pour autoriser l'accès à des applications moins sécurisées. Si vous recherchez, vous trouverez un commentaire aimable avec un écran GUI attaché, je vous laisse donc les détails.
def sendGmail(text):
user = '****@gmail.com' # username
password = '******' # password
to = ['****@gmail.com'] # your favorite mail address
sub = 'mail title'
msg = '''From: %s\nTo: %s\nSubject: %s\n\n%s
''' % (user, ','.join(to), sub, text)
server = smtplib.SMTP_SSL("smtp.gmail.com", 465)
server.ehlo()
server.login(user, password)
server.sendmail(user, to, msg)
server.close()
Vient ensuite la fonction d'envoi de ping. log est un DataFrame. Ce n'est pas forcément un bloc de données, mais j'y suis habitué parce que j'y suis habitué. Il y a beaucoup d'arguments pour enregistrer le résultat du ping, et c'est la partie que je trouve sale.
def ping(address, current_position, log):
ping_str = '-n 1' if platform.system().lower() == 'windows' else '-c 1'
response = os.system('ping ' + ping_str + ' ' + address)
if response == 1:
log[address][current_position] = 1
Vient ensuite la fonction principale. Séquentiellement, le résultat du ping est écrit dans la trame de données appelée journal et à chaque fois, lorsque 700 points sont retracés à partir du dernier journal, s'il y a 600 erreurs de ping ou plus, le courrier est ignoré.
if __name__ == '__main__':
domain_list = ['***address***'] # your favorite address
log = pd.DataFrame(0, index=range(60 * 60), columns=domain_list)
#Pour le moment, créez un grand DataFrame.
current_position = 0
sum_of_seconds = 0
sendGmail('tool has started.')
while True:
text = []
for address in domain_list:
p = threading.Thread(target=ping, args=(address, current_position, log))
p.start()
sum_error = 0
for i in range(700):#Je pense que c'est inefficace
sum_error += log.ix[current_position - i if current_position >= i else 60 * 15 - (i - current_position), address]
if sum_error > 600:
text.append(address)
if (sum_of_seconds % 600 == 0) and (text != []):
sendGmail(text)
current_position += 1
if current_position >= 60 * 15:
current_position = 0
sum_of_seconds += 1
time.sleep(1)
Le jour après avoir écrit la source ci-dessus, j'ai pensé que le multi-traitement serait mieux, alors je l'ai réécrit. J'ai trouvé le type dict utile pour la première fois.
Tout d'abord, la partie envoi de Gmail est la même. Ensuite, concernant la transmission Ping, il a été révisé comme suit.
import multiprocessing as mp
def ping(address, result):
ping_str = '-n 1' if platform.system().lower() == 'windows' else '-c 1'
response = subprocess.call('ping '+ ping_str + ' '+address)
if response = 1:
result[address] = 1
else:
result[address] = 0
le résultat est de type dict. Plus tard, nous ferons du multi-traitement. En ce qui concerne le ping, subprocess.call semble être meilleur que os.system, donc je le réécris sans comprendre.
Vient ensuite la fonction principale, qui est la suivante.
if __name__ == '__main__':
manager = mp.Manager()
current_position = 0
bottom = 60*60
evaluate_range = 5 # x5
recover_range = 2 #10
evaluate_ratio = 0.9
before_result = pd.Series()
act_num = 0
domain_list = ['***', '****']
log = pd.DataFrame(0, index=range(bottom), columns=domain_list)
#Il définit un DataFrame qui enregistre le résultat après le ping.
while True:
proc = [] #Pour le multi-traitement
result = manager.dict() #Définir un dict à partager entre les processus
for address in domain_list:
p1 = mp.Process(target=ping, args=(address, result,))
proc.append(p1)
for p1 in proc:
p1.start()
for p1 in proc:
p1.join()
#Copiez le résultat du ping du résultat de type dict dans le journal du DataFrame.
for address in domain_list:
log.ix[current_position, address] = result[address]
#Puisque le journal continuera d'être utilisé en tournant, la position actuelle contenant les dernières données
#En fonction de la valeur, dataframe.sum()La plage à agréger est modifiée dans.
value = log.ix[current_position-evaluate_range:current_position, :].sum() if current_position >= evaluate_range else \
log.ix[0:current_position, :].sum() + log.ix[bottom-(evaluate_range-current_position):bottom,:].sum()
#Similaire à la valeur ci-dessus, récupérez avec une plage de contrôle légèrement plus courte afin de refléter le jugement au moment du ping OK dès que possible._Calculer la valeur
recover_value = log.ix[current_position-recover_range:current_position, :].sum() if current_position >= recover_range else \
log.ix[0:current_position, :].sum() + log.ix[bottom-(recover_range-current_position):bottom,:].sum()
result = value[(value > evaluate_range*evaluate_ratio) & (recover_value != 0)]
#J'essaie d'appeler sendGmail uniquement lorsque le résultat change pour que le mail de notification ne vole pas trop.
#Puisque la conception ne regarde pas les détails du nombre de ping NG, seul l'index est extrait et comparé.
#.difference()Ne vérifie pas le différentiel dans les deux sens, je connecte donc la vérification unidirectionnelle avec ou.
if not pd.Series().index.equals(result.index.difference(before_result.index)) or not pd.Series().index.equals(before_result.index.difference(result.index)):
if result.size != 0:
sendGmail(result.index.str.cat(sep='\n'))
before_result = result
else:
sendGmail('All server are normally operating.')
before_result = result
current_position += 1
if current_position > bottom:
current_position = 0
time.sleep(1)
J'utilise des pandas parce que j'aime les pandas familiers pour l'agrégation de journaux. J'avais besoin de données partageables pour le multi-traitement, j'ai donc passé result = manager.dict () à la fonction ping.
Recommended Posts