I have a list of IP addresses like 1000 no's. I am reading the ip_file.txt and storing the result file as result_date.txt. Below is the code that I achieved the result. But my issue is it's taking too long to execute the entire files. Can anyone suggest multithreading, please so that the desired result can be achieved quickly? Thanks in advance.
#!/usr/bin/env python
import os
import csv
import paramiko
from datetime import datetime
import time
import sys
import re
from collections import defaultdict
# Verifies your os type
from paramiko import file
OS_TYPE = os.name
# Sets the count modifier to the os type
count = '-n' if OS_TYPE == 'nt' else '-c'
def create_ip_list():
ip_list = []
with open("ip_file.txt", "r") as file:
for line in file:
ip_list.append(line.strip())
return ip_list
# fetching data
now = datetime.now()
dat = now.strftime("%d/%m/%Y")
# time = now.strftime("%H:%M:%S")
date_string = dat.replace('/', '-')
timestr = time.strftime("%d%m%Y-%H%M%S")
def ping_device(ip_list):
"""Ping ip_list and return results
return: None
rtype: None
"""
results_file = open("results_" + str(timestr) + ".txt", "w")
for ip in ip_list:
response = os.popen(f"ping {ip} {count} 1").read()
time.sleep(1.5)
#fetch Average time
print(response)
for i in response.split("\n"):
para = i.split("=")
try:
if para[0].strip() == "Minimum":
latency = para[3].strip()
print(latency)
# output1=latency[0:8].split(" ")
# test=output1[0]
# print(test)
except:
print("time run")
if "Received = 1" and "Approximate" in response:
#print(f"UP {ip} Ping Successful")
results_file.write(f"{ip},UP,{latency}" + "\n")
else:
print(f"Down {ip} Ping Unsuccessful")
results_file.write(f"{ip} Down" + "\n")
results_file.close()
if __name__ == "__main__":
ping_device(create_ip_list())
Write a function ping_one_device that takes a single ip and returns a single string giving the status. It should be easy to pull this out of ping_device.
Then
with open(results_file, "w") as results_file:
with ThreadPoolExecutor() as executor:
for result in map(ping_one_device, ip_list):
results_file.write(result)
Related
I have the ip_file.txt with the following input fields.
8.8.8.8,8.8.4.4
www.google.com,www.yahoo.com
And I am getting the output as below:
8.8.8.8,UP,20,2022-08-11 22:58:16
8.8.4.4,UP,17,2022-08-11 22:58:16
www.google.com,UP,17,2022-08-11 22:58:16
www.yahoo.com,UP,364,2022-08-11 22:58:16
Here is my code in Python.
import subprocess
import threading
import time
import re
timestr = time.strftime("%Y-%m-%d %H%M%S")
timesec = time.strftime("%Y-%m-%d %H:%M:%S")
raw_list = []
def ping(host):
results_file = open("results_bng_" + str(timestr) + ".txt", "a")
p = subprocess.Popen(["ping", host, "-n", "5"], shell=True, universal_newlines=True, stdout=subprocess.PIPE)
response = p.communicate()[0]
for i in response.split("\n"):
para =i.split("=")
# print(para)
try:
if para[0].strip() =="Minimum":
latency =para[3].strip()
print(latency)
latfin = re.findall('\d+', latency)
latfin1 = latfin[0]
except:
print("time run")
if "Received = 1" and "Approximate" in response:
print(f"UP {host} Ping Successful")
results_file.write(f"{host},UP,{latfin1},{timesec}"+ "\n")
else:
print(f"Down {host} Ping Unsuccessful")
results_file.write(f"{host},Down,0,{timesec}" + "\n")
results_file.close()
with open(r'ip_file.txt', "r") as server_list_file:
hosts = server_list_file.read()
hosts_list = hosts.replace('\n', ',').split(',')
print(hosts_list)
num_threads = 1
number = 0
while number< len(hosts_list):
# print(number)
for i in range(num_threads):
t = threading.Thread(target=ping, args=(hosts_list[number+i],))
t.start()
t.join()
number = number +1
Is there any chance I get the output format as noted below:
8.8.8.8,UP,20,2022-08-11 22:58:16,8.8.4.4,UP,17,2022-08-11 22:58:16
www.google.com,UP,17,2022-08-11 22:58:16,www.yahoo.com,UP,364,2022-08-11 22:58:16
I tried multiple ways, but the input file is taken as a single Array and not able to write the output as given above. Can Anybody help in this. Thank you for your valuable time.
So here is my code:
from os import system
from datetime import datetime
import time
import os
import subprocess
import sys
def status(ip_addr):
return os.system('ping ' + ip_addr + '> nul') == 0
statut[]
print("##################################")
print("Current time: ", str(datetime.now()))
print(" ")
with open('data.txt', 'r+') as adds:
add = [addrs.strip() for addrs in adds.readlines()]
for website in add:
stat = status(website)
if stat == 1:
stats = " is up!"
statut[website] = 1
else:
stats = " is down!"
statut[website] = 0
print(website, stats)
print("##################################")
while True:
print("Current time: ", str(datetime.now()))
print(" ")
with open('data.txt', 'r+') as adds:
add = [addrs.strip() for addrs in adds.readlines()]
for website in add:
stat = status(website)
if stat != statut[website]:
stats = " is up!"
statut[website] = stat
print(website, stats)
print("##################################")
time.sleep(240)
What I want to make out of it is to firstly learn if a server is up/down and after that, check at every 240 sec if it went the other way around - I can't however use boolean array "statut" like I intended. I would really apreciate some help with how I could make it work.
If you are just looking for a state change you could do something like this:
from os import system
from datetime import datetime
import time
def server_status(ip_addr):
if system('ping ' + ip_addr + '> nul') == 0:
return 'up'
else:
return 'down'
status_history = {}
print("##################################")
print("Current time: ", str(datetime.now()))
print(" ")
with open('data.txt', 'r+') as adds:
ipaddress = [addrs.strip() for addrs in adds.readlines()]
# Set inital state
for server in ipaddress:
status_history[server] = server_status(server)
print(f"{server} is {status_history[server]}")
print("##################################")
while True:
print("Current time: ", str(datetime.now()))
print(" ")
for server in ipaddress:
if server_status(server) != status_history[server]:
status_history[server] = server_status(server)
print(f"{server} has switched state to {status_history[server]}")
else:
print(f"{server} is still {status_history[server]}")
print("##################################")
time.sleep(10)
I would put a timeout on the while loop just in case and possible make some parts more configurable, such as the sleep.
I am new to python. I am writing a python program to write to a JSON file if the website is unreachable. The multiple websites will be stored in hosts variable. It will be scheduled to check every 5 seconds. I have used pool from multiprocessing to process the website at the same time without delay. After that, i will write the data to the json file. But in here, it is writing only one website data to json file. So how to make this to write two data at the same time.
Here's the sample code:
import os
from multiprocessing import Pool
from datetime import datetime
import time
import json
hosts = ["www.google.com","www.smackcoders.com"]
n = len(hosts)
def write(hosts):
u = "down"
name = "stack.json"
if not os.path.exists(name):
with open(name, 'w') as f:
f.write('{}')
result = [(timestamp, {'monitor.status': u,
"monitor.id": "tcp-tcp#"+hosts
})]
with open(name, 'rb+') as f:
f.seek(-1, os.SEEK_END)
f.truncate()
for entry in result:
_entry = '"{}":{},\n'.format(entry[0], json.dumps(entry[1]))
_entry = _entry.encode()
f.write(_entry)
f.write('}'.encode('ascii'))
def main(hosts):
p = Pool(processes= n)
result = p.map(write, hosts)
while True:
timestamp = datetime.now().strftime("%B %d %Y, %H:%M:%S")
main(hosts)
time.sleep(5)
My output:
""March 13 2019, 10:49:03":{"monitor.id": "tcp-tcp#www.smackcoders.com", "monitor.status": "down"},
}
Required Output:
{"March 13 2019, 10:49:03":{"monitor.id": "tcp-tcp#www.smackcoders.com", "monitor.status": "down"},"March 13 2019, 10:49:03":{"monitor.id": "tcp-tcp#www.google.com", "monitor.status": "down"},
}
Ive made some minor changes to your code and implemented a Lock.
import os
from multiprocessing import Pool,RLock
from datetime import datetime
import time
import json
file_lock=RLock()
hosts = ["www.google.com","www.smackcoders.com"]
n = len(hosts)
def write(hosts):
u = "down"
name = "stack.json"
if not os.path.exists(name):
with open(name, 'w') as f:
f.write('{}')
result = [(timestamp, {'monitor.status': u,
"monitor.id": "tcp-tcp#"+hosts
})]
with file_lock:
with open(name, 'rb+') as f:
f.seek(-1, os.SEEK_END)
f.truncate()
for entry in result:
_entry = '"{}":{},\n'.format(entry[0], json.dumps(entry[1]))
_entry = _entry.encode()
f.write(_entry)
f.write('}'.encode('ascii'))
def main(hosts):
p = Pool(processes= n)
result = p.map(write, hosts)
while True:
timestamp = datetime.now().strftime("%B %d %Y, %H:%M:%S")
main(hosts)
time.sleep(5)
However, for a long running process that constantly has to read and write a file for logging seems like a poor implementation as the code will have to read a bulky file and completely rewrite it on every process. Consider writing the log in a database instead.
Here's a different option that will use Thread over Pool.
Created a class to get the return of join()
# Class that overwrite Thread to get the return of join()
class ThreadWithReturnValue(Thread):
def __init__(self, group=None, target=None, name=None, args=None, kwargs=None, Verbose=None):
if args is None:
args = ()
if kwargs is None:
kwargs = {}
super().__init__(group, target, name, args, kwargs)
self._return = None
def run(self):
print(type(self._target))
if self._target is not None:
self._return = self._target(*self._args, **self._kwargs)
def join(self, *args):
Thread.join(self, *args)
return self._return
I have changed the code to get the status of each hosts first, then writing the result to your file. Also fixed the way the JSON file is written.
import os
from datetime import datetime
import time
import json
from threading import Thread
hosts = ["www.google.com","www.smackcoders.com"]
filepath = os.path.join(os.getcwd(), "stack.json")
n = len(hosts)
def perform_ping(host_ip):
"""
You have hardcoded down, this method will ping to check if we get an ICMP response
"""
response = os.system("ping -c 1 " + host_ip)
if response == 0:
return 'UP'
else:
return 'DOWN'
def write_result(timestamp, results):
# u = "down" Using perform_ping to get the status
if not os.path.exists(filepath):
current_file = {}
else:
# If file exist, reading the current output
with open(filepath, 'r') as f_read:
current_file = json.loads(f_read.read())
inner_result = []
for result in results:
host, status = result
inner_result.append({'monitor.status': status,
"monitor.id": "tcp-tcp#"+host
})
current_file[timestamp] = inner_result
# writing the file with new input
with open(filepath, 'w') as f_write:
f_write.write(json.dumps(current_file))
def main():
while True:
thread_list = []
for host_ip in hosts:
thread_list.append(ThreadWithReturnValue(target=perform_ping, name=host_ip, args=(host_ip, )))
results = []
timestamp = datetime.now().strftime("%B %d %Y, %H:%M:%S")
for thread in thread_list:
thread.start()
for thread in thread_list:
results.append((thread.name, thread.join()))
# Ping is done in parallel, writing the result at the end to avoid thread collision and reading/writing the file to many times if you increase the number of host
write_result(timestamp, results)
time.sleep(5)
if __name__ == '__main__':
main()
I'm in the process of creating a program that takes an IP address, performs an nmap scan, and takes the output and puts it in a text file. The scan works fine, but I can't seem to figure out why it's not writing anything to the text file.
Here is what I have so far
if __name__ == "__main__":
import socket
import nmap
import sys
import io
from libnmap.parser import NmapParser, NmapParserException
from libnmap.process import NmapProcess
from time import sleep
from os import path
#Program Banner
if len(sys.argv) <= 1:
print(
"""
test
""")
sys.exit()
#Grab IP Address as argument
if len(sys.argv)==2:
ip = sys.argv[1]
print "\n[+] Reading IP Address"
#Function - Pass IP to Nmap then start scanning
print "\n[+] Passing " + ip + " to Nmap..."
print("\n[+] Starting Nmap Scan\n")
def nmap_scan(ip, options):
parsed = None
nmproc = NmapProcess(ip, options)
rc = nmproc.run()
if rc != 0:
print("nmap scan failed: {0}".format(nmproc.stderr))
try:
parsed = NmapParser.parse(nmproc.stdout)
except NmapParserException as e:
print("Exception raised while parsing scan: {0}".format(e.msg))
return parsed
#Function - Display Nmap scan results
def show_scan(nmap_report):
for host in nmap_report.hosts:
if len(host.hostnames):
tmp_host = host.hostnames.pop()
else:
tmp_host = host.address
print("Host is [ %s ]\n" % str.upper(host.status))
print(" PORT STATE SERVICE")
for serv in host.services:
pserv = "{0:>5s}/{1:3s} {2:12s} {3}".format(
str(serv.port),
serv.protocol,
serv.state,
serv.service)
if len(serv.banner):
pserv += " ({0})".format(serv.banner)
print(pserv)
#Function - Define output text file name & write to file
def createFile(dest):
name = "Enumerator-Results.txt"
if not(path.isfile(dest+name)):
f = open(dest+name,"a+")
f.write(show_scan(report))
f.close()
if __name__ == "__main__":
report = nmap_scan(ip, "-sV")
if report:
destination = "/root/Desktop/"
createFile(destination)
show_scan(report)
print "\nReport Complete!"
else:
print("No results returned")
You're using print statements in your show_scan() function. Instead try passing the file reference to show_scan() and replacing the print() calls with f.write() calls. This would save to file everything you're currently printing to the terminal.
Alternatively you could just change your code so that the show_scan is separate from the f.write().
ie change
f.write(show_scan(report))
to
f.write(report)
It depends on whether you want to save the raw output or what you're printing to the screen.
Also you will need to pass the reference of the report to createFile so that it has the report to print ie
createFile(destination, report)
Just make sure you are always calling f.write() with a string as its parameter.
#Function - Define output text file name & write to file
def createFile(dest, report):
name = "Enumerator-Results.txt"
if not(path.isfile(dest+name)):
f = open(dest+name,"a+")
f.write(report)
f.close()
if __name__ == "__main__":
report = nmap_scan(ip, "-sV")
if report:
destination = "/root/Desktop/"
createFile(destination, report)
show_scan(report)
print "\nReport Complete!"
else:
print("No results returned")
i wrote a simple agaent in python that all it dose is just cheacks for the internet connection.
When he finds out that ther is no connection he writes a log file to a text the hour and date and then just exit the program.
I want it to keep testing if there is a connection even if there is not how can i do this ? without the program exit
this is the code:
import os
import time
def Main():
ping =os.system('ping -n 1 -l 1000 8.8.8.8 ')
while ping ==0:
time.sleep(4)
ping = os.system('ping -n 1 -l 1000 8.8.8.8 ')
if ping ==1:
print 'no connection'
CT =time.strftime("%H:%M:%S %d/%m/%y")
alert=' No Connection'
f = open('logfile.txt','a+')
f.write('\n'+CT)
f.write(alert)
f.close()
if __name__ == "__main__":
Main()
Thanx a lot.
Wrap the Main call in an infinite loop?
if __name__ == "__main__":
while True:
Main()
time.sleep(1) # optional, as Main already contains a sleep time
This code should set you on your way. Just substitute the host with that of your choosing in the call to the LogPing object.
Check out the comments inline and please ask me if you have any questions.
from datetime import datetime
import os
import shlex
import subprocess
from time import sleep
class LogPing:
def __init__(self, host, count=1, timeout_seconds=10, logfile="ping_log.txt"):
self.host = host
self.count = count
self.timeout_seconds = timeout_seconds
self.logfile = logfile
self.output_blackhole = open(os.devnull, 'wb')
def _command(self):
command_string = "ping -c {count} -t {timeout} {host}".format(
count=self.count,
timeout=self.timeout_seconds,
host=self.host
)
try:
# we don't actually care about the output, just the return code,
# so trash the output. result == 0 on success
result = subprocess.check_call(
shlex.split(command_string),
stdout=self.output_blackhole,
stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError:
# if here, that means that the host couldn't be reached for some reason.
result = -1
return result
def run(self):
ping_command_result = self._command()
if ping_command_result == 0:
status = "OK"
else:
status = "NOK"
# The time won't be exact, but close enough
message = "{status} : {time} : {host}\n".format(
status=status,
time=datetime.utcnow().strftime("%Y-%m-%d_%T"),
host=self.host
)
# open file in a context manager for writing, creating if not exists
# using a+ so that we append to the end of the last line.
with open(self.logfile, 'a+') as f:
f.write(message)
if __name__ == "__main__":
while True:
ping_instance = LogPing("example.org").run()
sleep(4)
If I understand yous correctly this will do its job:
import os
import time
def Main():
while True:
ping = os.system('ping -n 1 -l 1000 8.8.8.8 ')
if ping:
print 'no connection'
CT =time.strftime("%H:%M:%S %d/%m/%y")
alert=' No Connection'
with open('logfile.txt','a+') as f:
f.write('\n'+CT)
f.write(alert)
time.sleep(4)
if __name__ == "__main__":
Main()