-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvdlogging.py
More file actions
133 lines (108 loc) · 4.09 KB
/
vdlogging.py
File metadata and controls
133 lines (108 loc) · 4.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# -*- coding: utf-8 -*-
"""
A module for logging
This module contains functions for creating and updating log files
"""
# Mozilla Public License 2.0 (MPL2)
#
# Copyright (c) 2025 Riley Ava
#
# The full licenese can be found at <https://www.mozilla.org/en-US/MPL/2.0/>
__author__ = "Riley Ava"
__version__ = "1.0.0"
__license__ = "MPL"
__email__ = "rileymeta@gmail.com"
import os
from sys import exit
from datetime import datetime
class Logging:
"""
A simple logging class for error tracking with automatic file versioning.
Creates timestamped log files with automatic version numbers to avoid
overwriting existing logs.
Example:
>>> L = Logging("my_program")
>>> L.log_event(404, "File not found")
>>> L.log_event(500, "Databse connection failed")
"""
def __init__(self, name: str, location: str = "/tmp/"):
"""
Initialize the logger with program name and optional location.
Args:
name (str): Name of the program/log file (without extension)
location (str): Directory to store log files. Defaults to "/tmp/"
Example:
>>> logger = Logging("my_app", "/var/log/")
>>> # Creates /var/log/my_app_1.log (or next available version)
"""
self.progstart = datetime.now()
self.location = location
self.name = name
self.log_path = self._get_log_version()
# Redundant, but make sure `/tmp/` exists
os.makedirs(self.location, exist_ok=True)
def _get_log_version(self):
"""
Find the next available version for the log file.
Returns:
str: Full path to the next available log file
Example:
If /tmp/myapp_1.log exists, returns /tmp/myapp_2.log
"""
version = 1
while True:
filename = f"{self.name}_{version}.log"
full_path = os.path.join(self.location, filename)
if not os.path.exists(full_path):
return full_path
version += 1
def _get_delta(self) -> str:
"""
Get time elapsed since program start as a formatted string.
Returns:
str: Formatted time delta (HH:MM:SS)
Example:
"0:01:23" (1 minute, 23 seconds since program start)
"""
timestamp = datetime.now() - self.progstart
return str(timestamp).split('.')[0]
def log_event(self, errnum: int, desc: str, error: bool = False):
"""
Log an error event with timestamp and error number.
Args:
errnum (int) : Error number/code for categorization
desc (str) : Description of the error that occurred
error (bool): Change how the event is labeled in the log
Example:
>>> L = Logging("myapp")
>>> try:
... open("nonexistent.txt", "r")
... except FileNotFoundError as e:
... L.log_event(404, f"File access failed: {e}")
Note:
Logs are appended to file in format:
"[LOG] {errnum} @ {timestamp}]: {desc}"
"[ERROR {errnum} @ {timestamp}]: {desc}"
"""
timestamp = self._get_delta()
try:
with open(self.log_path, 'a') as f:
f.write(f"[{"ERROR" if error else "LOG"} {errnum} @ {timestamp}]: {desc}\n")
except Exception as e:
print(f"Catastrophic Error during logging: {e}")
exit(255) # Catastrophic Error
def error(self, desc: str, errnum: int = 1, exit: bool = False):
"""
A simple console error with automatic logging.
Args:
errnum (int) : Error number/code for categorization
desc (str) : Description of the error that occurred
exit (bool): If the program should exit completely
Note:
All Errors are Events, but not all Events are Errors.
We allow you to use both individually for this exact reason.
"""
print(f"ERROR {errnum}: {desc}")
self.log_event(errnum, desc, error=True)
if exit:
exit(errnum)