Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / Python

Text monitor in a supremely slow virtual machine

1.00/5 (1 vote)
8 Jan 2013CPOL1 min read 9.5K   26  
Bare minimum code to monitor data files written by server processes.

Sample Image

Introduction

Manual monitoring of text data made easy Smile | :)

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.

Python
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:

Python
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) # check after this

self.panel.SetSizer(self.mainSizer)
self.panel.Layout()

self.Centre()
self.Show(True)
...

The mapping function is as follows:

Python
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>"

            # 41 -> K:

            # Connect to that remote drive using the win32 connection man
            win32wnet.WNetAddConnection2(resource, Password = inpPasswd, UserName = inpUsrName)
            win32wnet.WNetAddConnection2(DISK, "K:", "\\\\<serv_addr>\\<folder>")
        else:
            resource = win32wnet.NETRESOURCE()
            resource.lpRemoteName = "\\\\<serv_addr>\\<folder>"

            # 41 -> K: || 42 -> L:

            # Connect to that remote drive using the win32 connection man
            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>"

            # 42 -> L:

            # Connect to that remote drive using the win32 connection man
            win32wnet.WNetAddConnection2(resource, Password = inpPasswd, UserName = inpUsrName)
            win32wnet.WNetAddConnection2(DISK, "L:", "\\\\<serv_addr>\\<folder>")

        else:
            nxresource = win32wnet.NETRESOURCE()
            nxresource.lpRemoteName = "\\\\<serv_addr>\\<folder>"

            # Connect to that remote drive using the win32 connection man
            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:

Python
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)  # no_maximize

    testApp.MainLoop()

    # 41 Litsts
    <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 = []    

    # 42 Lists
    <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 = []

    # Need to write an overloaded readFile function for reading the SOA Log file
    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

    # Check if file exists or not
    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)
        # _asm --> spoiler
        # mov ah, 00h
        # int 21h --> bad practice, not always clears the buffer mem

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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)