Last active
June 22, 2018 19:39
-
-
Save nbr23/1c2f6ab486ff39e5b70e016c672589ef to your computer and use it in GitHub Desktop.
Parse SAP's available.log file to create an SLA calculation Excel spreadsheet
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #! /usr/bin/python3 | |
| import calendar | |
| import re | |
| import sys | |
| import os | |
| from dateutil.parser import parse | |
| import datetime | |
| def write_csv(downtimes, output, show_month=None): | |
| with open(output, 'w+') as f: | |
| i = 1 | |
| for month in sorted(downtimes.keys()): | |
| if show_month and show_month != month: | |
| continue | |
| f.write('Start,End,Downtime in seconds,Downtime,Planned?,Comment\n') | |
| i = i + 1 | |
| first_row = i | |
| total_sec = downtimes[month]['days'] * 24 * 60 * 60 | |
| for begin, end in downtimes[month]['downtimes']: | |
| sec = (end - begin).total_seconds() | |
| f.write('"=""%s""","=""%s""",%i,"=""%s""",No,\n' % | |
| (begin, | |
| end, | |
| sec, | |
| str(datetime.timedelta(seconds=sec)), | |
| )) | |
| i = i + 1 | |
| last_row = i - 1 | |
| f.write('\nMonth,Downtime in seconds,Downtime in minutes,SLA\n') | |
| i = i + 2 | |
| f.write('"=""%s""","=SUMIF(E%i:E%i,""No"",C%i:C%i)","=TEXT(TIME(INT(B%i/3600),MOD(INT(B%i/60),60),MOD(B%i, 60)), ""h:mm"")","=100-(((B%i)/%i)*100)"\n\n\n\n\n' % (month, first_row, last_row, first_row, last_row, i, i, i, i, total_sec)) | |
| i = i + 5 | |
| def append_downtime(downtimes, begin, end): | |
| month = '%i/%02d' % (begin.year, begin.month) | |
| if month not in downtimes: | |
| _, days = calendar.monthrange(begin.year, begin.month) | |
| downtimes[month] = {'days': days, 'downtimes': []} | |
| downtimes[month]['downtimes'].append((begin, end)) | |
| return downtimes | |
| def parse_log(logfile): | |
| with open(logfile) as f: | |
| downtimes = {} | |
| for line in f: | |
| if 'Unavailable' in line: | |
| match = re.search(r'Unavailable ([0-9.]+) ([0-9:]+) - ([0-9.]+) ([0-9:]+)', line) | |
| if match: | |
| begin = parse('%s %s' % (match.group(1), match.group(2)), dayfirst=True) | |
| end = parse('%s %s' % (match.group(3), match.group(4)), dayfirst=True) | |
| if begin.year == end.year and \ | |
| begin.month == end.month: | |
| downtimes = append_downtime(downtimes, begin, end) | |
| else: | |
| _, last_day = calendar.monthrange(begin.year, begin.month) | |
| end_of_month = parse('%s.%s.%s 23:59:59' % (last_day, begin.month, begin.year), dayfirst=True) | |
| beginning_of_month = parse('01.%s.%s 00:00:00' % (end.month, end.year), dayfirst=True) | |
| downtimes = append_downtime(downtimes, begin, end_of_month) | |
| downtimes = append_downtime(downtimes, beginning_of_month, end) | |
| return downtimes | |
| def process_available_log(input_file, output_file, date_filter): | |
| downtimes = parse_log(input_file) | |
| write_csv(downtimes, output_file, date_filter) | |
| def main(): | |
| if len(sys.argv) < 3: | |
| print('Usage: ./%s (<available.log> | <available_log_files_dir>) (<destination.csv> | <destination_dir>) [date_filter]' % sys.argv[0]) | |
| return 1 | |
| input_str = sys.argv[1] | |
| output_str = sys.argv[2] | |
| date_filter = sys.argv[3] if len(sys.argv) == 4 else None | |
| if os.path.isdir(input_str): | |
| for _, _, files in os.walk(input_str): | |
| if not os.path.isdir(output_str): | |
| print('Please specify destination directory when using directory as input.') | |
| return 1 | |
| for filename in files: | |
| fname, _ = os.path.splitext(filename) | |
| process_available_log('%s/%s' % (input_str, filename), | |
| '%s/%s.csv' % (output_str, fname), | |
| date_filter) | |
| else: | |
| if os.path.isdir(output_str): | |
| out = '%s/%s.csv' % (output_str, os.path.splitext(os.path.basename(input_str))) | |
| else: | |
| out = output_str | |
| process_available_log(input_str, out, date_filter) | |
| if __name__ == "__main__": | |
| sys.exit(main()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment