[Python-de] cmd-module und cmd.exe Probleme
Oliver Friedrich
beowulfof at gmx.de
Do Mär 27 09:06:38 CET 2014
Hier, aufgrund der Nachfragen, eine eingedampfte Version des Programms.
Ziel ist es, diverse Logdateien von Unix-Servern zu holen in einer
Umgebung mit sehr eingeschränkten Möglichkeiten, daher wird über Putty
eine Verbindung zu den Servern aufgebaut und mittels Netcat die
gewünschten Dateien übertragen. Diese werden anschließend in einzelne
Logeinträge geparsed und später weiter verarbeitet (Auswertung von
Performance-Ausgaben, etc).
Der Code ist noch ein Prototyp, daher ziemlich gemixt aus Prozedural und
OOP. Ok, sein wir ehrlich, er wird auch nie über den Prototyp-Status
hinaus kommen ;-)
#!/usr/bin/env python3
# -*- coding=UTF-8 -*-
from queue import Queue, Empty
from threading import Thread, Lock
from time import sleep
import codecs
import os, re
import subprocess
import hashlib
import shelve
import argparse
import csv
import cmd
import socket
timestampregex = []
def readTimestampRegex():
with codecs.open('timestamp.regex', encoding='utf-8') as file:
reader = csv.reader(file, delimiter=';')
for line in reader:
if not line[0][0] == '#':
timestampregex.append(re.compile(line[0] + '.*?(?=' + line[0]+')', re.M | re.S))
print(line[1] + ':' + line[0])
readTimestampRegex()
class RemoteFileMonitor():
def __init__(self, plink, outdir, dumpfile, queue, host, user, pw, name, path):
self.host = host
self.user = user
self.pw = pw
self.name = name
self.path = path
self.plink = plink
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socketConn = None
self.recvHost = ''
self.recvPort = 0
self.entryQueue = queue
self.link = None
self.readingThread = Thread(name=self.name + '_reader', target=self.enqueue_output, daemon=True)
self.parsingThread = Thread(name=self.name + '_parser', target=self.parse, daemon=True)
self.buffer = ''
self.bufferQueue = Queue()
def enqueue_output(self):
while True:
self.bufferQueue.put(self.socketConn.recv(1024).decode('utf-8','ignore'))
def getPlinkPrefix(self):
pre = self.plink
pre += ' -l ' + self.user
if not self.pw == '-':
pre += ' -pw ' + self.pw
pre += ' ' + self.host + ' '
return pre
def connect(self):
self.socket.bind((self.recvHost, self.recvPort))
self.recvPort = self.socket.getsockname()[1]
self.recvHost = socket.gethostbyname(socket.gethostname())
self.socket.listen(1)
cmd = 'tail -F ' + self.path + ' | nc ' + self.recvHost + ' ' + str(self.recvPort)
self.link = subprocess.Popen(self.getPlinkPrefix() + cmd, bufsize=1, stdout=subprocess.PIPE)
self.socketConn = self.socket.accept()[0]
def parse(self):
buf = ''
while True:
try:
line = self.bufferQueue.get_nowait()
except Empty:
pass
else:
buf += line
for r in timestampregex:
for m in r.finditer(buf):
self.entryQueue.put(self.path,m.group())
buf = buf.replace(m.group(),'')
def start(self):
if self.link == None:
self.connect()
self.readingThread.start()
self.parsingThread.start()
def stop(self):
self.parsingThread.stop()
self.readingThread.stop()
if self.link != None:
self.link.terminate()
class Monitor():
def __init__(self, configpath, delay, plink, outdir, dumpfile):
self.config = configpath
self.delay = delay
self.outdir = outdir
self.dumpfile = dumpfile
self.plink = plink
self.fileMonitors = []
self.entryQueue = Queue()
def readConfig(self):
with codecs.open(self.config, encoding='utf-8') as file:
reader = csv.reader(file, delimiter=';')
for line in reader:
if len(line) >= 5:
filemon = RemoteFileMonitor(self.plink, self.outdir, self.dumpfile, self.entryQueue, line[0], line[1], line[2], line[3], line[4])
self.fileMonitors.append(filemon)
def start(self):
for fileMon in self.fileMonitors:
fileMon.start()
print(fileMon.name + ' started')
def stop(self):
for fileMon in self.fileMonitors:
fileMon.stop()
class Shell(cmd.Cmd):
def __init__(self):
self.monitor = None
def do_prepare(self, arg):
self.Monitor = Monitor('logs.csv', 30, r'c:\Portable\Putty\plink.exe', r'c:\tmp', True)
self.Monitor.readConfig()
def do_start(self, arg):
self.Monitor.start()
def do_stop(self, arg):
self.Monitor.stop()
def do_status(self, arg):
print(self.Monitor.entryQeue.qsize())
def precmd(self, line):
line = line.lower()
return line
if __name__ == '__main__':
Shell().cmdloop()
Mehr Informationen über die Mailingliste python-de