Debug module
- class Debug.Debug[source]
Bases:
objectThis class will dump debug information into a debug log file.
In order for this to work, first you must set the options of the logger with at least a DEBUG_FILE parameter. You can do this by either calling
Debug.set_debug_file(), or by callingDebug.set_config()with a dictionary with at least a DEBUG_FILE item.All functions are static, you should not instantiate this class.
Once this class is correctly set up, you can start logging information by using any of the methods in this class. For instance, if you want to log an exception during a try-except, you can do so by using
Debug.debugException()orDebug.debugCritical()for critical exceptions.If you just want to log information, you can use
Debug.debugLog()at any given time.You can also use
Debug.inspect()to inspect any object and dump it’s information. This is very useful when you want to print information related to a variable. If you want to inspect global variables or local variables, useDebug.inspectGlobals()orDebug.inspectLocals()respectively. There is alsoDebug.inspectModules()if you need to dump all loaded modules.Last but not least,
Debug.hexdump()will dump the contents of a bytes array into the log. If you want to dump binary data into a different file so you can inspect it later by other means, useDebug.bindump().Example
from Debug import Debug Debug.set_config({ "DEBUG_FILE": "./debug/debug.log", "ROLLER_LINES": 25000, "WRITE_TO_STDOUT": True }) try: a = 5 b = 0 c = a/b except Exception as exc: Debug.debugException(exc)
This prints the following debug information into debug/debug.log:
-- START OF EXCEPTION (E 0xe7ba3afc) -- 12/07/2022, 13:42:10:356113 E 0xe7ba3afc [<class 'ZeroDivisionError'>] Traceback (most recent call last): File "E:\PY\maira\debugTest.py", line 12, in <module> c = a/b ZeroDivisionError: division by zero From: E:\PY\maira\debugTest.py 14 <module> Context: [' Debug.debugException(exc)'] locals(): local: __doc__ (<class 'NoneType'>) -> None local: __package__ (<class 'NoneType'>) -> None local: __spec__ (<class 'NoneType'>) -> None local: __cached__ (<class 'NoneType'>) -> None local: Debug (<class 'type'>) -> 12/07/2022, 13:42:10:357113 L 0x983305b7 [instance of type] WARNING: Objects instances of type are ignored due to deep recursion. END of local: Debug local: a (<class 'int'>) -> 5 local: b (<class 'int'>) -> 0 local: exc (<class 'ZeroDivisionError'>) -> 12/07/2022, 13:42:10:358114 L 0x4616027d [instance of ZeroDivisionError] WARNING: This instance of ZeroDivisionError is empty END of local: exc -- END OF EXCEPTION --
Understanding logs
Each log has a header with the following information:
<datetime> <log ID> [<event name>]datetimeis the date and time of the log, up to milliseconds.log IDis a unique identifier for the log in the following format:<log class> 0x<ID>Where
log classis the severity of the log (‘L’ for log/information, ‘E’ for Exception, and ‘C’ for Critical error), andIDis a unique identifier for the log.event nameis the name of the log event.When debugging exceptions, the log is wrapped into the following headers:
-- START OF EXCEPTION (<log ID>) -- ... -- END OF EXCEPTION --Everything between the start and the end of the exception, belongs to the exception being reported. The same applies for critical errors, except it says CRITICAL ERROR instead of EXCEPTION.
Exceptions and critical errors have a unique ID. Errors that generate in the same line of the code will all have the same ID. This will help you get track of errors as well.
When inspecting objects, the name, type and value of the object will be dumped. Class instances will also see their members dumped. The debugger will recursively dump all members of the object instance and add indentation depending on the level of recursion, until MAX_RECURSION is reached.
Warnings
You might see the following warnings in your log:
WARNING: <var num> variables not assigned: <list of not assigned>Caused when inspecting locals or globals and passing a list with variable names, but some of the variables in the list are not assigned at this point.
WARNING: Recursion limit when calling <debug function>. Skipping.Caused when MAX_RECURSION is reached while inspecting an object. At this point the debugger will not recurse into any of the object’s members any more.
WARNING: <name> (<object>) is emptyCaused when inspecting a list, dict or tuple that is empty.
WARNING: Attempting to call <function> on something that is not a <class>.Caused when attempting to inspect a list, dict or tuple that is not an instance of their respective function’s intended class (i.e calling debugDict and passing a Tuple as a parameter). The debugger will tell you what it really is in the next line.
WARNING: Objects instances of <type> are ignored due to deep recursion.Caused when attempting to inspect an object instance of a class that is known to cause deep recursion problems. Ignore these.
WARNING: Attempting to call 'debugClass' on object of type <type> (Not a class)Caused when calling debugClass on something that doesn’t seem to be an instance of a class. For instance, calling debugClass and passing a dict as it’s parameter.
WARNING: This instance of <type> is emptyCaused when calling debugClass with an object instance that has no members (it’s empty). Functions are ignored.
Class functions
- static bindump(obj: bytes, output_file: str, as_string: bool = False)[source]
- Parameters
obj (bytes) – Object to dump
output_file (str) – File where the binary data will be output.
as_string (bool) – Output a string with the binary data instead of binary data, defaults to False
This function will dump binary data into output_file. If as_string is set to True, it will instead dump the binary data as hex by calling hexdump.
- static debugClass(_instance: object, _rec: int = 0)[source]
- Parameters
_instance (object) – Object instance of any class.
Inspects an instance object, dumping all the information from it.
- static debugCritical(exc: Exception) int[source]
- Parameters
exc (Exception) – The exception to debug
Call this function only for critical errors. It’s the same as debugException, but it logs at critical level ‘C’ and outputs the whole global and local frames as well as the loaded modules.
- Returns
ID of the exception. The ID is a unique identifier for the exception, meaning that if the exception is the same, the same ID will be returned.
- Return type
int
- static debugDict(_dict: dict, name: str = '', _rec: int = 0)[source]
- Parameters
_dict – Dictionary to inspect
name (str) – Name of the dictionary, optional, defaults to “”
This function will dump all key-value pairs from the given dictionary. ‘name’ is optional and it’s only used to give a name to the dict in the log.
- static debugException(exc: Exception, inspect_globals: bool = False, inspect_global_vars: Optional[list] = None, inspect_locals: bool = True, inspect_local_vars: Optional[list] = None) int[source]
- Parameters
exc (Exception) – The exception to debug
inspect_globals (bool) – Inspect globals or not, defaults to False
inspect_global_vars (list) – List of global variable names to inspect as strings, defaults to None
inspect_locals (bool) – Inspect locals or not, defaults to True
inspect_local_vars (list) – List of local variable names to inspect as strings, defaults to None
When either inspect_global_vars or inspect_local_vars is set to a list of names, it will attempt to inspect those variables. If set to None, it will inspect all variables in the global and local scopes respectively.
- Returns
ID of the exception. The ID is a unique identifier for the exception, meaning that if the exception is the same, the same ID will be returned.
- Return type
int
- static debugListorTuple(_list: list, name: str = '', _rec: int = 0)[source]
- Parameters
_list – List or tuple to inspcect
name (str) – Name of the list or tuple, optional, defaults to “”
This function will dump all items from the given list or tuple. ‘name’ is optional and it’s only used to give a name to the list or tuple in the log.
- static debugLog(msg: str, name: str = '')[source]
- Parameters
msg (str) – Message to log.
name (str) – Name of the event to log, defaults to “”
The parameter ‘name’ is just for decorative purposes only.
- static getFrameInfo()[source]
Gets the caller current frame. It executes getframeinfo(currentframe().f_back)
- static getSystemInfo() dict[source]
Returns the system information as a dict containing the following information:
python: Python build version.platform: Platform information.cpu_name: Name of the processor architecture.cpu_count: String containing the physical CPU count and the logical CPU count.os: Name of the operating system.memorydict with the following information:virtual: Tuple with the virtual memory information.swap: Swap memory informationused_by_python: Memory used by the program.network: If the machine is connected to the internet, it’s set to True, False if it’s not.All units are in bytes.
Note: To determine if it’s connected to the internet, this function makes a request to ipecho.net.
- static hexdump(obj: bytes, start_offset: int = 0, end_offset: Optional[int] = None, cols: int = 16, rows: Optional[int] = None, split: int = 0, headers: bool = True, offsets: bool = True, ascii: bool = True, rawoutput: bool = False, forceasciionly=False) str[source]
- Parameters
obj (bytes) – Byte array to dump.
start_offset (int) – Starting offset to dump, defaults to 0
end_offset (int) – End offset to dump, defaults to None
cols (int) – Columns to dump, defaults to 16
rows (int) – Rows to dump, defaults to None
split (int) – Split the dump into several tables at this many rows, defaults to 0
headers (bool) – Print the headers or not, defaults to True
offsets (bool) – Print the offsets or not, defaults to True
ascii (bool) – Will print the ASCII representation of the hex information, defaults to True
rawoutput (bool) – Will only print a table of hex bytes and nothing else, defaults to False
forceasciionly (bool) – Will only print printable characters (such as letters and numbers), defaults to False
- Returns
String containing the hex dump, or None if the function fails
- Return type
str or None
This function will return an hex dump in the style of an hex editor as a string. The parameters determine the format and the information dumped. When dumping information, by default the offset column will always start at 0. If you want to inspect a portion of the array, using
start_offsetandend_offsetis recommended rather than slicing the array so that the output is accurate.The output is in a table format in the style of hex editors. Each row represents a string of n bytes, and each column represents a byte. The parameters
rowandcolsdetermine how many rows and how many columns can be represented. No more than 16 columns can be represented, and no less than 1 rows or columns can be represented.The parameter
splitwill split the output into smaller tables. It will split the table every n rows, where n is the value of split. So if split is set to 16, it will split the table every 16 rows.The header is the top part of the table and the offsets are at the left of the table. They can be disables with the
headersandoffsetsparameters if you don’t want them.The ascii representation of the data will be printed at the right of the table, and can also be disabled with the
asciiparameter.If
rawoutputis set to True, it will disable split, headers, offsets, and ascii. Set this to True if you want a raw output.When storing hex dumps into files, enable
forceasciionlyto avoid non-ascii characters to be stored that could cause issues.
- static inspectGlobals(for_id: str = '', vars: Optional[list] = None)[source]
- For_id
Ignore this parameter. It is used by the class.
- Parameters
vars (list) – List of variable names to inspect as strings, defaults to None
If vars is set to None, it will inspect all globals.
- static inspectLocals(l_: dict, vars: Optional[list] = None, for_id: str = '')[source]
- Parameters
l (dict) – Dictionary with the locals.
vars (list) – List of variable names to inspect as strings, defaults to None
for_id (str) – Ignore this parameter (It is used by the class), defaults to “”
Use GetFrameInfo(currentframe()) to get the local variables. If vars is set to None, it will inspect all locals.
- static inspectModules()[source]
This function will get all loaded modules and dump them into the log file.
- static set_config(config: dict)[source]
- Parameters
config (dict) – A dictionary with the Debugger configuration parameters.
Set the global configuration of the debugger. The configuration is in a dictionary object containing the paramenters and their respective values. The following values are accepted:
DEBUG_FILE(str): Path to the debug log where the information will be stored.MAX_RECURSION(int): Sets the maximum allowed recursion while inspecting. (Default: 11)WRITE_TO_STDOUT(bool): Output to the console. (Default: False)VERBOSE_STDOUT(bool): Will output EVERYTHING to the console. (Default: False)ROLLER(bool): Enable/disable the rolling log file (Default: True)ROLLER_LINES(int): Maximum lines in the log until it starts rolling (Default: 50000)DUMP_BYTES(bool): Will dump an hex representation of bytes objects (Default: True)DUMP_BYTES_LENGTH(int): Maximum length (in bytes) of the dumps (Default: 512)Notes: WRITE_TO_STDOUT will write to STDERR when calling to debugException or debugCritical.
- static set_debug_file(path: str) TextIOWrapper[source]
Set the output file where the log will be stored.
- static set_dump_bytes(dump_bytes: bool)[source]
Enable/Disable hex dumps of byte-like objects (bytes, ByteIO) during object inspection.
- static set_dump_bytes_length(dump_bytes_length: int)[source]
When DUMP_BYTES is enabled, sets the maximum number of bytes to dump. :param dump_bytes_length: The maximum number of bytes to dump. Must be between 8 and 1000000.
- static set_max_recursion(max_rec: int) bool[source]
Set the maximum recursion allowed when inspecting objects. :param max_rec: Maximum recursion. Must be between 1 and sys.getrecursionlimit() - 10. 10 recursions are reserved to avoid reaching maximum recursion. Set this to something relatively low (You shouldn’t need more than 10).
- static set_roller_lines(roller_lines: int)[source]
- Parameters
roller_lines – The number of lines. Must be between 1 and 10000000.
Set the maximum number of lines before the log starts rolling.
- static set_roller_log(roller_log: bool = True)[source]
Enable/Disable rolling logs. When enabled, log files will delete the first lines if the number of lines is bigger than ROLLER_LINES.