Tested.
In use at work. "If I return too many results, I cause a BSOD. I eat your non-paged pool for breakfast."to do: if query returns over 50 lines, prompt to continue... option to suppress this prompt. option to suppress command-line output.
Currently, the --parse option must fall before any other option in order to have the program function properly. This is to reduce the use of Global variables.
### input: me.py --file [syslog file] --find [find string] | --parse [comma-seperated list of tokens],[delimiter] | --email [email address]
### --email is an optional argument, and can be a single email address or a semi-colon seperated list
### output: return line(s) where string is located
### handle arguments (requiring both --file and --find)
### check if input file exists
### open file for read
#### read line by line checking to see if --find [string] is located
#### create an array and write the lines to it
### close file
### print contents of array
### if email argument exists, send email to given address
import sys
import getopt
import os
def main():
Arguments()
def Arguments():
# the main purpose of this function is to only evaluate arguments.
# it is not really to be used to perform other functions, but to call other functions.
try:
opts, args = getopt.getopt(sys.argv[1:], "f:,q:,p:,e:,d:,", ["file=", "find=", "parse=", "email=",])
except getopt.GetoptError, err:
YouErroredMe(str(err))
if len(sys.argv) == 1:
YouNeedHelp()
for opt, arg in opts:
if opt in ( "--parse" ): #take delimiter, and tokens
try:
#take the characters in the string to the left of the first : (from the left) :
strTokens = arg[0:arg.find(":")]
#make a list of these comma-seperated tokens, by using the string.split function :
global Tokens
Tokens = strTokens.split(",")
if len(Tokens) < 1:
YouErroredMe("You must give me some tokens. You want me to return nothing?")
#take the characters in the string to the right of the first : (from the left) :
global Delimiter
Delimiter = arg[arg.find(":")+1:len(arg)]
if len(Delimiter) < 1:
YouErroredMe("You must give me a delimiter with your tokens. You want me to return the whole line?")
except:
continue
elif opt in ( "--file" ):
strInputFile = arg
CheckIfFileExists( strInputFile )
elif opt in ( "--find" ):
strFindString = arg
CheckForStringInFile( strInputFile, strFindString )
elif opt in ("--email"):
try: #should be checking if Lines exists/has any members, what the vartype is???
strEmailAddress = arg
strEmailAddress = strEmailAddress.split(";")
Mailer( "ParserAlert", strEmailAddress, "Found " + strFindString + " in " + strInputFile, Lines)
except:
continue
def CheckIfFileExists( passFileName ):
if os.path.getsize( passFileName ) == 0:
YouErroredMe( "The file provided is 0 long. Give me some sugar." )
def CheckForStringInFile( passFileName, passFindString ):
objFile = open ( passFileName )
global Lines
Lines = "\n"
FoundLines = []
for line in objFile:
if line.count( passFindString ) <> 0:
FoundLines.append(line)
for line in FoundLines:
#if parse tokens and delimiter exist...
try:
if len(Tokens) > 0:
for item in Tokens:
Lines = Lines + line.split(str(Delimiter))[int(item)] + "\n"
except:
Lines = Lines + line
print Lines
if len(FoundLines) < 1:
print "String " + passFindString + " not found in file " + passFileName + "."
objFile.close
sys.exit()
objFile.close
def Mailer( passFromAddr, passToAddr, passSubject, passMessage ):
import smtplib
FROM = passFromAddr
TO = passToAddr
SUBJECT = passSubject
TEXT = passMessage
# Prepare actual message
message = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n %s" % (FROM, TO, SUBJECT, TEXT)
# Send the mail
server = smtplib.SMTP( "domain.com" )
errStatus = server.sendmail(FROM, TO, message)
for errorItem in errStatus:
print ""
print "SMTP Error: " + errorItem
## LogMe( "ERROR,smtp,%m,%d,%Y,%H:%M:%S,domain.com," + FROM + "," + TO + "," + errorItem )
server.quit()
return
def YouErroredMe( passError ):
print ""
print passError
print "/\\__/\\"
print ""
YouNeedHelp()
return
def YouNeedHelp():
print ""
print "input: me.py --parse [tokens]:[delimiter] --file [log file] --find [find string] --email [email address]"
print ""
print ""
print "--parse is an optional argument and must be before --file or --find. It can be a comma-seperated list of tokens, followed by a colon, followed by the delimiter. It will return this given subset only."
print "--email is an optional argument. It can be a single Email address, or a semi-colon seperated list."
print ""
print "output: return line(s) where string is located"
print ""
print "Examples:"
print "me.py --file syslog.txt --find subtype=sslvpn --email mbrown@domain.com"
print "me.py --file syslog.txt --find subtype=sslvpn --email mbrown@domain.com;helpdesk@domain.com"
print "me.py --parse 5,6,7:; --file syslog.txt --find subtype=sslvpn --email mbrown@domain.com;helpdesk@domain.com"
sys.exit()
return
main()
Output from a syslog from a Fortinet:
logparser.py --parse 0,4,9,10,11,12,13,14:, --file syslog.log --find sslvpn
Jan 4 13:27:55 192.168.1.1 date=2009-01-04
log_id=0132099601
user="username"
rip="4.2.2.1"
action=login
status=success
reason=none
msg="User username login successfully from 4.2.2.1"
Jan 4 13:36:13 192.168.1.1 date=2009-01-04
log_id=0132099604
user="username"
rip=4.2.2.1
action=logout
status=success
reason=timeout
msg="SSL VPN web access session timeout from 4.2.2.1"