Introduction
Manual monitoring of text data made easy
Background
Unfortunately, there is a lot of boring work involved in monitoring text data, hence the requirement of a code to do the same work in the background. The idea was to run the code in the background. The code will scan the files and in case that particular keyword exists - it will display a wx.AlertBox with ON_TOP field selected so that the user comes to know that an anomaly has been found at some time/server.
Using the code
The prerequisites can be found from the source itself. Just take a look at the imports in the file. The imports are nothing but like the preprocessor inclusion in C/C++.
win32wnet
and wx
support are required for the UI and mapping of drives to work properly. The flow is simple (Keep
It Stupidly Simple), first map the server network drives,
and then start reading the files one after the other. Threading was kept in mind but since this was built to run on a virtual machine, threading was removed as the virtual
machine was slowing down a bit.
import wx
import win32wnet
import win32com.client
from win32netcon import RESOURCETYPE_DISK as DISK
import sys
import os
import fileinput
import shutil
import re
import time
...
The imports are mostly present apart from the Win32 modules and the wx module. After the imports, the UI is brought up using the following code:
def displayUI(self):
menuBar = wx.MenuBar()
fileMenu = wx.Menu()
helpMenu = wx.Menu()
fileItem = fileMenu.Append(wx.ID_EXIT, "Quit Ctrl+Q", "Quit Application")
aboutItem = helpMenu.Append(wx.ID_ANY, "About Log Monitor", "Log Monitor Help")
menuBar.Append(fileMenu, "&File")
menuBar.Append(helpMenu, "&Help")
self.SetMenuBar(menuBar)
self.Bind(wx.EVT_MENU, self.OnQuit, fileItem)
self.Bind(wx.EVT_MENU, self.DispAbt, aboutItem)
self.panel = wx.Panel(self, -1)
basicLabel = wx.StaticText(self.panel, -1, "Username: ")
self.basicText = wx.TextCtrl(self.panel, -1, "", size=(175, -1))
self.basicText.SetInsertionPoint(0)
pwdLabel = wx.StaticText(self.panel, -1, "Password: ")
self.pwdText = wx.TextCtrl(self.panel, -1, "", size=(175, -1), style=wx.TE_PASSWORD)
self.pwdText.SetInsertionPoint(0)
self.onErr = wx.CheckBox(self.panel, 1, 'Alert box on Error')
self.onRestart = wx.CheckBox(self.panel, 1, 'Alert box on Cluster Restart')
self.onExc = wx.CheckBox(self.panel, 1, 'Alert box on Exception')
self.onHT = wx.CheckBox(self.panel, 1, 'Alert on hung threads')
self.onFtnft = wx.CheckBox(self.panel, 1, 'Alert on Feature * not found')
self.onDlock = wx.CheckBox(self.panel, 1, 'Alert on Deadlock')
self.map_button = wx.Button(self.panel, wx.ID_OK, "Map")
self.map_button.Bind(wx.EVT_BUTTON, self.OnMap)
self.mainSizer = wx.BoxSizer(wx.VERTICAL)
unameSizer = wx.BoxSizer(wx.HORIZONTAL)
pwdSizer = wx.BoxSizer(wx.HORIZONTAL)
btnSizer = wx.BoxSizer(wx.HORIZONTAL)
onErrSizer = wx.BoxSizer(wx.HORIZONTAL)
onRestartSizer = wx.BoxSizer(wx.HORIZONTAL)
onExcSizer = wx.BoxSizer(wx.HORIZONTAL)
onHTSizer = wx.BoxSizer(wx.HORIZONTAL)
onFtnftSizer = wx.BoxSizer(wx.HORIZONTAL)
onDlockSizer = wx.BoxSizer(wx.HORIZONTAL)
unameSizer.Add(basicLabel, 0, wx.CENTER, 5)
unameSizer.Add(self.basicText, 1, wx.CENTER, 5)
pwdSizer.Add(pwdLabel, 0, wx.CENTER, 5)
pwdSizer.Add(self.pwdText, 1, wx.CENTER, 5)
btnSizer.Add(self.map_button, 0, wx.CENTER, 5)
onErrSizer.Add(self.onErr, 0, wx.LEFT, 5)
onRestartSizer.Add(self.onRestart, 1, wx.LEFT, 5)
onExcSizer.Add(self.onExc, 2, wx.LEFT, 5)
onHTSizer.Add(self.onHT, 0, wx.LEFT, 5)
onFtnftSizer.Add(self.onFtnft, 0, wx.LEFT, 5)
onDlockSizer.Add(self.onDlock, 0, wx.LEFT, 5)
self.mainSizer.Add(unameSizer, 0, wx.ALL|wx.CENTER, 5)
self.mainSizer.Add(pwdSizer, 0, wx.ALL|wx.CENTER, 5)
self.mainSizer.Add(btnSizer, 0, wx.ALL|wx.CENTER, 5)
self.mainSizer.Add(onErrSizer, 0, wx.ALL|wx.LEFT, 5)
self.mainSizer.Add(onRestartSizer, 0, wx.ALL|wx.LEFT, 5)
self.mainSizer.Add(onExcSizer, 0, wx.ALL|wx.LEFT, 5)
self.mainSizer.Add(onHTSizer, 0, wx.ALL|wx.LEFT, 5)
self.mainSizer.Add(onFtnftSizer, 0, wx.ALL|wx.LEFT, 5)
self.mainSizer.Add(onDlockSizer, 0, wx.ALL|wx.LEFT, 5)
self.panel.SetSizer(self.mainSizer)
self.panel.Layout()
self.Centre()
self.Show(True)
...
The mapping function is as follows:
def MapNetworkDrive(inpUsrName, inpPasswd):
try:
if os.path.exists("K:"):
network = win32com.client.Dispatch("WScript.Network")
network.RemoveNetworkDrive("K:", True, True)
resource = win32wnet.NETRESOURCE()
resource.lpRemoteName = "\\\\<serv_addr>\\<folder>"
win32wnet.WNetAddConnection2(resource, Password = inpPasswd, UserName = inpUsrName)
win32wnet.WNetAddConnection2(DISK, "K:", "\\\\<serv_addr>\\<folder>")
else:
resource = win32wnet.NETRESOURCE()
resource.lpRemoteName = "\\\\<serv_addr>\\<folder>"
win32wnet.WNetAddConnection2(resource, Password = inpPasswd, UserName = inpUsrName)
win32wnet.WNetAddConnection2(DISK, "K:", "\\\\<serv_addr>\\<folder>")
if os.path.exists("L:"):
network = win32com.client.Dispatch("WScript.Network")
network.RemoveNetworkDrive("L:", True, True)
resource = win32wnet.NETRESOURCE()
resource.lpRemoteName = "\\\\<serv_addr>\\<folder>"
win32wnet.WNetAddConnection2(resource, Password = inpPasswd, UserName = inpUsrName)
win32wnet.WNetAddConnection2(DISK, "L:", "\\\\<serv_addr>\\<folder>")
else:
nxresource = win32wnet.NETRESOURCE()
nxresource.lpRemoteName = "\\\\<serv_addr>\\<folder>"
win32wnet.WNetAddConnection2(nxresource, Password = inpPasswd, UserName = inpUsrName)
win32wnet.WNetAddConnection2(DISK, "L:", "\\\\<serv_addr>\\<folder>")
return True
except:
print "Username/password error"
Rest is easily understandable from the code. The main loop is as follows:
def main():
print "Working"
testApp = wx.App()
tpBox(None, title="Log Monitor Release Build Version 3.0", style=wx.MINIMIZE_BOX |
wx.SYSTEM_MENU | wx.CAPTION | wx.CLOSE_BOX)
testApp.MainLoop()
<serv_dir_name>serv = []
<serv_dir_name>serv = []
<serv_dir_name>serv = []
<serv_dir_name>serv = []
<serv_dir_name>app = []
<serv_dir_name>app = []
<serv_dir_name>app = []
<serv_dir_name>app = []
<serv_dir_name>serv = []
<serv_dir_name>serv = []
<serv_dir_name>serv = []
<serv_dir_name>serv = []
<serv_dir_name>app = []
<serv_dir_name>app = []
<serv_dir_name>app = []
<serv_dir_name>app = []
if os.path.isdir("C:\\temp"):
print '"temp" Dir found'
if os.path.isdir("C:\\temp\\final"):
print '"final" Dir found'
if os.path.isdir("C:\\temp\\final\\Server"):
print '"Server" Dir found'
else:
print 'Serv Dir not found, creating it...'
os.makedirs("C:\\temp\\final\\Server")
if os.path.isdir("C:\\temp\\final\\App"):
print '"Application" Dir found'
else:
print 'App Dir not found, creating it...'
os.makedirs("C:\\temp\\final\App")
if os.path.isdir("C:\\temp\\usrLogs"):
print 'User directory found'
else:
print 'Creating user directory'
os.makedirs("C:\\temp\\usrLogs")
else:
print 'final dir not found, creating it...'
os.makedirs("C:\\temp\\final")
print 'Also creating other dirs...'
os.makedirs("C:\\temp\\final\\Server")
os.makedirs("C:\\temp\\final\App")
os.makedirs("C:\\temp\\usrLogs")
print '\n\nRunning in background, will notify...\n\n'
else:
print 'Creating dirs...'
os.makedirs("C:\\temp")
os.makedirs("C:\\temp\\final")
os.makedirs("C:\\temp\\final\\Server")
os.makedirs("C:\\temp\\final\App")
os.makedirs("C:\\temp\\usrLogs")
print '\n\nRunning in background, will notify...\n\n'
global alertOnDb2
readBuffer = None
writeLogFile = None
global alertOnError
global alertOnRestart
global alertOnException
global alertOnHT
global alertOnFtnft
global alertOnDeadlock
if os.path.isfile("C:\\temp\\usrLogs\\userLog.lgm") and
os.access("C:\\temp\\usrLogs\\userLog.lgm", os.R_OK):
fileInst = open("C:\\temp\\usrLogs\\userLog.lgm", 'r')
readBuffer = fileInst.read()
fileInst.close()
elif os.path.isfile("C:\\temp\\usrLogs\\userLog.lgm")
and not os.access("C:\\temp\\usrLogs\\userLog.lgm", os.R_OK):
print 'File present but read stream corrupt'
else:
readBuffer = None
if readBuffer == None:
writeLogFile = open("C:\\temp\\usrLogs\\userLog.lgm", 'w')
writeLogFile.write(str(time.asctime(time.localtime(time.time()))) + '\n\n')
writeLogFile.write('Status Alert on error : ' + str(alertOnError) + '\n')
writeLogFile.write('Status Alert on restart : ' + str(alertOnRestart) + '\n')
writeLogFile.write('Status Alert on exception : ' + str(alertOnException) + '\n')
writeLogFile.write('Status Alert on Feature <*> Not Found : ' + str(alertOnFtnft) + '\n')
writeLogFile.write('Status Alert on Hung threads : ' + str(alertOnHT) + '\n')
writeLogFile.write('Status Alert on Deadlock : ' + str(alertOnDeadlock) + '\n')
writeLogFile.close()
else:
writeLogFile = open("C:\\temp\\usrLogs\\userLog.lgm", 'w')
readBuffer += '\n'
writeLogFile.write(readBuffer)
writeLogFile.write(str(time.asctime(time.localtime(time.time()))) + '\n\n')
writeLogFile.write('Status Alert on error : ' + str(alertOnError) + '\n')
writeLogFile.write('Status Alert on restart : ' + str(alertOnRestart) + '\n')
writeLogFile.write('Status Alert on exception : ' + str(alertOnException) + '\n')
writeLogFile.write('Status Alert on Feature <*> Not Found : ' + str(alertOnFtnft) + '\n')
writeLogFile.write('Status Alert on Hung threads : ' + str(alertOnHT) + '\n')
writeLogFile.write('Status Alert on Deadlock : ' + str(alertOnDeadlock) + '\n')
writeLogFile.close()
try:
while True:
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>SERV", <serv_dir_name>serv)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
readFile("<serv_jvm_name>APP", <serv_dir_name>app)
except:
wx.MessageBox('Exiting Application', "Log Monitor", wx.OK | wx.ICON_INFORMATION)
if __name__ == "__main__":
main()
Changes and improvement
I know a lot of changes can be done, but I have written this for the beginner. The image provided in this article is the actual version being run. Because of security issues, the names of the alert fields are not displayed. But the idea is simple. Please comment/write/modify at your own will and suggest methods.