diff --git a/.gitignore b/.gitignore index 0bb204ce..01b4fb71 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ python/*/__pycache__/ python/.vscode/ python/*/log/ python/.xray-configs +python/result/ .tmp golang/CFScanner windows/*.rsuser diff --git a/python/README.md b/python/README.md index 5da10ebc..930ec36b 100644 --- a/python/README.md +++ b/python/README.md @@ -220,6 +220,9 @@ Contributors names and contact info * 1.2.1 * Fixed the bug for keyboard interrupt in windows * improved the keyboard interrupt handling in general +* 1.2.2 + * Improved error logging + * Errors are logged into a file in case of an unexpected error [python]: https://img.shields.io/badge/-Python-3776AB?logo=python&logoColor=white [version]: https://img.shields.io/badge/Version-1.2.1-blue diff --git a/python/args/parser.py b/python/args/parser.py index f2205b2e..6e443c0a 100644 --- a/python/args/parser.py +++ b/python/args/parser.py @@ -1,8 +1,9 @@ import argparse -from report.print import color_text from rich.console import Console +from report.print import color_text + console = Console() diff --git a/python/args/testconfig.py b/python/args/testconfig.py index 92b5bce6..8de1f7e3 100644 --- a/python/args/testconfig.py +++ b/python/args/testconfig.py @@ -2,14 +2,13 @@ import json import os +from utils.exceptions import * from utils.exceptions import BinaryNotFoundError, TemplateReadError from utils.os import detect_system from utils.requests import download_file from xray import templates from xray.binary import download_binary -from utils.exceptions import * - PATH = os.path.dirname(os.path.abspath(__file__)) PARENT_PATH = os.path.dirname(PATH) diff --git a/python/cfscanner.py b/python/cfscanner.py index 192cfaec..57a396a4 100644 --- a/python/cfscanner.py +++ b/python/cfscanner.py @@ -17,6 +17,7 @@ from subnets import cidr_to_ip_list, get_num_ips_in_cidr, read_cidrs from utils.exceptions import * from utils.os import create_dir +import logging console = Console() @@ -36,6 +37,13 @@ def _init_pool(): START_DT_STR = datetime.now().strftime(r"%Y%m%d_%H%M%S") INTERIM_RESULTS_PATH = os.path.join(RESULTDIR, f'{START_DT_STR}_result.csv') +log_dir = os.path.join(SCRIPTDIR, "log") +os.makedirs(log_dir, exist_ok=True) +logging.basicConfig( + filename=os.path.join(log_dir, f"{START_DT_STR}.log") +) + +logger = logging.getLogger(__name__) if __name__ == "__main__": console = Console() @@ -50,7 +58,8 @@ def _init_pool(): try: create_dir(CONFIGDIR) except Exception as e: - console.log("[red]Could not created config directory[/red]") + console.log("[red]Could not create config directory[/red]") + logging.exception("Could not create config directory") exit(1) console.log(f"[blue]Config directory created \"{CONFIGDIR}\"[/blue]") configFilePath = args.config_path @@ -60,6 +69,8 @@ def _init_pool(): create_dir(RESULTDIR) except Exception as e: console.log("[red]Could not create results directory[/red]") + logging.exception("Could not create results directory") + exit(1) console.log(f"[blue]Results directory created \"{RESULTDIR}\"[/blue]") # create empty result file @@ -86,6 +97,8 @@ def _init_pool(): console.log( f"[red]Could not create empty result file:\n\"{INTERIM_RESULTS_PATH}\"[/red]" ) + logging.exception("Could not create empty result file") + exit(1) threadsCount = args.threads @@ -95,9 +108,11 @@ def _init_pool(): cidr_list = read_cidrs(args.subnets) except SubnetsReadError as e: console.log(f"[red]Could not read subnets. {e}[/red]") + logging.exception("Could not read subnets") exit(1) except Exception as e: console.log(f"Unknown error in reading subnets: {e}") + logging.exception("Unknown error in reading subnets") exit(1) console.log( f"[blue]Subnets successfully read from \"{args.subnets}\"[/blue]") @@ -119,9 +134,11 @@ def _init_pool(): exit(1) try: test_config = TestConfig.from_args(args) - except TemplateReadError: + except TemplateReadError as e: console.log( - f"[red]Could not read template from file \"{args.template_path}\"[/red]") + f"[red]Could not read template from file \"{args.template_path}\"[/red]" + ) + logger.exception(e) exit(1) except BinaryNotFoundError: console.log( @@ -206,6 +223,8 @@ def _init_pool(): progress.stop() console.log(f"[red]{e}[/red]") pool.terminate() + logging.exception("Error in starting xray service.") + break except StopIteration as e: for task in progress.tasks: progress.stop_task(task.id) @@ -225,3 +244,4 @@ def _init_pool(): except Exception as e: progress.log("[red]Unknown error![/red]") console.print_exception() + logging.exception(e) diff --git a/python/report/print.py b/python/report/print.py index 68463553..20870619 100644 --- a/python/report/print.py +++ b/python/report/print.py @@ -1,7 +1,9 @@ -from . import Colors +from statistics import mean from subprocess import Popen + from speedtest.tools import mean_jitter -from statistics import mean + +from . import Colors def no_and_kill( @@ -43,23 +45,21 @@ def ok_message( f"avg_down_jitter: {down_mean_jitter:7.2f}ms "\ f"avg_up_jitter: {up_mean_jitter:4.2f}ms"\ f"[/blue]" - - - + + def color_text(text: str, rgb: tuple, bold: bool = False): """prints a colored text in the terminal using ANSI escape codes based on the rgb values Args: text (str): the text to be printed rgb (tuple): the rgb values of the color - """ + """ if bold: return f"\033[1m\033[38;2;{rgb[0]};{rgb[1]};{rgb[2]}m{text}\033[m" else: return f"\033[38;2;{rgb[0]};{rgb[1]};{rgb[2]}m{text}\033[m" - def box_text(text: str): """prints a box around the text @@ -68,15 +68,15 @@ def box_text(text: str): Returns: str: the text with the box around it - """ + """ lines = text.splitlines() max_width = max(len(line) for line in lines) - + # Define the ANSI escape codes for the header HEADER_COLOR = '\033[38;2;64;224;208m' BORDER_COLOR = '\033[38;2;100;100;100m' BOX_WIDTH = max_width + 10 - + res_text = "" # Print the header with a colored border @@ -84,5 +84,5 @@ def box_text(text: str): for line in lines: res_text += f"{BORDER_COLOR}|{HEADER_COLOR}{line.center(BOX_WIDTH - 2)}{BORDER_COLOR}|\n" res_text += f"{BORDER_COLOR}{'+' + '-' * (BOX_WIDTH - 2) + '+'}\033[m" - + return res_text diff --git a/python/speedtest/conduct.py b/python/speedtest/conduct.py index 7d7dd030..49770b03 100644 --- a/python/speedtest/conduct.py +++ b/python/speedtest/conduct.py @@ -1,6 +1,5 @@ -import statistics - import requests + from args.testconfig import TestConfig from report.print import no_and_kill, ok_message from utils.decorators import timeout_fun @@ -13,7 +12,6 @@ from .upload import upload_speed_test - class TestResult: """class to store test results """ @@ -101,8 +99,10 @@ def test_ip( ) except Exception as e: test_result.is_ok = False - raise StartProxyServiceError(f"Could not start xray service - {ip}") - + raise StartProxyServiceError( + f"Could not start xray service - {ip}" + ) + else: process = _FakeProcess() proxies = None @@ -134,8 +134,8 @@ def timeout_download_fun(): return test_result except Exception as e: fail_msg = no_and_kill( - ip=ip, - message="download unknown error", + ip=ip, + message="download unknown error", process=process ) test_result.message = fail_msg @@ -213,7 +213,7 @@ def timeout_download_fun(): process.kill() test_ok_msg = ok_message(test_result.result) - + test_result.is_ok = True test_result.message = test_ok_msg return test_result diff --git a/python/speedtest/tools.py b/python/speedtest/tools.py index d7a3b2d9..94f36679 100644 --- a/python/speedtest/tools.py +++ b/python/speedtest/tools.py @@ -9,7 +9,7 @@ def mean_jitter(latencies: list) -> float: Returns: float: the mean jitter - """ + """ if len(latencies) <= 1: return -1 jitters = [abs(a - b) for a, b in zip(latencies[1:], latencies[:-1])] diff --git a/python/xray/binary.py b/python/xray/binary.py index 46e516eb..9e64dcd0 100644 --- a/python/xray/binary.py +++ b/python/xray/binary.py @@ -3,6 +3,7 @@ import requests from rich.console import Console + from utils.decorators import timeout_fun from utils.exceptions import * from utils.requests import download_file @@ -65,15 +66,12 @@ def download_binary( except FileDownloadError as e: raise BinaryDownloadError( f"Failed to download the release zip file from xtls xray-core github repo {str(system_info)}") - return False except KeyError as e: raise BinaryDownloadError( f"Failed to get binary from zip file {zip_url}") - return False except Exception as e: raise BinaryDownloadError( f"Unknown error - detected system: {str(system_info)}") - return False else: console.log(f"[blue]Binary file already exists {bin_path}[/blue]") return bin_path