Commit bd72af5c authored by Michael König (Student)'s avatar Michael König (Student)
Browse files

more refactoring

parent 54270258
================================================================================
The source code of this software has been developed by:
Karlsruhe Institute of Technology
......@@ -36,7 +34,3 @@ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================================================
# -*- coding: utf-8 -*-
class StdoutLogging:
def __init__(self, sampleQueue, valuesToLog):
self.sampleQueue = sampleQueue
self.valuesToLog = valuesToLog
pass
def preLog(self):
pass
# print logformat
def proccessLogSample(self):
"""Print log data to stdout"""
try:
sampleObject = self.sampleQueue.popleft()
except IndexError:
pass
else:
valueList = []
for val in self.valuesToLog:
valueList.append(str(getattr(sampleObject, val, None)))
logLine = ' '.join(valueList)
print(logLine)
def postLogging(self):
pass
......@@ -27,9 +27,7 @@ from ipaddress import ip_address
from .sample import Sample
from .flow import Flow
from .broadcast_log_server import BroadcastLogServer
import tcpinfo
from .output_backends.broadcast_log_server import BroadcastLogServer
# format of "/proc/net/tcpprobe"
#
......@@ -69,23 +67,23 @@ FLOW_CLEAR_TIMEOUT = 10 # in seconds
REFRESH_RATE_LIVE_STATS = 1 # in seconds
BANDWIDTH_SAMPLE_DELTA = 1 # in seconds
shutdownFlag = False
lock = threading.Lock()
class TcpLogApp():
def __init__(self, options):
self.options = options
class TcpLog:
def init(self):
def run(self):
"""Initializes data structures and starts needed tasks"""
# register signals
signal.signal(signal.SIGINT, self.handleSignals)
signal.signal(signal.SIGTERM, self.handleSignals)
if(len(args.filterPorts) < 1):
args.filterPorts.append(DEFAULT_FILTER_PORT)
if(len(self.options.filterPorts) < 1):
self.options.filterPorts.append(DEFAULT_FILTER_PORT)
self.__start_time = None
self.__timestampLastSample = 0
self.__log = deque(maxlen = args.bufferLength)
self.__log = deque(maxlen = self.options.bufferLength)
self.__flows = {}
self.__linesProccessed = 0
self.__matchesProccessed = 0
......@@ -100,9 +98,11 @@ class TcpLog:
self.__autologgingControlThread.daemon = True
self.__processTcpProbeThread.start()
if(args.quiet != True and args.logType != "stdout"):
print("foo123123")
if(self.options.quiet != True and self.options.logType != "stdout"):
self.__printStatsThread.start()
if(args.killswitchTimeout > 0):
if(self.options.killswitchTimeout > 0):
self.__autologgingControlThread.start()
......@@ -113,7 +113,7 @@ class TcpLog:
def reading_from_regular_file(self):
## TODO(mario) we could optimize this by just checking this once and write the result to bool variable
return not args.inputFile.startswith("/proc")
return not options.inputFile.startswith("/proc")
# @profile
......@@ -124,8 +124,8 @@ class TcpLog:
# for regular files, we could make a nice/informing "progress" output,
# rater than using the "live" curses GUI or just -q
try:
if(not args.useTcpInfo and not args.useNativeTcpInfo):
self.__tcpProbeFileHandler = open(args.inputFile, 'r')
if(not options.useTcpInfo and not options.useNativeTcpInfo):
self.__tcpProbeFileHandler = open(options.inputFile, 'r')
## Try to read a timestamp, if it's a regular file
if ( self.reading_from_regular_file() ):
......@@ -154,16 +154,16 @@ class TcpLog:
except:
print("Error: while parsing " + args.inputFile)
print("Error: while parsing " + options.inputFile)
sys.exit(1)
return
else:
if(args.useTcpInfo):
if(options.useTcpInfo):
fakeRelativeTimestamp_start = time.time()
lastTimestamp = 0
while(not self.__stopped.wait(0.000001)):
if(time.time() - lastTimestamp < args.logResolution):
time.sleep(args.logResolution/1000)
if(time.time() - lastTimestamp < options.logResolution):
time.sleep(options.logResolution/1000)
continue;
lastTimestamp = time.time()
fakeRelativeTimestamp = time.time() - fakeRelativeTimestamp_start
......@@ -183,12 +183,13 @@ class TcpLog:
lineToParse = " ".join(tmpLine)
self.processLogLine(lineToParse, TCP_PROBE_FORMAT) # to reuse processLogLine use same format as TcpProbe
elif(args.useNativeTcpInfo):
elif(options.useNativeTcpInfo):
import tcpinfo
fakeRelativeTimestamp_start = time.time()
lastTimestamp = 0
while(not self.__stopped.wait(0.000001)):
if(time.time() - lastTimestamp < args.logResolution):
time.sleep(args.logResolution/1000)
if(time.time() - lastTimestamp < options.logResolution):
time.sleep(options.logResolution/1000)
continue;
lastTimestamp = time.time()
fakeRelativeTimestamp = time.time() - fakeRelativeTimestamp_start
......@@ -273,10 +274,10 @@ class TcpLog:
# srcIp:srcPort-dstIp:dstPot
flowIdentifer = src + "-" + dst
if(args.noFilter):
if(options.noFilter):
processLine = True
if(dstPort in args.filterPorts):
if(dstPort in options.filterPorts):
processLine = True
if(processLine):
......@@ -309,8 +310,8 @@ class TcpLog:
loss_detected = False
flow.sst = new_sst
if(not args.useTcpInfo and not args.useNativeTcpInfo):
if(relativeTimestamp - lastTimestamp < args.logResolution):
if(not options.useTcpInfo and not options.useNativeTcpInfo):
if(relativeTimestamp - lastTimestamp < options.logResolution):
# make an exception from the regular sampling rate, if packet loss is assumed
if ( not loss_detected ):
# FIXME: "reactivate" exception
......@@ -400,32 +401,31 @@ class TcpLog:
def processLogData(self):
"""Macro to initialize logging to logType-destination"""
if(args.logType == "socket"):
self.processSocketLog()
elif(args.logType == "file"):
self.processFileLog()
elif(args.logType == "stdout"):
self.processStdLog()
# if(options.logType == "socket"):
# self.processSocketLog()
# elif(options.logType == "file"):
# self.processFileLog()
if(options.logType == "stdout"):
from .output_backends.stdout
else:
print("Logging type invalid.")
self.tearDown()
print("Logging type invalid. Exit...")
sys.exit(1)
def processSocketLog(self):
"""Macro to start broadcast server"""
self.__socketServer = BroadcastLogServer(SERVER_ADDRESS, args.logPort, self.__log, self.__msgQueue).listen()
self.__socketServer = BroadcastLogServer(SERVER_ADDRESS, options.logPort, self.__log, self.__msgQueue).listen()
def processFileLog(self):
"""Log data to file. Creates empty file on startup"""
lock.acquire()
try:
self.__logFileHandler = open(args.logFilePath, 'w')
self.__logFileHandler = open(options.logFilePath, 'w')
except:
print("Error: while opening log file: " + args.logFilePath)
print("Error: while opening log file: " + options.logFilePath)
sys.exit(1)
else:
# open file and clear content (if there is any)
os.chmod(args.logFilePath, 0o644)
os.chmod(options.logFilePath, 0o644)
self.__logFileHandler.truncate(0)
if ( self.__start_time == False ):
......@@ -440,7 +440,7 @@ class TcpLog:
self.__logFileHandler.write("#VERSION: " + str(TCP_LOG_FORMAT_VERSION) + "\n")
self.__logFileHandler.write("#DATE: " + timeAsString + "\n")
self.__logFileHandler.write("#TIMESTAMP: " + start_time + "\n")
self.__logFileHandler.write("#RESOLUTION: " + str(args.logResolution) + "s" + "\n")
self.__logFileHandler.write("#RESOLUTION: " + str(options.logResolution) + "s" + "\n")
self.__logFileHandler.write("#FORMAT: " + " ".join(map(str, VALUES_TO_LOG)) +"\n")
self.__logFileHandler.write("#UNITS: " + " ".join(map(str, VALUES_TO_LOG_UNITS)) +"\n")
self.__logFileHandler.write("#END_HEADER\n\n")
......@@ -461,35 +461,21 @@ class TcpLog:
self.__logFileHandler.write(logLine + "\n")
lock.release()
def printHelper(self, stringToPrint):
"""Macro for text printing. Tests for quiet-option"""
if(args.quiet != True):
if(options.quiet != True):
print(stringToPrint)
def processStdLog(self):
"""Print log data to stdout"""
while(not self.__stopped.wait(0.0001)):
try:
sampleObject = self.__log.popleft()
except IndexError:
time.sleep(0.0001)
else:
valueList = []
for val in VALUES_TO_LOG:
valueList.append(str(getattr(sampleObject, val, None)))
logLine = ' '.join(valueList)
print(logLine)
return
def autologgingControl(self):
"""Handles autologging timeouts"""
while(not self.__stopped.wait(0.2)):
currentTimestamp = time.time()
if(self.__timestampLastSample > 0):
if(currentTimestamp - self.__timestampLastSample > args.killswitchTimeout):
if(currentTimestamp - self.__timestampLastSample > options.killswitchTimeout):
self.printHelper("Autologging timeout reached - exiting...")
self.__stopped.set()
return
......@@ -525,12 +511,12 @@ class TcpLog:
try:
if(clearTerminal):
time.sleep(args.refreshRateLiveStats)
time.sleep(options.refreshRateLiveStats)
window.clear()
window.refresh()
clearTerminal = False
if(args.logType == "socket"):
if(options.logType == "socket"):
try:
self.__numberOfClients = self.__msgQueue.get(True, 0.001)
except queue.Empty:
......@@ -555,16 +541,16 @@ class TcpLog:
# print general config
configString = ""
configString += "Filtering for these ports:\n"
if(not args.noFilter):
for port in args.filterPorts:
if(not options.noFilter):
for port in options.filterPorts:
configString += " * " + str(port) + "\n"
else:
configString += " * all ports\n"
configString += "\n"
if(args.logType == "socket"):
configString += "Logging to socket: " + SERVER_ADDRESS + ":" + str(args.logPort)
elif(args.logType == "file"):
configString += "Logging to file: " + args.logFilePath
if(options.logType == "socket"):
configString += "Logging to socket: " + SERVER_ADDRESS + ":" + str(options.logPort)
elif(options.logType == "file"):
configString += "Logging to file: " + options.logFilePath
else:
pass
configString += "\n"
......@@ -577,11 +563,11 @@ class TcpLog:
"Lines processed" : self.__linesProccessed,
"Lines filtered" : self.__matchesProccessed,
"Filtered Flows" : len(self.__flows),
"Log resolution" : str(args.logResolution),
"Logbuffer" : str(len(self.__log)) + "/" + str(args.bufferLength)
"Log resolution" : str(options.logResolution),
"Logbuffer" : str(len(self.__log)) + "/" + str(options.bufferLength)
}
if(args.logType == "socket"):
if(options.logType == "socket"):
applicationInfos["Clients"] = str(self.__numberOfClients)
lengthLongestString = 0
......@@ -661,7 +647,7 @@ class TcpLog:
startXindex = 0
startYindex += 1
window.refresh()
time.sleep(args.refreshRateLiveStats)
time.sleep(options.refreshRateLiveStats)
except:
clearTerminal = True
......@@ -679,22 +665,20 @@ class TcpLog:
def tearDown(self):
"""Performs the cleanup at programm termination."""
global shutdownFlag
shutdownFlag = True
self.__stopped.set()
self.__processTcpProbeThread.join(1.5)
if(args.quiet != True and args.logType != "stdout"):
if(options.quiet != True and options.logType != "stdout"):
self.__printStatsThread.join(1.5)
if(args.killswitchTimeout > 0):
if(options.killswitchTimeout > 0):
self.__autologgingControlThread.join(1.5)
self.printHelper("\n")
self.printHelper("Shutting down...")
if(args.logType == "socket"):
if(options.logType == "socket"):
self.printHelper("Closing socket...")
# Sockets gets closed by signal
elif(args.logType == "file"):
elif(options.logType == "file"):
self.printHelper("Closing log file...")
self.__logFileHandler.close()
......@@ -704,8 +688,7 @@ class TcpLog:
def getLog(self):
return self.__log
def main():
#parse args
def parse_options():
parser = argparse.ArgumentParser()
parser.add_argument(
......@@ -810,32 +793,34 @@ def main():
type=int,
default=0)
args = parser.parse_args()
options = parser.parse_args()
return options
def startupSelfCheck(options):
# test for root-permissions
if (os.getuid() == 0):
print("Error: Please do not run this program with root-privileges. Exiting...")
sys.exit(1)
if (args.showVersion):
if (options.showVersion):
print("TCPlog version: " + TCP_LOG_VERSION + " (format version: " + TCP_LOG_FORMAT_VERSION + ")")
sys.exit(0)
PID = str(os.getpid())
if(os.path.isfile(PID_FILE)):
print("Error: %s already exists. Exiting..." % PID_FILE)
sys.exit(1)
# test if tcp_probe/input-file is readable
if(not args.useTcpInfo and not args.useNativeTcpInfo):
readable = os.access(args.inputFile, os.R_OK)
if(not options.useTcpInfo and not options.useNativeTcpInfo):
readable = os.access(options.inputFile, os.R_OK)
if(not readable):
print("\n\n")
print("=======================================================================")
print("Error: TCP-Probe file '" + args.inputFile + "' not readable. Exiting...")
print("Error: TCP-Probe file '" + options.inputFile + "' not readable. Exiting...")
# only print this help if necessary
if(args.inputFile == PATH_TO_TCP_PROBE):
if(options.inputFile == PATH_TO_TCP_PROBE):
print("Kernel module loaded? Permissions set? Try:\n")
print("sudo modprobe tcp_probe full=1 port=0 &&\n \\sudo chmod 444 /proc/net/tcpprobe")
......@@ -843,7 +828,7 @@ def main():
sys.exit(1)
# test if TcpInfo binary is there and executable
if(args.useTcpInfo):
if(options.useTcpInfo):
if(not os.path.isfile(PATH_TO_TCP_INFO)):
print("Error: TcpInfo binary not found. Exiting...")
sys.exit(1)
......@@ -851,7 +836,7 @@ def main():
print("Error: TcpInfo binary found but not executable. Exiting...")
sys.exit(1)
if(args.useNativeTcpInfo):
if(options.useNativeTcpInfo):
try:
import tcpinfo
tcpinfo.getTcpInfoList()
......@@ -860,9 +845,9 @@ def main():
sys.exit(1)
# test if another process is already using the input-file
if(not args.useTcpInfo and not args.useNativeTcpInfo):
if(not options.useTcpInfo and not options.useNativeTcpInfo):
# count stdout of lsof and do some dirty casting...
command = "lsof -t " + args.inputFile + "|wc -l"
command = "lsof -t " + options.inputFile + "|wc -l"
process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=None, shell=True)
numberOfProcsAsString = bytes(process.communicate()[0]).decode('utf-8')
numberOfProcs = int(numberOfProcsAsString)
......@@ -870,22 +855,34 @@ def main():
print("Error: Input file already in use by another process. Exiting...")
sys.exit(1)
def main():
options = parse_options()
startupSelfCheck(options)
# if we made it to this point: No startup errors detected...
# write pid-file
PID = str(os.getpid())
pidFileHandler = open(PID_FILE, "w")
pidFileHandler.write(PID)
try:
TcpLog().init() # <-- starts the main programme
print("abc")
tcpLogApp = TcpLogApp(options) # <-- starts the main programme
tcpLogApp.run()
print("sdivhaskldf")
except Exception as e:
print(str(e))
raise e
finally:
print("quitted")
# clean up (remove pid-file) and exit
os.unlink(PID_FILE)
sys.exit(0)
if __name__ == "__main__":
args = None
options = None
stdsrc = None
print("foo")
main()
......@@ -3,26 +3,26 @@
from setuptools import setup
with open("VERSION.txt", "rb") as f:
version = f.read().decode("utf-8")
setup(
name = "tcplog",
packages = ["TCPlog", "TCPplot"],
entry_points = {
"console_scripts": [
name = "tcplog",
packages = ["TCPlog", "TCPplot"],
entry_points = {
"console_scripts": [
'tcplog = TCPlog.tcplog:main'
],
"gui_scripts": [
],
"gui_scripts": [
'tcpplot = TCPplot.tcpplot:main'
]
},
version = version,
description = "Collection of tools to log, plot and analyze TCP flows.",
author = "Michael Koenig",
author_email = "michael.koenig2@student.kit.edu",
url = "https://git.scc.kit.edu/CPUnetLOG/TCPlog/",
license = "BSD 2-Clause License"
)
]
},
version = version,
description = "Collection of tools to log, plot and analyze TCP flows.",
author = "Michael Koenig",
author_email = "michael.koenig2@student.kit.edu",
url = "https://git.scc.kit.edu/CPUnetLOG/TCPlog/",
license = "BSD",
install_requires = ['tcpinfo>=0.1']
)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment