Skip to content

Commit 8994622

Browse files
Decorator log update (#141)
## Pull Request Template ### Prerequisites <!-- Take a couple of minutes to help our maintainers work faster by checking of the pre-requisites. --> <!-- To tick the checkboxes replace the space with an 'x', so [ ] becomes [x] . --> - [x] I have [searched](https://github.com/DefinetlyNotAI/Logicytics/pulls) for duplicate or closed issues. - [x] I have read the [contributing guidelines](https://github.com/DefinetlyNotAI/Logicytics/blob/main/CONTRIBUTING.md). - [x] I have followed the instructions in the [wiki](https://github.com/DefinetlyNotAI/Logicytics/wiki) about contributions. - [x] I have updated the documentation accordingly, if required. - [x] I have tested my code with the `--dev` flag, if required. ### PR Type <!-- Take a couple of minutes to help our maintainers work faster by telling us what is the PR guided on. --> <!-- To tick the checkboxes replace the space with an 'x', so [ ] becomes [x] . --> - [x] Bug fix <!-- Non-Breaking Bug Fix - Usually relates to fixing an issue --> - [x] New feature <!-- Non-Breaking Change that adds a new feature --> - [ ] Refactoring <!-- Non-Breaking Change that modifies existing code to refactor it to become more organised --> - [ ] Documentation update <!-- Non-Breaking Change that modifies existing documentation to refactor it or add extra comments - either wiki, md files or code is included here --> - [ ] ⚠️ Breaking change ⚠️ <!-- Breaking Bug Fix / New Addition that changes how Logicytics works --> ### Description <!-- REQUIRED: Provide a summary of the PR and what you expected to happen. --> Added a new `log.function` decorator, this allows to debug time run by a function as well as debug the function name for development purposes, also fixed minor bugs and removed redundant feature ### Motivation and Context <!-- REQUIRED: Why is this PR required? What problem does it solve? Why do you want to do it? --> Solves plans and fixes minor bugs ### Credit <!-- If this PR is a contribution, please mention the contributors here using the appropriate syntax. --> <!-- ### File-Created/CONTRIBUTION by MAIN-Username What you did, created, removed, refactored, fixed, or discovered. - [Your GitHub Username](https://github.com/YourGitHubLink) - [Your GitHub Username](https://github.com/YourGitHubLink) etc... --> _N/A_ ### Issues Fixed <!-- REQUIRED: What issues will be fixed? (Format: "#50, #23" etc.) if none exist type _N/A_ --> _N/A_
2 parents 8a1c6f0 + a0312df commit 8994622

21 files changed

+104
-114
lines changed

CODE/Logicytics.py

Lines changed: 15 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,19 @@
11
from __future__ import annotations
22

3-
import datetime
43
import threading
54
from typing import Any
65

76
from __lib_class import *
87

9-
"""
10-
This python script is the main entry point for the tool called Logicytics.
11-
The script performs various actions based on command-line flags and configuration settings.
128

13-
Here's a high-level overview of what the script does:
14-
15-
1. Initializes directories and checks for admin privileges.
16-
2. Parses command-line flags and sets up logging.
17-
3. Performs special actions based on flags, such as debugging, updating, or restoring backups.
18-
4. Creates an execution list of files to run, which can be filtered based on flags.
19-
5. Runs the files in the execution list, either sequentially or in parallel using threading.
20-
6. Zips generated files and attempts to delete event logs.
21-
7. Performs sub-actions, such as shutting down or rebooting the system, or sending a webhook.
22-
23-
The script appears to be designed to be highly configurable and modular,
24-
with many options and flags that can be used to customize its behavior.
25-
"""
9+
# Initialization
10+
FileManagement.mkdir()
11+
log = Log({"log_level": DEBUG})
2612

2713

2814
class Health:
2915
@staticmethod
16+
@log.function
3017
def backup(directory: str, name: str):
3118
"""
3219
Creates a backup of a specified directory by zipping its contents and moving it to a designated backup location.
@@ -53,6 +40,7 @@ def backup(directory: str, name: str):
5340
shutil.move(f"{name}.zip", "../ACCESS/BACKUP")
5441

5542
@staticmethod
43+
@log.function
5644
def update() -> tuple[str, str]:
5745
"""
5846
Updates the repository by pulling the latest changes from the remote repository.
@@ -79,6 +67,7 @@ def update() -> tuple[str, str]:
7967
return output, "info"
8068

8169

70+
@log.function
8271
def get_flags() -> tuple[str, str]:
8372
"""
8473
Retrieves the command-line flags and sub-actions.
@@ -106,6 +95,7 @@ def get_flags() -> tuple[str, str]:
10695
return actions, sub_actions
10796

10897

98+
@log.function
10999
def special_execute(file_path: str):
110100
"""
111101
Executes a Python script in a new command prompt window.
@@ -120,6 +110,7 @@ def special_execute(file_path: str):
120110
exit(0)
121111

122112

113+
@log.function
123114
def handle_special_actions():
124115
"""
125116
Handles special actions based on the provided action flag.
@@ -186,6 +177,7 @@ def handle_special_actions():
186177
exit(0)
187178

188179

180+
@log.function
189181
def check_privileges():
190182
"""
191183
Checks if the script is running with administrative privileges and handles UAC (User Account Control) settings.
@@ -207,6 +199,7 @@ def check_privileges():
207199
log.warning("UAC is enabled, this may cause issues - Please disable UAC if possible")
208200

209201

202+
@log.function
210203
def generate_execution_list(actions: str) -> list | list[str] | list[str | Any]:
211204
"""
212205
Creates an execution list based on the provided action.
@@ -269,32 +262,15 @@ def generate_execution_list(actions: str) -> list | list[str] | list[str | Any]:
269262
return execution_list
270263

271264

272-
def attempt_hide():
273-
"""
274-
Attempts to delete Windows event logs from the current day.
275-
276-
Parameters:
277-
None
278-
279-
Returns:
280-
None
281-
"""
282-
today = datetime.date.today()
283-
log_path = r"C:\Windows\System32\winevt\Logs"
284-
285-
for file in os.listdir(log_path):
286-
if file.endswith(".evtx") and file.startswith(today.strftime("%Y-%m-%d")):
287-
subprocess.run(f'del "{os.path.join(log_path, file)}"', shell=False)
288-
289-
265+
@log.function
290266
def execute_scripts():
291267
"""Executes the scripts in the execution list based on the action."""
292268
# Check weather to use threading or not, as well as execute code
293269
if action == "threaded" or action == "depth":
294270
def threaded_execution(execution_list_thread, index_thread):
295271
log.debug(f"Thread {index_thread} started")
296272
try:
297-
log.execute_log_parse(Execute.script(execution_list_thread[index_thread]))
273+
log.parse_execution(Execute.script(execution_list_thread[index_thread]))
298274
log.info(f"{execution_list_thread[index_thread]} executed")
299275
except UnicodeDecodeError as err:
300276
log.error(f"Error in thread: {err}")
@@ -322,14 +298,15 @@ def threaded_execution(execution_list_thread, index_thread):
322298
try:
323299
execution_list = generate_execution_list(action)
324300
for file in range(len(execution_list)): # Loop through List
325-
log.execute_log_parse(Execute.script(execution_list[file]))
301+
log.parse_execution(Execute.script(execution_list[file]))
326302
log.info(f"{execution_list[file]} executed")
327303
except UnicodeDecodeError as e:
328304
log.error(f"Error in code: {e}")
329305
except Exception as e:
330306
log.error(f"Error in code: {e}")
331307

332308

309+
@log.function
333310
def zip_generated_files():
334311
"""Zips generated files based on the action."""
335312

@@ -347,6 +324,7 @@ def zip_and_log(directory, name):
347324
zip_and_log(".", "CODE")
348325

349326

327+
@log.function
350328
def handle_sub_action():
351329
"""
352330
Handles sub-actions based on the provided sub_action flag.
@@ -363,11 +341,7 @@ def handle_sub_action():
363341
# log.warning("This feature is not implemented yet! Sorry")
364342

365343

366-
# Initialization
367-
FileManagement.mkdir()
368-
369344
if __name__ == "__main__":
370-
log = Log({"log_level": DEBUG})
371345
# Get flags and configs
372346
action, sub_action = get_flags()
373347
# Check for special actions
@@ -379,8 +353,6 @@ def handle_sub_action():
379353
execute_scripts()
380354
# Zip generated files
381355
zip_generated_files()
382-
# Attempt event log deletion
383-
attempt_hide()
384356
# Finish with sub actions
385357
log.info("Completed successfully!")
386358
# Finish with sub actions

CODE/__lib_class.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,14 @@
44
import ctypes
55
import hashlib
66
import json
7-
import os
87
import os.path
98
import shutil
109
import subprocess
1110
import zipfile
12-
from datetime import datetime
1311
from pathlib import Path
1412
from subprocess import CompletedProcess
1513

16-
from __lib_log import Log
14+
from __lib_log import *
1715

1816

1917
class Flag:
@@ -316,7 +314,7 @@ class Zip:
316314
__move_files(filename: str):
317315
Moves the zip file and its hash file to designated directories.
318316
319-
and_hash(self, path: str, name: str, flag: str) -> tuple | str:
317+
and_hash(cls, path: str, name: str, flag: str) -> tuple | str:
320318
Zips files, generates a SHA256 hash, and moves the files.
321319
"""
322320

CODE/__lib_log.py

Lines changed: 34 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,25 @@ def __pad_message(message: str) -> str:
102102
else message[:150] + "..."
103103
) + "|"
104104

105+
def __internal(self, message):
106+
"""
107+
Logs an internal message.
108+
109+
:param message: The internal message to be logged.
110+
"""
111+
if self.color and message != "None" and message is not None:
112+
colorlog.log(self.INTERNAL_LOG_LEVEL, str(message))
113+
114+
@staticmethod
115+
def debug(message):
116+
"""
117+
Logs a debug message.
118+
119+
:param message: The debug message to be logged.
120+
"""
121+
if message != "None" and message is not None:
122+
colorlog.debug(str(message))
123+
105124
def raw(self, message):
106125
"""
107126
Logs a raw message directly to the log file.
@@ -172,16 +191,6 @@ def critical(self, message):
172191
f"[{self.__timestamp()}] > CRITICAL: | {self.__pad_message(str(message))}"
173192
)
174193

175-
@staticmethod
176-
def debug(message):
177-
"""
178-
Logs a debug message.
179-
180-
:param message: The debug message to be logged.
181-
"""
182-
if message != "None" and message is not None:
183-
colorlog.debug(str(message))
184-
185194
def string(self, message, type: str):
186195
"""
187196
Logs a message with a specified type. Supported types are 'debug', 'info', 'warning', 'error', 'critical'
@@ -212,21 +221,26 @@ def exception(self, message, exception_type: Type = Exception):
212221
)
213222
raise exception_type(message)
214223

215-
def __internal(self, message):
216-
"""
217-
Logs an internal message.
218-
219-
:param message: The internal message to be logged.
220-
"""
221-
if self.color and message != "None" and message is not None:
222-
colorlog.log(self.INTERNAL_LOG_LEVEL, str(message))
223-
224-
def execute_log_parse(self, message_log):
224+
def parse_execution(self, message_log: list[list[str]]):
225225
if message_log:
226226
for message_list in message_log:
227227
if len(message_list) == 2:
228228
self.string(message_list[0], message_list[1])
229229

230+
def function(self, func: callable):
231+
def wrapper(*args, **kwargs):
232+
if not callable(func):
233+
self.exception(f"Function {func.__name__} is not callable.",
234+
TypeError)
235+
start_time = datetime.now()
236+
self.debug(f"Running the function {func.__name__}().")
237+
result = func(*args, **kwargs)
238+
end_time = datetime.now()
239+
elapsed_time = end_time - start_time
240+
self.debug(f"Function {func.__name__}() executed in {elapsed_time}.")
241+
return result
242+
return wrapper
243+
230244

231245
if __name__ == "__main__":
232246
Log().exception(

CODE/__wrapper__.py

Lines changed: 0 additions & 27 deletions
This file was deleted.

CODE/_debug.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212

1313
class HealthCheck:
14+
@log_debug.function
1415
def get_online_config(
1516
self,
1617
) -> bool | tuple[tuple[str, str, str], tuple[str, str, str]]:
@@ -92,7 +93,8 @@ def __check_files(local_files: list, remote_files: list) -> tuple[str, str, str]
9293

9394
class DebugCheck:
9495
@staticmethod
95-
def SysInternal_Binaries(path: str) -> tuple[str, str]:
96+
@log_debug.function
97+
def sys_internal_binaries(path: str) -> tuple[str, str]:
9698
"""
9799
Checks the contents of the given path and determines the status of the SysInternal Binaries.
98100
@@ -135,6 +137,7 @@ def SysInternal_Binaries(path: str) -> tuple[str, str]:
135137
return f"An Unexpected error occurred: {e}", "ERROR"
136138

137139
@staticmethod
140+
@log_debug.function
138141
def execution_policy() -> bool:
139142
"""
140143
Checks the current PowerShell execution policy.
@@ -150,6 +153,7 @@ def execution_policy() -> bool:
150153
return result.stdout.strip().lower() == "unrestricted"
151154

152155
@staticmethod
156+
@log_debug.function
153157
def cpu_info() -> tuple[str, str, str]:
154158
"""
155159
Retrieves information about the CPU.
@@ -164,6 +168,7 @@ def cpu_info() -> tuple[str, str, str]:
164168
)
165169

166170

171+
@log_debug.function
167172
def debug():
168173
"""
169174
Performs a series of system checks and logs the results.
@@ -181,7 +186,7 @@ def debug():
181186
log_debug.string(file_tuple[0], file_tuple[2])
182187

183188
# Check SysInternal Binaries
184-
message, type = DebugCheck.SysInternal_Binaries("SysInternal_Suite")
189+
message, type = DebugCheck.sys_internal_binaries("SysInternal_Suite")
185190
log_debug.string(message, type)
186191

187192
# Check Admin

CODE/_dev.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
from __lib_class import *
44

5+
if __name__ == "__main__":
6+
log_dev = Log({"log_level": DEBUG})
7+
58

69
class Dev:
710
@staticmethod
@@ -54,6 +57,7 @@ def __prompt_user(question: str, file_to_open: str = None, special: bool = False
5457
except Exception as e:
5558
log_dev.error(e)
5659

60+
@log_dev.function
5761
def dev_checks(self) -> str | None:
5862
"""
5963
Performs a series of checks to ensure that the developer has followed the required guidelines and best practices.
@@ -93,8 +97,6 @@ def dev_checks(self) -> str | None:
9397
return str(e)
9498

9599

96-
if __name__ == "__main__":
97-
log_dev = Log({"log_level": DEBUG})
98100
message = Dev().dev_checks()
99101
if message is not None:
100102
log_dev.error(message)

CODE/_extra.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
log = Log({"log_level": DEBUG})
1212

1313

14+
@log.function
1415
def menu():
1516
"""
1617
Displays a menu of available executable scripts in the '../EXTRA/EXTRA' directory,

CODE/cmd_commands.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
log = Log({"log_level": DEBUG})
55

66

7+
@log.function
78
def command(file: str, commands: str, message: str, encoding: str = "UTF-8") -> None:
89
"""
910
Executes a command and writes the output to a file.

0 commit comments

Comments
 (0)