Skip to content

Instantly share code, notes, and snippets.

@bicobus
Last active August 24, 2017 19:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bicobus/089a5f7460dd88dc450689557989100c to your computer and use it in GitHub Desktop.
Save bicobus/089a5f7460dd88dc450689557989100c to your computer and use it in GitHub Desktop.
Scan a papyrus log and summarize the existing stack dumps if any exists.
#!/usr/bin/env python3
# the goal here is to pull stack dumps per file and analyse what scripts were dumped
# might give us a clue as to what went wrong hopefully
# todo: add date of files when they were modified, size of files, to help identify if the files are the same
# maybe hash
# if more than one dump, print difference between the two time wise, we have stamps
# and/or give time of dump
import sys, os, re
from collections import Counter
script_pattern = re.compile('"[^"]*.psc"')
time_pattern = re.compile('\[.*\]')
# if no specific file is selected, do for all files in dir
fin_fnames = []
if len(sys.argv) > 1:
i=1
while i < len(sys.argv):
fin_fnames.append(sys.argv[i])
i+=1
del(i)
else:
for (dirpath, dirnames, filenames) in os.walk("."):
for f in filenames:
# Only append log files
if f[-4:] == ".log" or f[-8:] == ".log.bak":
fin_fnames.append(f)
break
if len(fin_fnames) == 0:
print("No file to parse.\nExiting...")
exit()
print(fin_fnames)
def analyse_file(file_name):
global script_pattern, time_pattern
with open(file_name,'r') as fin:
dump_active = False
stack_count = stack_line_count = line_count = 0
dump_output = ""
dump_timestamp = ""
# second part
psc_list = []
fstring = '{}: {}'
dump_str_pattern = "Dump {} @ line #{}\nTime of dump: {}\n"
psc_count = ""
# per line parser, easy enough
for line in fin:
line_count += 1
#if not dump_active and "dumping stacks" in line : # doesn't work because the VM thaws right after
if not dump_active and "Dumping stack " in line :
dump_active = True
stack_count += 1
stack_line_count = line_count
stack_timestamp = time_pattern.search(line).group()
elif dump_active and "VM is frozen" in line or "VM is thawing..." in line:
dump_active = False
# reorganize the lines we got
tmp = Counter(psc_list)
while len(tmp)>0:
try:
psc_count+= fstring.format(*tmp.popitem()) + "\n"
except KeyError:
break # Safeguard against empty dict, should never happen.
except Exception:
raise
# for some reason, we can reach this spot with a stack size of zero, when there's no stack and no lines of stack
# this is a temporary fix
if stack_count > 0 and stack_timestamp:
dump_output += dump_str_pattern.format(stack_count, stack_line_count, stack_timestamp)
dump_output += "-"*39 + "\n"
stack_timestamp = ""
for line in psc_count.splitlines():
if int(line.split()[1]) > 1:
dump_output += line + "\n"
dump_output += "+"*10 + "\n\n"
stack_line_count = 0
psc_list = []
# another usable line
if dump_active:
search_result = script_pattern.search(line)
if search_result :
psc_list.append((search_result.group()))
# dir(fin)
# import datetime
# print file_name + " (" + os.stat(file_name).st_mtime + ") " + str(line_count)
print("{} - With a total of {} lines.".format(file_name, line_count))
#print "lines of stack dump(s): " + str(stack_line_count)
print("dump count: " + str(stack_count))
print("="*13) # + "\n"
print(dump_output)
# now we need to sort the elements and print the sorted list
#if stack_count > 0:
#psc_count = str(Counter(psc_list)).replace('\'', '').replace('\"', '').replace('\\n', '').replace('Counter({', '')
#print psc_count.replace(", ", "\n")
# ------------------ main ------------------
if __name__ == '__main__':
for name in fin_fnames:
print("="*10)
analyse_file(name)
# windows cmd window lock open
raw_input("Press enter to exit ")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment