Skip to content

Instantly share code, notes, and snippets.

@nbr23
Last active June 22, 2018 19:39
Show Gist options
  • Select an option

  • Save nbr23/1c2f6ab486ff39e5b70e016c672589ef to your computer and use it in GitHub Desktop.

Select an option

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
#! /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