easy-utils-dev 2.93__tar.gz → 2.140__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- easy_utils_dev-2.140/MANIFEST.in +1 -0
- easy_utils_dev-2.140/PKG-INFO +23 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/EasySsh.py +1 -1
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/FastQueue.py +27 -6
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/__init__.py +3 -1
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/check_license.py +14 -9
- easy_utils_dev-2.140/easy_utils_dev/debugger-C-PF4PAMMP.py +486 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/debugger.py +81 -28
- easy_utils_dev-2.140/easy_utils_dev/ept.py +655 -0
- easy_utils_dev-2.140/easy_utils_dev/ept_sql/create_dirs.sql +82 -0
- easy_utils_dev-2.140/easy_utils_dev/ept_sql/create_ept_tables.sql +3559 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/exceptions.py +8 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/generate_license.py +11 -4
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/ne1830PSS.py +235 -102
- easy_utils_dev-2.140/easy_utils_dev/nsp_kafka.py +240 -0
- easy_utils_dev-2.140/easy_utils_dev/openid_server.py +71 -0
- easy_utils_dev-2.140/easy_utils_dev/require_auth.py +21 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/simple_sqlite.py +76 -31
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/temp_memory.py +15 -8
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/uiserver.py +5 -1
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/utils.py +2 -1
- easy_utils_dev-2.140/easy_utils_dev/wsnoclib.py +774 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/wsselib.py +0 -1
- easy_utils_dev-2.140/easy_utils_dev.egg-info/PKG-INFO +23 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev.egg-info/SOURCES.txt +9 -1
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev.egg-info/requires.txt +2 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/setup.py +5 -2
- easy_utils_dev-2.93/PKG-INFO +0 -5
- easy_utils_dev-2.93/easy_utils_dev/wsnoclib.py +0 -526
- easy_utils_dev-2.93/easy_utils_dev.egg-info/PKG-INFO +0 -5
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/Events.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/NameObject.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/abortable.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/brevosmtp.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/cplib.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/custom_env.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/easy_oracle.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/encryptor.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/filescompressor.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/keycloakapi.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/lralib.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/optics_utils.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev/winserviceapi.py +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev.egg-info/dependency_links.txt +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/easy_utils_dev.egg-info/top_level.txt +0 -0
- {easy_utils_dev-2.93 → easy_utils_dev-2.140}/setup.cfg +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
recursive-include easy_utils_dev/ept_sql *.sql
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: easy_utils_dev
|
|
3
|
+
Version: 2.140
|
|
4
|
+
Keywords: python3
|
|
5
|
+
Classifier: Programming Language :: Python :: 3
|
|
6
|
+
Requires-Dist: psutil
|
|
7
|
+
Requires-Dist: ping3
|
|
8
|
+
Requires-Dist: flask
|
|
9
|
+
Requires-Dist: flask_cors
|
|
10
|
+
Requires-Dist: xmltodict
|
|
11
|
+
Requires-Dist: paramiko
|
|
12
|
+
Requires-Dist: oracledb
|
|
13
|
+
Requires-Dist: requests
|
|
14
|
+
Requires-Dist: flask_socketio
|
|
15
|
+
Requires-Dist: python-dotenv
|
|
16
|
+
Requires-Dist: gevent
|
|
17
|
+
Requires-Dist: pyzipper
|
|
18
|
+
Requires-Dist: pyjwt
|
|
19
|
+
Requires-Dist: authlib
|
|
20
|
+
Requires-Dist: kafka-python
|
|
21
|
+
Dynamic: classifier
|
|
22
|
+
Dynamic: keywords
|
|
23
|
+
Dynamic: requires-dist
|
|
@@ -69,7 +69,7 @@ class CREATESSH :
|
|
|
69
69
|
ch.disconnect = disconnect
|
|
70
70
|
return ch
|
|
71
71
|
|
|
72
|
-
def ssh_execute(self ,command , merge_output=False , hide_output=
|
|
72
|
+
def ssh_execute(self ,command , merge_output=False , hide_output=True) :
|
|
73
73
|
self.logger.info(f"executing {command}")
|
|
74
74
|
try :
|
|
75
75
|
stdin_ , stdout_ , stderr_ = self.ssh.exec_command(command)
|
|
@@ -24,11 +24,12 @@ class FastQueue :
|
|
|
24
24
|
actionArgs = task['actionArgs']
|
|
25
25
|
onComplete = task['onComplete']
|
|
26
26
|
onFailure = task['onFailure']
|
|
27
|
-
onFailureArgs = task['onFailureArgs']
|
|
28
|
-
onCompleteArgs = task['onCompleteArgs']
|
|
27
|
+
onFailureArgs : dict = task['onFailureArgs']
|
|
28
|
+
onCompleteArgs : dict = task['onCompleteArgs']
|
|
29
29
|
onSuccess = task['onSuccess']
|
|
30
|
-
onSuccessArgs = task['onSuccessArgs']
|
|
30
|
+
onSuccessArgs : dict = task['onSuccessArgs']
|
|
31
31
|
supressError = task['supressError']
|
|
32
|
+
isSuccess= False
|
|
32
33
|
result = None
|
|
33
34
|
try:
|
|
34
35
|
task['running'] = True
|
|
@@ -36,18 +37,38 @@ class FastQueue :
|
|
|
36
37
|
task['result'] = result
|
|
37
38
|
task['completed'] = True
|
|
38
39
|
task['running'] = False
|
|
40
|
+
task['error'] = None
|
|
41
|
+
task['traceback'] = None
|
|
42
|
+
isSuccess = True
|
|
39
43
|
if onSuccess :
|
|
40
|
-
|
|
44
|
+
for key , value in task.items() :
|
|
45
|
+
onSuccessArgs.update({ key : value })
|
|
46
|
+
onSuccessArgs.update({'_task' : task })
|
|
47
|
+
onSuccessArgs.update({'result' : result })
|
|
48
|
+
onSuccessArgs.update({'isSuccess' : True })
|
|
49
|
+
onSuccess(**onSuccessArgs)
|
|
41
50
|
except Exception as e:
|
|
51
|
+
task['error'] = e
|
|
52
|
+
task['traceback']= traceback
|
|
42
53
|
if onFailure :
|
|
43
|
-
|
|
54
|
+
onFailureArgs.update({'_task' : task })
|
|
55
|
+
for key , value in task.items() :
|
|
56
|
+
onFailureArgs.update({ key : value })
|
|
57
|
+
onFailureArgs.update({'traceback' : traceback })
|
|
58
|
+
onFailureArgs.update({'error' : e })
|
|
59
|
+
onFailureArgs.update({'isSuccess' : False })
|
|
60
|
+
onFailure(**onFailureArgs)
|
|
44
61
|
if not supressError :
|
|
45
62
|
print(traceback.format_exc())
|
|
46
63
|
task['completed'] = True
|
|
47
64
|
task['result'] = None
|
|
48
65
|
task['running'] = False
|
|
66
|
+
onCompleteArgs.update({'_task' : task })
|
|
67
|
+
onCompleteArgs.update({'isSuccess' : isSuccess })
|
|
68
|
+
for key , value in task.items() :
|
|
69
|
+
onCompleteArgs.update({ key : value })
|
|
49
70
|
if onComplete :
|
|
50
|
-
onComplete(
|
|
71
|
+
onComplete(**onCompleteArgs)
|
|
51
72
|
self.removeFromQueue(task_id)
|
|
52
73
|
if 'exception' in task and not supressError :
|
|
53
74
|
raise task['exception']
|
|
@@ -20,4 +20,6 @@ from .exceptions import *
|
|
|
20
20
|
from .temp_memory import TemporaryMemory
|
|
21
21
|
from .easy_oracle import *
|
|
22
22
|
from .abortable import *
|
|
23
|
-
from .filescompressor import *
|
|
23
|
+
from .filescompressor import *
|
|
24
|
+
from .require_auth import require_permission
|
|
25
|
+
from .ept import *
|
|
@@ -3,6 +3,7 @@ import hashlib
|
|
|
3
3
|
import base64 , subprocess , sys
|
|
4
4
|
from datetime import datetime
|
|
5
5
|
from .generate_license import generate_license
|
|
6
|
+
import os
|
|
6
7
|
|
|
7
8
|
def get_delta_days(date_str):
|
|
8
9
|
try :
|
|
@@ -23,14 +24,18 @@ def verify_license(license_key, appname, uuid=None, level="basic",return_dict=Fa
|
|
|
23
24
|
# print(f'appname={appname}')
|
|
24
25
|
# print(f'uuid={uuid}')
|
|
25
26
|
# print(f'level={level}')
|
|
26
|
-
|
|
27
|
+
features=None
|
|
28
|
+
if len(key.split('||')) == 3 :
|
|
29
|
+
features=key.split('||')[2]
|
|
30
|
+
os.environ.update({'LICENSEKEY_FEATURES' : features })
|
|
31
|
+
# print(features)
|
|
32
|
+
if len(key.split('||')) < 1 :
|
|
27
33
|
if exit_on_failure :
|
|
28
34
|
sys.exit(f'Invalid license file')
|
|
29
35
|
if return_dict :
|
|
30
|
-
return {'status' : 400 , 'message' : "400_INVALID_LICENSE_FILE" }
|
|
36
|
+
return {'status' : 400 , 'message' : "400_INVALID_LICENSE_FILE" , "features" : features }
|
|
31
37
|
else :
|
|
32
38
|
return "400_INVALID_LICENSE_FILE"
|
|
33
|
-
|
|
34
39
|
license_key = key.split('||')[0].replace('\n' , '')
|
|
35
40
|
expire_date = key.split('||')[1].replace('\n', '')
|
|
36
41
|
if disable_expire_days_warn :
|
|
@@ -45,7 +50,7 @@ def verify_license(license_key, appname, uuid=None, level="basic",return_dict=Fa
|
|
|
45
50
|
if exit_on_failure :
|
|
46
51
|
sys.exit("400_NOT_SUPPORTED_OS")
|
|
47
52
|
elif return_dict :
|
|
48
|
-
return {'status' : 400 , 'message' : "400_NOT_SUPPORTED_OS" }
|
|
53
|
+
return {'status' : 400 , 'message' : "400_NOT_SUPPORTED_OS" , 'features' : features }
|
|
49
54
|
return "400_NOT_SUPPORTED_OS"
|
|
50
55
|
|
|
51
56
|
if open_all :
|
|
@@ -60,7 +65,7 @@ def verify_license(license_key, appname, uuid=None, level="basic",return_dict=Fa
|
|
|
60
65
|
if exit_on_failure :
|
|
61
66
|
sys.exit(f'400_INCORRECT_LICENSE_FORMAT')
|
|
62
67
|
if return_dict :
|
|
63
|
-
return {'status' : 400 , 'message' : "400_INCORRECT_FORMAT" }
|
|
68
|
+
return {'status' : 400 , 'message' : "400_INCORRECT_FORMAT" , 'features' : features }
|
|
64
69
|
return "400_INCORRECT_FORMAT"
|
|
65
70
|
# Convert expected_license_key to bytes
|
|
66
71
|
expected_key_bytes = base64.b64decode(expected_license_key)
|
|
@@ -74,16 +79,16 @@ def verify_license(license_key, appname, uuid=None, level="basic",return_dict=Fa
|
|
|
74
79
|
if exit_on_failure :
|
|
75
80
|
sys.exit(f'License is expired.')
|
|
76
81
|
if return_dict :
|
|
77
|
-
return {'status' : 400 , 'message' : "400_EXPIRED" }
|
|
82
|
+
return {'status' : 400 , 'message' : "400_EXPIRED" , 'features' : features }
|
|
78
83
|
return "400_EXPIRED"
|
|
79
84
|
if return_dict :
|
|
80
|
-
return {'status' : 200 , 'message' : "200_LICENSE_IS_VALID"}
|
|
85
|
+
return {'status' : 200 , 'message' : "200_LICENSE_IS_VALID" , 'features' : features }
|
|
81
86
|
return "200"
|
|
82
87
|
else:
|
|
83
88
|
if exit_on_failure :
|
|
84
|
-
|
|
89
|
+
sys.exit(f'License is not valid. license key is not correct.')
|
|
85
90
|
if return_dict :
|
|
86
|
-
return {'status' : 400 , 'message' : "400_LICENSE_NOT_VALID"
|
|
91
|
+
return {'status' : 400 , 'message' : "400_LICENSE_NOT_VALID" , 'features' : features }
|
|
87
92
|
return "400_LICENSE_NOT_VALID."
|
|
88
93
|
|
|
89
94
|
def main():
|
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from logging.handlers import RotatingFileHandler
|
|
6
|
+
from .utils import getRandomKey , convert_mb_to_bytes , getTimestamp , start_thread
|
|
7
|
+
from .custom_env import custom_env , setupEnvironment
|
|
8
|
+
from .Events import EventEmitter
|
|
9
|
+
from threading import Thread
|
|
10
|
+
from time import sleep
|
|
11
|
+
|
|
12
|
+
gEvent = EventEmitter()
|
|
13
|
+
logging.addLevelName(25, "SCREEN")
|
|
14
|
+
|
|
15
|
+
def setGlobalHomePath( path ) :
|
|
16
|
+
env = custom_env()
|
|
17
|
+
env['debugger_homepath'] = path
|
|
18
|
+
gEvent.dispatchEvent('update_home_path')
|
|
19
|
+
|
|
20
|
+
def setGlobalDisableOnScreen(on_screen=False) :
|
|
21
|
+
env = custom_env()
|
|
22
|
+
env['debugger_on_screen'] = on_screen
|
|
23
|
+
if not on_screen :
|
|
24
|
+
gEvent.dispatchEvent('disable_global_printing')
|
|
25
|
+
else :
|
|
26
|
+
gEvent.dispatchEvent('enable_global_printing')
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def setGlobalDebugLevel(level='info') :
|
|
30
|
+
env = custom_env()
|
|
31
|
+
env['debugger_global_level'] = level
|
|
32
|
+
gEvent.dispatchEvent('update_debug_level')
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class DEBUGGER:
|
|
36
|
+
def __init__(self
|
|
37
|
+
, name
|
|
38
|
+
, level='info',
|
|
39
|
+
fullSyntax=True,
|
|
40
|
+
onscreen=True,
|
|
41
|
+
log_rotation=3,
|
|
42
|
+
homePath=None,
|
|
43
|
+
id=getRandomKey(9) ,
|
|
44
|
+
global_debugger=None,
|
|
45
|
+
disable_log_write=False,
|
|
46
|
+
file_name=None,
|
|
47
|
+
seperate_files=True
|
|
48
|
+
):
|
|
49
|
+
env = custom_env()
|
|
50
|
+
setupEnvironment( 'debugger' )
|
|
51
|
+
debugger_on_screen = env.get('debugger_on_screen' , True)
|
|
52
|
+
env['debugger_on_screen'] = debugger_on_screen
|
|
53
|
+
self.env = env
|
|
54
|
+
self.events = gEvent
|
|
55
|
+
self.debuggerLabel = f"{name}"
|
|
56
|
+
self.logger = logging.getLogger(self.debuggerLabel)
|
|
57
|
+
self.set_level(level)
|
|
58
|
+
self.file_handler_class=None
|
|
59
|
+
self.LOG_SIZE_THRESHOLD_IN_BYTES = 10 * 1024 * 1024
|
|
60
|
+
self.BACKUP_COUNT = log_rotation
|
|
61
|
+
self.homePath = homePath
|
|
62
|
+
self.lastAbsoluteHomePath= None
|
|
63
|
+
self.fullSyntax=fullSyntax
|
|
64
|
+
self.onScreen= onscreen
|
|
65
|
+
self.id = id
|
|
66
|
+
self.how_many_times_write= 0
|
|
67
|
+
self.stream_service = None
|
|
68
|
+
if not env['debugger'].get(name) :
|
|
69
|
+
self.console = console_handler = logging.StreamHandler()
|
|
70
|
+
else :
|
|
71
|
+
self.console = console_handler = env['debugger'].get(name).console
|
|
72
|
+
if not self.logger.hasHandlers() :
|
|
73
|
+
self.logger.addHandler(self.console)
|
|
74
|
+
self.name = name
|
|
75
|
+
self.rotate_disabled=False
|
|
76
|
+
self.isInPyinstaller = False
|
|
77
|
+
self.log_iterations=0
|
|
78
|
+
self.log_iterations_threshold = 200
|
|
79
|
+
self.global_debugger = global_debugger
|
|
80
|
+
self.isLogWriteDisabled = disable_log_write
|
|
81
|
+
self.type = "CUSTOM_DEBUGGER"
|
|
82
|
+
self.seperate_files=seperate_files
|
|
83
|
+
if fullSyntax :
|
|
84
|
+
f = f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
85
|
+
else :
|
|
86
|
+
f = f"[{self.name}]-[%(levelname)s]: %(message)s"
|
|
87
|
+
self.syntax = f
|
|
88
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
89
|
+
self.filename = file_name
|
|
90
|
+
path = self.homepath(homePath)
|
|
91
|
+
if not env['debugger'].get(name) :
|
|
92
|
+
console_handler.setFormatter(self.formatter)
|
|
93
|
+
if not disable_log_write :
|
|
94
|
+
if not env['debugger'].get(name) :
|
|
95
|
+
self.file_handler_class = self.createRotateFileHandler(path)
|
|
96
|
+
if onscreen :
|
|
97
|
+
self.enable_print()
|
|
98
|
+
elif not onscreen :
|
|
99
|
+
self.disable_print()
|
|
100
|
+
self.events.addEventListener('disable_global_printing' , self.disable_print )
|
|
101
|
+
self.events.addEventListener('enable_global_printing' , self.enable_print )
|
|
102
|
+
self.events.addEventListener('update_home_path' , self.updateGlobalHomePath )
|
|
103
|
+
self.events.addEventListener('update_debug_level' , self.updateGlobalSetLevel )
|
|
104
|
+
if env['debugger'].get(name) :
|
|
105
|
+
self = env['debugger'].get(name)
|
|
106
|
+
else:
|
|
107
|
+
env['debugger'][id] = self
|
|
108
|
+
env['debugger'][name] = self
|
|
109
|
+
if not env.get('debugger_on_screen' , True ) :
|
|
110
|
+
self.disable_print()
|
|
111
|
+
if env.get('debugger_on_screen' , True ) :
|
|
112
|
+
self.enable_print()
|
|
113
|
+
if os.environ.get("EASY_UTILS_DEBUG_LEVEL") :
|
|
114
|
+
EASY_UTILS_DEBUG_LEVEL = os.environ.get("EASY_UTILS_DEBUG_LEVEL")
|
|
115
|
+
if not EASY_UTILS_DEBUG_LEVEL.lower() in ['info' , 'debug' , 'warning' , 'error' , 'critical'] :
|
|
116
|
+
self.logger.error(f'EASY_UTILS_DEBUG_LEVEL ENV must be one of [info,debug,warning,error,critical] | Current Env Variable Is "{EASY_UTILS_DEBUG_LEVEL}". Skipping ')
|
|
117
|
+
else :
|
|
118
|
+
self.set_level(EASY_UTILS_DEBUG_LEVEL)
|
|
119
|
+
if os.environ.get("EASY_UTILS_ENABLE_PRINT" , '' ).lower() == 'true' :
|
|
120
|
+
self.enable_print()
|
|
121
|
+
|
|
122
|
+
def switch_full_syntax(self , toggle) :
|
|
123
|
+
if toggle :
|
|
124
|
+
f = f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
125
|
+
else :
|
|
126
|
+
f = f"[{self.name}]-[%(levelname)s]: %(message)s"
|
|
127
|
+
self.syntax = f
|
|
128
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
129
|
+
self.console.setFormatter(self.formatter)
|
|
130
|
+
|
|
131
|
+
def custom_log_syntax(self , syntax) :
|
|
132
|
+
'''
|
|
133
|
+
f"[%(asctime)s]-[{self.name}]-[%(levelname)s]: %(message)s"
|
|
134
|
+
'''
|
|
135
|
+
f = syntax
|
|
136
|
+
self.syntax = f
|
|
137
|
+
self.formatter = logging.Formatter(f , datefmt='%Y-%m-%d %H:%M:%S' )
|
|
138
|
+
self.console.setFormatter(self.formatter)
|
|
139
|
+
|
|
140
|
+
def updateGlobalHomePath(self ) :
|
|
141
|
+
if not self.isLogWriteDisabled :
|
|
142
|
+
getFromEnv = self.env.get('debugger_homepath' , None )
|
|
143
|
+
self.homepath(getFromEnv)
|
|
144
|
+
if getFromEnv :
|
|
145
|
+
self.file_handler_class = self.createRotateFileHandler(self.homePath)
|
|
146
|
+
|
|
147
|
+
def updateGlobalSetLevel( self ) :
|
|
148
|
+
self.set_level(self.env['debugger_global_level'])
|
|
149
|
+
|
|
150
|
+
def advertiseGlobalDebugLevel(self , level) :
|
|
151
|
+
setGlobalDebugLevel(level)
|
|
152
|
+
|
|
153
|
+
def disable_rotate(self) :
|
|
154
|
+
self.rotate_disabled = True
|
|
155
|
+
|
|
156
|
+
def enable_rotate(self) :
|
|
157
|
+
self.rotate_disabled = False
|
|
158
|
+
|
|
159
|
+
def createRotateFileHandler( self , path ) :
|
|
160
|
+
old = self.file_handler_class
|
|
161
|
+
if old :
|
|
162
|
+
self.logger.removeHandler(old)
|
|
163
|
+
file_handler = RotatingFileHandler(path , maxBytes=self.LOG_SIZE_THRESHOLD_IN_BYTES , backupCount=self.BACKUP_COUNT , delay=True )
|
|
164
|
+
self.file_handler= file_handler.setFormatter(self.formatter)
|
|
165
|
+
self.logger.addHandler(file_handler)
|
|
166
|
+
return file_handler
|
|
167
|
+
|
|
168
|
+
def update_log_iterantions_threshold(self,threshold : int ):
|
|
169
|
+
'''
|
|
170
|
+
set value when rotation should be checked. when every on_log function called.
|
|
171
|
+
by default rotation will be checked every 200 on_log function call.
|
|
172
|
+
'''
|
|
173
|
+
self.log_iterations_threshold = threshold
|
|
174
|
+
|
|
175
|
+
def updateGlobalDebugger(self , logger ) :
|
|
176
|
+
'''
|
|
177
|
+
this function pass the log message to other logger to write the same log message to it.
|
|
178
|
+
logger must be debugger class.
|
|
179
|
+
'''
|
|
180
|
+
if logger.type != 'CUSTOM_DEBUGGER' :
|
|
181
|
+
raise Exception(f'Invalid logger type. must pass debugger class.')
|
|
182
|
+
self.global_debugger = logger
|
|
183
|
+
|
|
184
|
+
def getStreamServiceUrlPath(self) :
|
|
185
|
+
return self.streampath
|
|
186
|
+
|
|
187
|
+
def getStreamService(self) :
|
|
188
|
+
return self.stream_service
|
|
189
|
+
|
|
190
|
+
def isStreamServiceAvailable(self) :
|
|
191
|
+
if self.stream_service :
|
|
192
|
+
return True
|
|
193
|
+
return False
|
|
194
|
+
|
|
195
|
+
def addStreamService( self , socketio , streampath='/debugger/stream/log' ) :
|
|
196
|
+
"""
|
|
197
|
+
This function takes a live socketio server. it emit the log message using default path which is /debugger/stream/log
|
|
198
|
+
"""
|
|
199
|
+
self.stream_service = socketio
|
|
200
|
+
self.streampath = streampath
|
|
201
|
+
|
|
202
|
+
def updateLogName( self , name ) :
|
|
203
|
+
self.name = name
|
|
204
|
+
|
|
205
|
+
def disable_log_write(self) :
|
|
206
|
+
'''
|
|
207
|
+
this function is used to disable the log write to file. if onScreen is enabled, logs will be displayed only on screen.
|
|
208
|
+
'''
|
|
209
|
+
self.isLogWriteDisabled = True
|
|
210
|
+
if self.file_handler_class :
|
|
211
|
+
self.logger.removeHandler(self.file_handler_class)
|
|
212
|
+
|
|
213
|
+
def enable_log_write(self) :
|
|
214
|
+
self.createRotateFileHandler(self.homePath)
|
|
215
|
+
|
|
216
|
+
def manage_file_rotation(self, record ) :
|
|
217
|
+
handler = self.get_rotate_handler()
|
|
218
|
+
if handler.shouldRollover(record) :
|
|
219
|
+
handler.doRollover()
|
|
220
|
+
self.log_iterations = 0
|
|
221
|
+
|
|
222
|
+
def get_rotate_handler(self) :
|
|
223
|
+
return self.file_handler_class
|
|
224
|
+
|
|
225
|
+
def change_log_size(self, size) -> bool:
|
|
226
|
+
'''
|
|
227
|
+
change the size of each log file rotation.
|
|
228
|
+
default is 10M
|
|
229
|
+
size should be passed as MB
|
|
230
|
+
'''
|
|
231
|
+
size = convert_mb_to_bytes(size)
|
|
232
|
+
self.LOG_SIZE_THRESHOLD_IN_BYTES = size
|
|
233
|
+
handler = self.get_rotate_handler()
|
|
234
|
+
handler.maxBytes = size
|
|
235
|
+
return True
|
|
236
|
+
|
|
237
|
+
|
|
238
|
+
def checks_in_bg(self) :
|
|
239
|
+
while True :
|
|
240
|
+
if self.env.get('GLOBAL_DEBUGGER_STREAM_SERVICE') :
|
|
241
|
+
self.addStreamService(socketio=self.env.get('GLOBAL_DEBUGGER_STREAM_SERVICE'))
|
|
242
|
+
if self.env.get('debugger_global_level' , None) :
|
|
243
|
+
self.set_level( level=self.env.get('debugger_global_level') )
|
|
244
|
+
if not self.env.get('debugger_on_screen' , True ) :
|
|
245
|
+
self.disable_print()
|
|
246
|
+
if self.env.get('debugger_on_screen' , True ) :
|
|
247
|
+
self.enable_print()
|
|
248
|
+
if os.environ.get("EASY_UTILS_DEBUG_LEVEL") :
|
|
249
|
+
EASY_UTILS_DEBUG_LEVEL = os.environ.get("EASY_UTILS_DEBUG_LEVEL")
|
|
250
|
+
if not EASY_UTILS_DEBUG_LEVEL.lower() in ['info' , 'debug' , 'warning' , 'error' , 'critical'] :
|
|
251
|
+
self.logger.error(f'EASY_UTILS_DEBUG_LEVEL ENV must be one of [info,debug,warning,error,critical] | Current Env Variable Is "{EASY_UTILS_DEBUG_LEVEL}". Skipping ')
|
|
252
|
+
else :
|
|
253
|
+
self.set_level(EASY_UTILS_DEBUG_LEVEL)
|
|
254
|
+
self.updateGlobalHomePath()
|
|
255
|
+
if os.environ.get("EASY_UTILS_ENABLE_PRINT" , '' ).lower() == 'true' :
|
|
256
|
+
self.enable_print()
|
|
257
|
+
sleep(5)
|
|
258
|
+
|
|
259
|
+
def close(self) :
|
|
260
|
+
try :
|
|
261
|
+
logging.shutdown()
|
|
262
|
+
except :
|
|
263
|
+
pass
|
|
264
|
+
|
|
265
|
+
def homepath(self , path=None ) :
|
|
266
|
+
env = custom_env()
|
|
267
|
+
getFromEnv = env.get('debugger_homepath' , None )
|
|
268
|
+
if getFromEnv is not None :
|
|
269
|
+
self.homePath = getFromEnv
|
|
270
|
+
else :
|
|
271
|
+
if path is not None :
|
|
272
|
+
if self.homePath and '.log' in str(self.homePath):
|
|
273
|
+
self.lastAbsoluteHomePath= self.homePath
|
|
274
|
+
self.homePath = path
|
|
275
|
+
else :
|
|
276
|
+
self.homePath = os.path.join(os.getcwd() , 'debug')
|
|
277
|
+
if not os.path.exists( self.homePath ) :
|
|
278
|
+
try :
|
|
279
|
+
os.makedirs( self.homePath )
|
|
280
|
+
except :
|
|
281
|
+
pass
|
|
282
|
+
if self.filename :
|
|
283
|
+
self.homePath = os.path.join( self.homePath, f'{self.filename}.log' )
|
|
284
|
+
else :
|
|
285
|
+
self.homePath = os.path.join( self.homePath, f'{self.name}.log' )
|
|
286
|
+
return self.homePath
|
|
287
|
+
|
|
288
|
+
def get_current_levels(self):
|
|
289
|
+
"""
|
|
290
|
+
Returns a list of log levels that will be printed based on the current logging level.
|
|
291
|
+
"""
|
|
292
|
+
levels_order = [
|
|
293
|
+
('debug', logging.DEBUG),
|
|
294
|
+
('info', logging.INFO),
|
|
295
|
+
('warning', logging.WARNING),
|
|
296
|
+
('error', logging.ERROR),
|
|
297
|
+
('critical', logging.CRITICAL),
|
|
298
|
+
]
|
|
299
|
+
# Optional custom level
|
|
300
|
+
if hasattr(logging, 'SCREEN'):
|
|
301
|
+
levels_order.append(('screen', logging.SCREEN))
|
|
302
|
+
current_level = self.logger.level
|
|
303
|
+
# Return all levels with numeric value >= current_level
|
|
304
|
+
return [name for name, value in levels_order if value >= current_level]
|
|
305
|
+
|
|
306
|
+
def enable_print(self) :
|
|
307
|
+
self.onScreen = True
|
|
308
|
+
self.logger.addHandler(self.console)
|
|
309
|
+
|
|
310
|
+
def disable_print(self) :
|
|
311
|
+
self.onScreen = False
|
|
312
|
+
self.logger.removeHandler(self.console)
|
|
313
|
+
|
|
314
|
+
def changeHomePath( self , path ) :
|
|
315
|
+
p = self.homepath(path)
|
|
316
|
+
self.file_handler_class = self.createRotateFileHandler(p)
|
|
317
|
+
if self.lastAbsoluteHomePath :
|
|
318
|
+
os.remove(self.lastAbsoluteHomePath)
|
|
319
|
+
|
|
320
|
+
def isGlobalDebuggerDefined(self) :
|
|
321
|
+
if self.global_debugger :
|
|
322
|
+
return True
|
|
323
|
+
else :
|
|
324
|
+
return False
|
|
325
|
+
|
|
326
|
+
def set_level(self, level : str):
|
|
327
|
+
if 'info' in level.lower() : lvl = logging.INFO
|
|
328
|
+
elif 'warn' in level.lower() : lvl = logging.WARNING
|
|
329
|
+
elif 'warning' in level.lower() : lvl = logging.WARNING
|
|
330
|
+
elif 'critical' in level.lower() : lvl = logging.CRITICAL
|
|
331
|
+
elif 'debug' in level.lower() : lvl = logging.DEBUG
|
|
332
|
+
elif 'error' in level.lower() : lvl = logging.ERROR
|
|
333
|
+
elif 'screen' in level.lower() : lvl = logging.SCREEN
|
|
334
|
+
else : raise ValueError('Unknown level, not one of [info,warn,warning,critical,debug,error,screen]')
|
|
335
|
+
self.currentDebugLevel = level
|
|
336
|
+
self.logger.setLevel(lvl)
|
|
337
|
+
|
|
338
|
+
def get_current_debug_level(self) :
|
|
339
|
+
return self.currentDebugLevel
|
|
340
|
+
|
|
341
|
+
def get_logger(self) :
|
|
342
|
+
return self.logger
|
|
343
|
+
|
|
344
|
+
def before_log(self , message , level) :
|
|
345
|
+
|
|
346
|
+
def __call_thread__() :
|
|
347
|
+
if not level in self.get_current_levels() :
|
|
348
|
+
return
|
|
349
|
+
if self.isStreamServiceAvailable() :
|
|
350
|
+
d = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
351
|
+
streamUrl = self.getStreamServiceUrlPath()
|
|
352
|
+
self.stream_service.emit( streamUrl , {
|
|
353
|
+
'message' : message ,
|
|
354
|
+
'level' : level ,
|
|
355
|
+
'msg' : message,
|
|
356
|
+
'date' : d ,
|
|
357
|
+
'id' : self.id,
|
|
358
|
+
'formate' : 'json' ,
|
|
359
|
+
'source' : self.name ,
|
|
360
|
+
'getTimestamp' : getTimestamp()
|
|
361
|
+
})
|
|
362
|
+
try :
|
|
363
|
+
t= Thread(target=__call_thread__)
|
|
364
|
+
# t.daemon=True
|
|
365
|
+
t.start()
|
|
366
|
+
except :
|
|
367
|
+
__call_thread__()
|
|
368
|
+
|
|
369
|
+
params = {
|
|
370
|
+
'screen' : True ,
|
|
371
|
+
'file': True
|
|
372
|
+
}
|
|
373
|
+
if self.onScreen and self.env['debugger_on_screen'] == True :
|
|
374
|
+
params['screen'] = True
|
|
375
|
+
else :
|
|
376
|
+
params['screen'] = False
|
|
377
|
+
return params
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
def info(self, message , external_debugger=None,source=None):
|
|
381
|
+
def __call__(message) :
|
|
382
|
+
if source :
|
|
383
|
+
message = f'[{source}]-{message}'
|
|
384
|
+
self.before_log(message , 'info')
|
|
385
|
+
self.logger.info(message)
|
|
386
|
+
if self.isGlobalDebuggerDefined() :
|
|
387
|
+
self.global_debugger.info(message)
|
|
388
|
+
if external_debugger :
|
|
389
|
+
external_debugger.info(message)
|
|
390
|
+
try :
|
|
391
|
+
r=Thread(target=__call__,args=[message])
|
|
392
|
+
r.daemon=True
|
|
393
|
+
r.start()
|
|
394
|
+
r.join()
|
|
395
|
+
except :
|
|
396
|
+
__call__(message)
|
|
397
|
+
|
|
398
|
+
def debug(self, message , external_debugger=None,source=None):
|
|
399
|
+
def __call__(message) :
|
|
400
|
+
if source :
|
|
401
|
+
message = f'[{source}]-{message}'
|
|
402
|
+
self.before_log(message , 'debug')
|
|
403
|
+
self.logger.debug(message)
|
|
404
|
+
if self.isGlobalDebuggerDefined() :
|
|
405
|
+
self.global_debugger.debug(message)
|
|
406
|
+
if external_debugger :
|
|
407
|
+
external_debugger.debug(message)
|
|
408
|
+
try :
|
|
409
|
+
r=Thread(target=__call__,args=[message])
|
|
410
|
+
r.daemon=True
|
|
411
|
+
r.start()
|
|
412
|
+
r.join()
|
|
413
|
+
except :
|
|
414
|
+
__call__(message)
|
|
415
|
+
|
|
416
|
+
def warning(self, message , external_debugger=None,source=None):
|
|
417
|
+
def __call__(message) :
|
|
418
|
+
if source :
|
|
419
|
+
message = f'[{source}]-{message}'
|
|
420
|
+
self.before_log(message , 'warning')
|
|
421
|
+
self.logger.warning(message)
|
|
422
|
+
if self.isGlobalDebuggerDefined() :
|
|
423
|
+
self.global_debugger.warning(message)
|
|
424
|
+
if external_debugger :
|
|
425
|
+
external_debugger.warning(message)
|
|
426
|
+
try :
|
|
427
|
+
r=Thread(target=__call__,args=[message])
|
|
428
|
+
r.daemon=True
|
|
429
|
+
r.start()
|
|
430
|
+
r.join()
|
|
431
|
+
except :
|
|
432
|
+
__call__(message)
|
|
433
|
+
|
|
434
|
+
def error(self, message,external_debugger=None,source=None):
|
|
435
|
+
def __call__(message) :
|
|
436
|
+
if source :
|
|
437
|
+
message = f'[{source}]-{message}'
|
|
438
|
+
self.before_log(message , 'error')
|
|
439
|
+
self.logger.error(message)
|
|
440
|
+
if self.isGlobalDebuggerDefined() :
|
|
441
|
+
self.global_debugger.error(message)
|
|
442
|
+
if external_debugger :
|
|
443
|
+
external_debugger.error(message)
|
|
444
|
+
try :
|
|
445
|
+
r=Thread(target=__call__,args=[message])
|
|
446
|
+
r.daemon=True
|
|
447
|
+
r.start()
|
|
448
|
+
r.join()
|
|
449
|
+
except :
|
|
450
|
+
__call__(message)
|
|
451
|
+
|
|
452
|
+
def critical(self, message,external_debugger=None,source=None):
|
|
453
|
+
def __call__() :
|
|
454
|
+
if source :
|
|
455
|
+
message = f'[{source}]-{message}'
|
|
456
|
+
self.before_log(message , 'critical')
|
|
457
|
+
self.logger.critical(message)
|
|
458
|
+
if self.isGlobalDebuggerDefined() :
|
|
459
|
+
self.global_debugger.critical(message)
|
|
460
|
+
if external_debugger :
|
|
461
|
+
external_debugger.critical(message)
|
|
462
|
+
try :
|
|
463
|
+
r=Thread(target=__call__,args=[message])
|
|
464
|
+
r.daemon=True
|
|
465
|
+
r.start()
|
|
466
|
+
r.join()
|
|
467
|
+
except :
|
|
468
|
+
__call__(message)
|
|
469
|
+
|
|
470
|
+
def screen(self, message,external_debugger=None,source=None):
|
|
471
|
+
def __call__() :
|
|
472
|
+
if source :
|
|
473
|
+
message = f'[{source}]-{message}'
|
|
474
|
+
self.before_log(message , 'critical')
|
|
475
|
+
print(f"{self.syntax}")
|
|
476
|
+
if self.isGlobalDebuggerDefined() :
|
|
477
|
+
self.global_debugger.critical(message)
|
|
478
|
+
if external_debugger :
|
|
479
|
+
external_debugger.critical(message)
|
|
480
|
+
try :
|
|
481
|
+
r=Thread(target=__call__,args=[message])
|
|
482
|
+
r.daemon=True
|
|
483
|
+
r.start()
|
|
484
|
+
r.join()
|
|
485
|
+
except :
|
|
486
|
+
__call__(message)
|