Last active
July 29, 2021 10:21
-
-
Save rogfrich/de4ea9312268f9766c11eed339ffb49b to your computer and use it in GitHub Desktop.
My solution for the Real Python "Python Practice Problems" Exercise 4: Log Parser (https://realpython.com/python-practice-problems)
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
""" log parser | |
Accepts a filename on the command line. The file is a linux-like log file | |
from a system you are debugging. Mixed in among the various statements are | |
messages indicating the state of the device. They look like: | |
Jul 11 16:11:51:490 [139681125603136] dut: Device State: ON | |
The device state message has many possible values, but this program only | |
cares about three: ON, OFF, and ERR. | |
Your program will parse the given log file and print out a report giving | |
how long the device was ON, and the time stamp of any ERR conditions. | |
""" | |
import datetime, unittest | |
def find_err_status(line, timestamp): | |
if "ERR" in line: | |
return f"ERROR at timestamp: {timestamp}" | |
def convert_string_to_date_time_obj(timestamp): | |
timestamp_obj = datetime.datetime.strptime(timestamp, "%b %d %H:%M:%S:%f") | |
return timestamp_obj | |
def calculate_uptime(on_events, off_events): | |
uptime = datetime.timedelta(0) | |
for on, off in zip(on_events, off_events): | |
uptime += (off - on) | |
return uptime | |
class TestLogParse(unittest.TestCase): | |
def test_find_err_status(self): | |
err_status = find_err_status("Jul 11 16:11:54:661 [139681125603136] dut: Device State: ERR", | |
"Jul 11 16:11:54:661") | |
self.assertEqual(err_status, "ERROR at timestamp: Jul 11 16:11:54:661") | |
def test_convert_string_to_time(self): | |
time = convert_string_to_date_time_obj("Jul 11 16:11:51:490") | |
test_time = datetime.datetime.strptime("Jul 11 16:11:51:490", "%b %d %H:%M:%S:%f") | |
self.assertEqual(time, test_time) | |
def test_calculate_uptime(self): | |
on = convert_string_to_date_time_obj("Jul 11 16:11:51:490") | |
off = convert_string_to_date_time_obj("Jul 11 16:11:53:490") | |
uptime = calculate_uptime([on], [off]) | |
self.assertEqual(uptime, off - on) | |
if __name__ == "__main__": | |
with open("test.log") as fin: | |
on_events = [] | |
off_events = [] | |
for line in fin.readlines(): | |
full_date_time_stamp = line[0:19] | |
# Check whether there is an error code ("ERR") in the report line and print it if there is. | |
err_status = find_err_status(line, full_date_time_stamp) | |
if err_status: | |
print(err_status) | |
# Check if the report line is for an ON or OFF event, and build a list for each event type. | |
if "Device State: ON" in line or "Device State: OFF" in line: | |
datetime_obj = convert_string_to_date_time_obj(full_date_time_stamp[0:19]) | |
if "Device State: ON" in line: | |
on_events.append(datetime_obj) | |
elif "Device State: OFF" in line: | |
off_events.append(datetime_obj) | |
else: | |
print("No ON or OFF events in log file") | |
uptime = calculate_uptime(on_events, off_events) | |
print(f"The device was ON for: {uptime}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment