atomicshop 2.11.47__py3-none-any.whl → 3.10.5__py3-none-any.whl

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.
Files changed (268) hide show
  1. atomicshop/__init__.py +1 -1
  2. atomicshop/{addons/mains → a_mains}/FACT/update_extract.py +3 -2
  3. atomicshop/a_mains/addons/process_list/compile.cmd +7 -0
  4. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
  5. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
  6. atomicshop/a_mains/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
  7. atomicshop/{addons → a_mains/addons}/process_list/process_list.cpp +8 -1
  8. atomicshop/a_mains/dns_gateway_setting.py +11 -0
  9. atomicshop/a_mains/get_local_tcp_ports.py +85 -0
  10. atomicshop/a_mains/github_wrapper.py +11 -0
  11. atomicshop/a_mains/install_ca_certificate.py +172 -0
  12. atomicshop/{addons/mains → a_mains}/msi_unpacker.py +3 -1
  13. atomicshop/a_mains/process_from_port.py +119 -0
  14. atomicshop/a_mains/set_default_dns_gateway.py +90 -0
  15. atomicshop/a_mains/update_config_toml.py +38 -0
  16. atomicshop/appointment_management.py +5 -3
  17. atomicshop/basics/ansi_escape_codes.py +3 -1
  18. atomicshop/basics/argparse_template.py +2 -0
  19. atomicshop/basics/booleans.py +27 -30
  20. atomicshop/basics/bytes_arrays.py +43 -0
  21. atomicshop/basics/classes.py +149 -1
  22. atomicshop/basics/dicts.py +12 -0
  23. atomicshop/basics/enums.py +2 -2
  24. atomicshop/basics/exceptions.py +5 -1
  25. atomicshop/basics/list_of_classes.py +29 -0
  26. atomicshop/basics/list_of_dicts.py +69 -5
  27. atomicshop/basics/lists.py +14 -0
  28. atomicshop/basics/multiprocesses.py +374 -50
  29. atomicshop/basics/package_module.py +10 -0
  30. atomicshop/basics/strings.py +160 -7
  31. atomicshop/basics/threads.py +14 -0
  32. atomicshop/basics/tracebacks.py +13 -4
  33. atomicshop/certificates.py +153 -52
  34. atomicshop/config_init.py +12 -7
  35. atomicshop/console_user_response.py +7 -14
  36. atomicshop/consoles.py +9 -0
  37. atomicshop/datetimes.py +98 -0
  38. atomicshop/diff_check.py +340 -40
  39. atomicshop/dns.py +128 -12
  40. atomicshop/etws/_pywintrace_fix.py +17 -0
  41. atomicshop/etws/const.py +38 -0
  42. atomicshop/etws/providers.py +21 -0
  43. atomicshop/etws/sessions.py +43 -0
  44. atomicshop/etws/trace.py +168 -0
  45. atomicshop/etws/traces/trace_dns.py +162 -0
  46. atomicshop/etws/traces/trace_sysmon_process_creation.py +126 -0
  47. atomicshop/etws/traces/trace_tcp.py +130 -0
  48. atomicshop/file_io/csvs.py +222 -24
  49. atomicshop/file_io/docxs.py +35 -18
  50. atomicshop/file_io/file_io.py +35 -19
  51. atomicshop/file_io/jsons.py +49 -0
  52. atomicshop/file_io/tomls.py +139 -0
  53. atomicshop/filesystem.py +864 -293
  54. atomicshop/get_process_list.py +133 -0
  55. atomicshop/{process_name_cmd.py → get_process_name_cmd_dll.py} +52 -19
  56. atomicshop/http_parse.py +149 -93
  57. atomicshop/ip_addresses.py +6 -1
  58. atomicshop/mitm/centered_settings.py +132 -0
  59. atomicshop/mitm/config_static.py +207 -0
  60. atomicshop/mitm/config_toml_editor.py +55 -0
  61. atomicshop/mitm/connection_thread_worker.py +875 -357
  62. atomicshop/mitm/engines/__parent/parser___parent.py +4 -17
  63. atomicshop/mitm/engines/__parent/recorder___parent.py +108 -51
  64. atomicshop/mitm/engines/__parent/requester___parent.py +116 -0
  65. atomicshop/mitm/engines/__parent/responder___parent.py +75 -114
  66. atomicshop/mitm/engines/__reference_general/parser___reference_general.py +10 -7
  67. atomicshop/mitm/engines/__reference_general/recorder___reference_general.py +5 -5
  68. atomicshop/mitm/engines/__reference_general/requester___reference_general.py +47 -0
  69. atomicshop/mitm/engines/__reference_general/responder___reference_general.py +95 -13
  70. atomicshop/mitm/engines/create_module_template.py +58 -14
  71. atomicshop/mitm/import_config.py +359 -139
  72. atomicshop/mitm/initialize_engines.py +160 -74
  73. atomicshop/mitm/message.py +64 -23
  74. atomicshop/mitm/mitm_main.py +892 -0
  75. atomicshop/mitm/recs_files.py +183 -0
  76. atomicshop/mitm/shared_functions.py +4 -10
  77. atomicshop/mitm/ssh_tester.py +82 -0
  78. atomicshop/mitm/statistic_analyzer.py +257 -166
  79. atomicshop/mitm/statistic_analyzer_helper/analyzer_helper.py +136 -0
  80. atomicshop/mitm/statistic_analyzer_helper/moving_average_helper.py +525 -0
  81. atomicshop/monitor/change_monitor.py +96 -120
  82. atomicshop/monitor/checks/dns.py +139 -70
  83. atomicshop/monitor/checks/file.py +77 -0
  84. atomicshop/monitor/checks/network.py +81 -77
  85. atomicshop/monitor/checks/process_running.py +33 -34
  86. atomicshop/monitor/checks/url.py +94 -0
  87. atomicshop/networks.py +671 -0
  88. atomicshop/on_exit.py +205 -0
  89. atomicshop/package_mains_processor.py +84 -0
  90. atomicshop/permissions/permissions.py +22 -0
  91. atomicshop/permissions/ubuntu_permissions.py +239 -0
  92. atomicshop/permissions/win_permissions.py +33 -0
  93. atomicshop/print_api.py +24 -41
  94. atomicshop/process.py +63 -17
  95. atomicshop/process_poller/__init__.py +0 -0
  96. atomicshop/process_poller/pollers/__init__.py +0 -0
  97. atomicshop/process_poller/pollers/psutil_pywin32wmi_dll.py +95 -0
  98. atomicshop/process_poller/process_pool.py +207 -0
  99. atomicshop/process_poller/simple_process_pool.py +311 -0
  100. atomicshop/process_poller/tracer_base.py +45 -0
  101. atomicshop/process_poller/tracers/__init__.py +0 -0
  102. atomicshop/process_poller/tracers/event_log.py +46 -0
  103. atomicshop/process_poller/tracers/sysmon_etw.py +68 -0
  104. atomicshop/python_file_patcher.py +1 -1
  105. atomicshop/python_functions.py +27 -75
  106. atomicshop/question_answer_engine.py +2 -2
  107. atomicshop/scheduling.py +24 -5
  108. atomicshop/sound.py +4 -2
  109. atomicshop/speech_recognize.py +8 -0
  110. atomicshop/ssh_remote.py +158 -172
  111. atomicshop/startup/__init__.py +0 -0
  112. atomicshop/startup/win/__init__.py +0 -0
  113. atomicshop/startup/win/startup_folder.py +53 -0
  114. atomicshop/startup/win/task_scheduler.py +119 -0
  115. atomicshop/system_resource_monitor.py +61 -46
  116. atomicshop/system_resources.py +8 -8
  117. atomicshop/tempfiles.py +1 -2
  118. atomicshop/timer.py +30 -11
  119. atomicshop/urls.py +41 -0
  120. atomicshop/venvs.py +28 -0
  121. atomicshop/versioning.py +27 -0
  122. atomicshop/web.py +110 -25
  123. atomicshop/web_apis/__init__.py +0 -0
  124. atomicshop/web_apis/google_custom_search.py +44 -0
  125. atomicshop/web_apis/google_llm.py +188 -0
  126. atomicshop/websocket_parse.py +450 -0
  127. atomicshop/wrappers/certauthw/certauth.py +1 -0
  128. atomicshop/wrappers/cryptographyw.py +29 -8
  129. atomicshop/wrappers/ctyping/etw_winapi/__init__.py +0 -0
  130. atomicshop/wrappers/ctyping/etw_winapi/const.py +335 -0
  131. atomicshop/wrappers/ctyping/etw_winapi/etw_functions.py +393 -0
  132. atomicshop/wrappers/ctyping/file_details_winapi.py +67 -0
  133. atomicshop/wrappers/ctyping/msi_windows_installer/cabs.py +2 -1
  134. atomicshop/wrappers/ctyping/msi_windows_installer/extract_msi_main.py +13 -9
  135. atomicshop/wrappers/ctyping/msi_windows_installer/tables.py +35 -0
  136. atomicshop/wrappers/ctyping/setup_device.py +466 -0
  137. atomicshop/wrappers/ctyping/win_console.py +39 -0
  138. atomicshop/wrappers/dockerw/dockerw.py +113 -2
  139. atomicshop/wrappers/elasticsearchw/config_basic.py +0 -12
  140. atomicshop/wrappers/elasticsearchw/elastic_infra.py +75 -0
  141. atomicshop/wrappers/elasticsearchw/elasticsearchw.py +2 -20
  142. atomicshop/wrappers/factw/get_file_data.py +12 -5
  143. atomicshop/wrappers/factw/install/install_after_restart.py +89 -5
  144. atomicshop/wrappers/factw/install/pre_install_and_install_before_restart.py +20 -14
  145. atomicshop/wrappers/factw/postgresql/firmware.py +4 -6
  146. atomicshop/wrappers/githubw.py +583 -51
  147. atomicshop/wrappers/loggingw/consts.py +49 -0
  148. atomicshop/wrappers/loggingw/filters.py +102 -0
  149. atomicshop/wrappers/loggingw/formatters.py +58 -71
  150. atomicshop/wrappers/loggingw/handlers.py +459 -40
  151. atomicshop/wrappers/loggingw/loggers.py +19 -0
  152. atomicshop/wrappers/loggingw/loggingw.py +1010 -178
  153. atomicshop/wrappers/loggingw/reading.py +344 -19
  154. atomicshop/wrappers/mongodbw/__init__.py +0 -0
  155. atomicshop/wrappers/mongodbw/mongo_infra.py +31 -0
  156. atomicshop/wrappers/mongodbw/mongodbw.py +1432 -0
  157. atomicshop/wrappers/netshw.py +271 -0
  158. atomicshop/wrappers/playwrightw/engine.py +34 -19
  159. atomicshop/wrappers/playwrightw/infra.py +5 -0
  160. atomicshop/wrappers/playwrightw/javascript.py +7 -3
  161. atomicshop/wrappers/playwrightw/keyboard.py +14 -0
  162. atomicshop/wrappers/playwrightw/scenarios.py +172 -5
  163. atomicshop/wrappers/playwrightw/waits.py +9 -7
  164. atomicshop/wrappers/powershell_networking.py +80 -0
  165. atomicshop/wrappers/psutilw/processes.py +81 -0
  166. atomicshop/wrappers/psutilw/psutil_networks.py +85 -0
  167. atomicshop/wrappers/psutilw/psutilw.py +9 -0
  168. atomicshop/wrappers/pyopensslw.py +9 -2
  169. atomicshop/wrappers/pywin32w/__init__.py +0 -0
  170. atomicshop/wrappers/pywin32w/cert_store.py +116 -0
  171. atomicshop/wrappers/pywin32w/console.py +34 -0
  172. atomicshop/wrappers/pywin32w/win_event_log/__init__.py +0 -0
  173. atomicshop/wrappers/pywin32w/win_event_log/fetch.py +174 -0
  174. atomicshop/wrappers/pywin32w/win_event_log/subscribe.py +212 -0
  175. atomicshop/wrappers/pywin32w/win_event_log/subscribes/__init__.py +0 -0
  176. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_create.py +57 -0
  177. atomicshop/wrappers/pywin32w/win_event_log/subscribes/process_terminate.py +49 -0
  178. atomicshop/wrappers/pywin32w/win_event_log/subscribes/schannel_logging.py +97 -0
  179. atomicshop/wrappers/pywin32w/winshell.py +19 -0
  180. atomicshop/wrappers/pywin32w/wmis/__init__.py +0 -0
  181. atomicshop/wrappers/pywin32w/wmis/msft_netipaddress.py +113 -0
  182. atomicshop/wrappers/pywin32w/wmis/win32_networkadapterconfiguration.py +259 -0
  183. atomicshop/wrappers/pywin32w/wmis/win32networkadapter.py +112 -0
  184. atomicshop/wrappers/pywin32w/wmis/wmi_helpers.py +236 -0
  185. atomicshop/wrappers/socketw/accepter.py +21 -7
  186. atomicshop/wrappers/socketw/certificator.py +216 -150
  187. atomicshop/wrappers/socketw/creator.py +190 -50
  188. atomicshop/wrappers/socketw/dns_server.py +500 -173
  189. atomicshop/wrappers/socketw/exception_wrapper.py +45 -52
  190. atomicshop/wrappers/socketw/process_getter.py +86 -0
  191. atomicshop/wrappers/socketw/receiver.py +144 -102
  192. atomicshop/wrappers/socketw/sender.py +65 -35
  193. atomicshop/wrappers/socketw/sni.py +334 -165
  194. atomicshop/wrappers/socketw/socket_base.py +134 -0
  195. atomicshop/wrappers/socketw/socket_client.py +137 -95
  196. atomicshop/wrappers/socketw/socket_server_tester.py +14 -9
  197. atomicshop/wrappers/socketw/socket_wrapper.py +717 -116
  198. atomicshop/wrappers/socketw/ssl_base.py +15 -14
  199. atomicshop/wrappers/socketw/statistics_csv.py +148 -17
  200. atomicshop/wrappers/sysmonw.py +157 -0
  201. atomicshop/wrappers/ubuntu_terminal.py +65 -26
  202. atomicshop/wrappers/win_auditw.py +189 -0
  203. atomicshop/wrappers/winregw/__init__.py +0 -0
  204. atomicshop/wrappers/winregw/winreg_installed_software.py +58 -0
  205. atomicshop/wrappers/winregw/winreg_network.py +232 -0
  206. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/METADATA +31 -49
  207. atomicshop-3.10.5.dist-info/RECORD +306 -0
  208. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/WHEEL +1 -1
  209. atomicshop/_basics_temp.py +0 -101
  210. atomicshop/addons/a_setup_scripts/install_psycopg2_ubuntu.sh +0 -3
  211. atomicshop/addons/a_setup_scripts/install_pywintrace_0.3.cmd +0 -2
  212. atomicshop/addons/mains/install_docker_rootless_ubuntu.py +0 -11
  213. atomicshop/addons/mains/install_docker_ubuntu_main_sudo.py +0 -11
  214. atomicshop/addons/mains/install_elastic_search_and_kibana_ubuntu.py +0 -10
  215. atomicshop/addons/mains/install_wsl_ubuntu_lts_admin.py +0 -9
  216. atomicshop/addons/package_setup/CreateWheel.cmd +0 -7
  217. atomicshop/addons/package_setup/Setup in Edit mode.cmd +0 -6
  218. atomicshop/addons/package_setup/Setup.cmd +0 -7
  219. atomicshop/addons/process_list/compile.cmd +0 -2
  220. atomicshop/addons/process_list/compiled/Win10x64/process_list.dll +0 -0
  221. atomicshop/addons/process_list/compiled/Win10x64/process_list.exp +0 -0
  222. atomicshop/addons/process_list/compiled/Win10x64/process_list.lib +0 -0
  223. atomicshop/archiver/_search_in_zip.py +0 -189
  224. atomicshop/archiver/archiver.py +0 -34
  225. atomicshop/archiver/search_in_archive.py +0 -250
  226. atomicshop/archiver/sevenz_app_w.py +0 -86
  227. atomicshop/archiver/sevenzs.py +0 -44
  228. atomicshop/archiver/zips.py +0 -293
  229. atomicshop/etw/dns_trace.py +0 -118
  230. atomicshop/etw/etw.py +0 -61
  231. atomicshop/file_types.py +0 -24
  232. atomicshop/mitm/engines/create_module_template_example.py +0 -13
  233. atomicshop/mitm/initialize_mitm_server.py +0 -240
  234. atomicshop/monitor/checks/hash.py +0 -44
  235. atomicshop/monitor/checks/hash_checks/file.py +0 -55
  236. atomicshop/monitor/checks/hash_checks/url.py +0 -62
  237. atomicshop/pbtkmultifile_argparse.py +0 -88
  238. atomicshop/permissions.py +0 -110
  239. atomicshop/process_poller.py +0 -237
  240. atomicshop/script_as_string_processor.py +0 -38
  241. atomicshop/ssh_scripts/process_from_ipv4.py +0 -37
  242. atomicshop/ssh_scripts/process_from_port.py +0 -27
  243. atomicshop/wrappers/_process_wrapper_curl.py +0 -27
  244. atomicshop/wrappers/_process_wrapper_tar.py +0 -21
  245. atomicshop/wrappers/dockerw/install_docker.py +0 -209
  246. atomicshop/wrappers/elasticsearchw/infrastructure.py +0 -265
  247. atomicshop/wrappers/elasticsearchw/install_elastic.py +0 -232
  248. atomicshop/wrappers/ffmpegw.py +0 -125
  249. atomicshop/wrappers/loggingw/checks.py +0 -20
  250. atomicshop/wrappers/nodejsw/install_nodejs.py +0 -139
  251. atomicshop/wrappers/process_wrapper_pbtk.py +0 -16
  252. atomicshop/wrappers/socketw/base.py +0 -59
  253. atomicshop/wrappers/socketw/get_process.py +0 -107
  254. atomicshop/wrappers/wslw.py +0 -191
  255. atomicshop-2.11.47.dist-info/RECORD +0 -251
  256. /atomicshop/{addons/mains → a_mains}/FACT/factw_fact_extractor_docker_image_main_sudo.py +0 -0
  257. /atomicshop/{addons → a_mains/addons}/PlayWrightCodegen.cmd +0 -0
  258. /atomicshop/{addons → a_mains/addons}/ScriptExecution.cmd +0 -0
  259. /atomicshop/{addons/mains → a_mains/addons}/inits/init_to_import_all_modules.py +0 -0
  260. /atomicshop/{addons → a_mains/addons}/process_list/ReadMe.txt +0 -0
  261. /atomicshop/{addons/mains → a_mains}/search_for_hyperlinks_in_docx.py +0 -0
  262. /atomicshop/{archiver → etws}/__init__.py +0 -0
  263. /atomicshop/{etw → etws/traces}/__init__.py +0 -0
  264. /atomicshop/{monitor/checks/hash_checks → mitm/statistic_analyzer_helper}/__init__.py +0 -0
  265. /atomicshop/{wrappers/nodejsw → permissions}/__init__.py +0 -0
  266. /atomicshop/wrappers/pywin32w/{wmi_win32process.py → wmis/win32process.py} +0 -0
  267. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info/licenses}/LICENSE.txt +0 -0
  268. {atomicshop-2.11.47.dist-info → atomicshop-3.10.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,49 @@
1
+ DEFAULT_ROTATING_SUFFIXES_FROM_WHEN: dict = {
2
+ 'midnight': '%Y-%m-%d',
3
+ 'S': '%Y-%m-%d_%H-%M-%S',
4
+ 'M': '%Y-%m-%d_%H-%M',
5
+ 'H': '%Y-%m-%d_%H',
6
+ 'D': '%Y-%m-%d',
7
+ 'W0': '%Y-%m-%d',
8
+ 'W1': '%Y-%m-%d',
9
+ 'W2': '%Y-%m-%d',
10
+ 'W3': '%Y-%m-%d',
11
+ 'W4': '%Y-%m-%d',
12
+ 'W5': '%Y-%m-%d',
13
+ 'W6': '%Y-%m-%d'
14
+ }
15
+
16
+
17
+ DEFAULT_STREAM_FORMATTER: str = "%(asctime)s | %(levelname)s | %(threadName)s | %(name)s | %(message)s"
18
+ DEFAULT_MESSAGE_FORMATTER: str = "%(message)s"
19
+
20
+ FORMAT_ELEMENT_TO_HEADER: dict = {
21
+ 'asctime': 'Event Time [Y-M-D H:M:S]',
22
+ 'created': 'Created',
23
+ 'filename': "ModuleFileName ",
24
+ 'funcName': 'Function',
25
+ 'levelname': 'Log Level',
26
+ 'levelno': 'Level Number',
27
+ 'lineno': 'Line ',
28
+ 'module': 'Module',
29
+ 'msecs': '[MS.mS]',
30
+ 'message': 'Message',
31
+ 'name': 'Logger Name ',
32
+ 'pathname': 'Path',
33
+ 'process': 'Process',
34
+ 'processName': 'Process Name',
35
+ 'relativeCreated': 'Relative Created',
36
+ 'thread': 'Thread',
37
+ 'threadName': 'Thread Name'
38
+ }
39
+
40
+ DEFAULT_FORMATTER_TXT_FILE: str = \
41
+ "{asctime} | " \
42
+ "{levelname:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['levelname'])}" + "s} | " \
43
+ "{name:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['name'])}" + "s} | " \
44
+ "{filename:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['filename'])}" + "s} : " \
45
+ "{lineno:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['lineno'])}" + "d} | " \
46
+ "{threadName} | {message}"
47
+
48
+ DEFAULT_FORMATTER_CSV_FILE: str = \
49
+ '\"{asctime}\",{levelname},{name},{filename},{lineno},{threadName},\"{message}\"'
@@ -0,0 +1,102 @@
1
+ import logging
2
+ import threading
3
+ import os
4
+
5
+
6
+ from ...basics import ansi_escape_codes
7
+
8
+
9
+ class HeaderFilter(logging.Filter):
10
+ """
11
+ A logging.Filter that writes a header to a log file if the file is empty (
12
+ i.e., no log records have been written, i.e.2, on file rotation).
13
+ """
14
+
15
+ # noinspection PyPep8Naming
16
+ def __init__(self, header, baseFilename):
17
+ super().__init__()
18
+ self.header = header
19
+ self.baseFilename = baseFilename
20
+ self._write_header_if_needed()
21
+
22
+ def _write_header_if_needed(self):
23
+ if not os.path.exists(self.baseFilename) or os.path.getsize(self.baseFilename) == 0:
24
+ self._write_header()
25
+
26
+ def _write_header(self):
27
+ if self.header:
28
+ with open(self.baseFilename, 'a') as f:
29
+ f.write(self.header + '\n')
30
+
31
+ def filter(self, record):
32
+ self._write_header_if_needed()
33
+ return True
34
+
35
+
36
+ class ThreadColorLogFilter(logging.Filter):
37
+ """
38
+ A logging.Filter that adds color to log records based on the thread that emitted the log record.
39
+ """
40
+ def __init__(self, color: str, thread_id):
41
+ super().__init__()
42
+ self.color = color
43
+ self.thread_id = thread_id
44
+
45
+ def filter(self, record):
46
+ if threading.get_ident() == self.thread_id:
47
+ record.msg = (
48
+ ansi_escape_codes.get_colors_basic_dict(self.color) + record.msg +
49
+ ansi_escape_codes.ColorsBasic.END)
50
+ return True
51
+
52
+
53
+ """
54
+ A logging.Filter in Python's logging module is an object that provides a way to perform fine-grained
55
+ filtering of log records.
56
+ It allows you to control which log records are passed through and which are filtered out,
57
+ based on specific criteria you define.
58
+
59
+ Basic Concepts of logging.Filter
60
+ Purpose: Filters are used to allow or deny log records from being processed further.
61
+ This can be based on various criteria, such as the level of the log record, the source logger, or custom attributes.
62
+ Implementation: Filters are typically subclasses of logging.Filter,
63
+ but they can also be any callable that accepts a log record and returns a boolean value.
64
+
65
+ How logging.Filter Works
66
+ When a log record is emitted, it is passed through any filters attached to the logger or the handler.
67
+ If the filter returns True, the log record is processed. If the filter returns False, the log record is ignored.
68
+
69
+ Example of logging.Filter
70
+ Here’s a simple example to demonstrate the use of logging.Filter:
71
+
72
+ Create a Filter: Subclass logging.Filter and override the filter method.
73
+ import logging
74
+
75
+ class MyFilter(logging.Filter):
76
+ def filter(self, record):
77
+ # Example: Allow only log records with a level of WARNING or higher
78
+ return record.levelno >= logging.WARNING
79
+
80
+ Attach the Filter to a Handler or Logger:
81
+ # Create a logger
82
+ logger = logging.getLogger('my_logger')
83
+ logger.setLevel(logging.DEBUG)
84
+
85
+ # Create a console handler
86
+ console_handler = logging.StreamHandler()
87
+
88
+ # Create an instance of the custom filter
89
+ my_filter = MyFilter()
90
+
91
+ # Add the filter to the handler
92
+ console_handler.addFilter(my_filter)
93
+
94
+ # Add the handler to the logger
95
+ logger.addHandler(console_handler)
96
+
97
+ # Log some messages
98
+ logger.debug('This is a debug message') # Will be filtered out
99
+ logger.info('This is an info message') # Will be filtered out
100
+ logger.warning('This is a warning message') # Will be displayed
101
+ logger.error('This is an error message') # Will be displayed
102
+ """
@@ -1,4 +1,7 @@
1
1
  import logging
2
+ import time
3
+
4
+ from . import consts
2
5
 
3
6
 
4
7
  # Log formatter, means how the log will look inside the file
@@ -8,63 +11,33 @@ import logging
8
11
 
9
12
  # ".40" truncating the string to only 40 characters. Example: %(message).250s
10
13
 
11
- # Adding '%(asctime)s.%(msecs)06f' will print milliseconds as well as nanoseconds:
12
- # 2022-02-17 15:15:51,913.335562
13
- # If you don't use custom 'datefmt' in your 'setFormatter' function,
14
- # it will print duplicate milliseconds:
15
- # 2022-02-17 15:15:51,913.913.335562
16
- # The setting should be like:
17
- # file_handler.setFormatter(logging.Formatter(log_formatter_file, datefmt='%Y-%m-%d,%H:%M:%S'))
18
- # 's' stands for string. 'd' stands for digits, a.k.a. 'int'. 'f' stands for float.
19
-
20
- # Old tryouts:
21
- # log_formatter_file: str = f"%(asctime)s.%(msecs)06f | " \
22
- # log_formatter_file: str = f"%(asctime)s.%(msecs) | " \
23
- # f"%(levelname)-{len(log_header_level)}s | " \
24
- # f"%(name)-{len(log_header_logger)}s | " \
25
- # f"%(filename)-{len(log_header_script)}s : " \
26
- # f"%(lineno)-{len(log_header_line)}d | " \
27
- # "%(threadName)s: %(message)s"
28
- # log_formatter_file: str = "{asctime}.{msecs:0<3.0f} | " \
29
- # log_formatter_file: str = "{asctime}.{msecs:0>3.0f}.{msecs:0>.6f} | " \
30
-
31
- # Old tryouts for reference:
32
- # file_formatter = logging.Formatter(log_formatter_file, style='{')
33
- # file_formatter.default_time_format = '%Y-%m-%d %H:%M:%S'
34
- # file_formatter.default_msec_format = '%s,%03d'
35
- # file_formatter.default_msec_format = '%s,%03f'
36
-
37
-
38
- FORMAT_ELEMENT_TO_HEADER: dict = {
39
- 'asctime': 'Event Time [Y-M-D H:M:S]',
40
- 'created': 'Created',
41
- 'filename': "ModuleFileName ",
42
- 'funcName': 'Function',
43
- 'levelname': 'Log Level',
44
- 'levelno': 'Level Number',
45
- 'lineno': 'Line ',
46
- 'module': 'Module',
47
- 'msecs': '[MS.mS]',
48
- 'message': 'Message',
49
- 'name': 'Logger Name ',
50
- 'pathname': 'Path',
51
- 'process': 'Process',
52
- 'processName': 'Process Name',
53
- 'relativeCreated': 'Relative Created',
54
- 'thread': 'Thread',
55
- 'threadName': 'Thread Name'
56
- }
57
-
58
- DEFAULT_FORMATTER_TXT_FILE: str = \
59
- "{asctime},{msecs:013.9f} | " \
60
- "{levelname:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['levelname'])}" + "s} | " \
61
- "{name:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['name'])}" + "s} | " \
62
- "{filename:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['filename'])}" + "s} : " \
63
- "{lineno:<" + f"{len(FORMAT_ELEMENT_TO_HEADER['lineno'])}" + "d} | " \
64
- "{threadName} | {message}"
65
-
66
- DEFAULT_FORMATTER_CSV_FILE: str = \
67
- '\"{asctime}.{msecs:010.6f}\",{levelname},{name},{filename},{lineno},{threadName},\"{message}\"'
14
+
15
+ class NanosecondsFormatter(logging.Formatter):
16
+ def __init__(self, fmt=None, datefmt=None, style='%', use_nanoseconds=False):
17
+ super().__init__(fmt, datefmt, style)
18
+ self.use_nanoseconds = use_nanoseconds
19
+
20
+ def formatTime(self, record, datefmt=None):
21
+ ct = self.converter(record.created)
22
+
23
+ if datefmt:
24
+ # Remove unsupported %f from datefmt if present
25
+ if '%f' in datefmt:
26
+ datefmt = datefmt.replace('%f', '')
27
+ self.use_nanoseconds = True
28
+ else:
29
+ # Default time format if datefmt is not provided
30
+ datefmt = '%Y-%m-%d %H:%M:%S'
31
+
32
+ s = time.strftime(datefmt, ct)
33
+
34
+ if self.use_nanoseconds:
35
+ # Calculate nanoseconds from the fractional part of the timestamp
36
+ nanoseconds = f'{record.created:.9f}'.split('.')[1]
37
+ # Return the formatted string with nanoseconds appended
38
+ return f'{s}.{nanoseconds}'
39
+ else:
40
+ return s
68
41
 
69
42
 
70
43
  class FormatterProcessor:
@@ -144,13 +117,17 @@ class FormatterProcessor:
144
117
  # Iterate through all the elements and get the header list.
145
118
  header_dict: dict = dict()
146
119
  for element in self.list_of_elements:
147
- header_dict.update({element: FORMAT_ELEMENT_TO_HEADER[element]})
120
+ header_dict.update({element: consts.FORMAT_ELEMENT_TO_HEADER[element]})
148
121
 
149
122
  return header_dict
150
123
 
151
124
 
152
125
  def get_logging_formatter_from_string(
153
- formatter: str, style=None, datefmt=None, disable_duplicate_ms: bool = False) -> logging.Formatter:
126
+ formatter: str,
127
+ style=None,
128
+ datefmt=None,
129
+ use_nanoseconds: bool = False
130
+ ) -> logging.Formatter:
154
131
  """
155
132
  Function to get the logging formatter from the string.
156
133
 
@@ -160,12 +137,12 @@ def get_logging_formatter_from_string(
160
137
  '%': will use the '%' style.
161
138
  '{': will use the '{' style.
162
139
  :param datefmt: string, date format of 'asctime' element. Default is None.
163
- :param disable_duplicate_ms: bool, if True, will disable the duplicate milliseconds in the 'asctime' element.
164
- Example: If we're using '%(asctime)s.%(msecs)06f' msecs value in our time stamp, we need to use custom
165
- 'datefmt' to get rid of the additional duplicate milliseconds:
166
- Instead of '2022-02-17 15:15:51,913.913.335562' print '2022-02-17 15:15:51,913.335562'
167
- The problem with this method is that milliseconds aren't adjusted to 3 digits with zeroes (like 1 = 001).
168
- We can use the regular strftime format: datefmt='%Y-%m-%d,%H:%M:%S:%f'
140
+ We use custom formatter that can process the date format with nanoseconds:
141
+ '%Y-%m-%d %H:%M:%S.%f' -> '2021-01-01 00:00:00.000000000'
142
+ :param use_nanoseconds: bool, if set to True, the formatter will use nanoseconds instead of milliseconds.
143
+ This will print 'asctime' in the following format: '2021-01-01 00:00:00.000000000', instead of
144
+ '2021-01-01 00:00:00.000'.
145
+
169
146
  :return: logging.Formatter, formatter.
170
147
  """
171
148
 
@@ -173,10 +150,20 @@ def get_logging_formatter_from_string(
173
150
  if not style:
174
151
  style = FormatterProcessor(formatter).get_style()['style']
175
152
 
176
- # The regular 'datefmt' is '%Y-%m-%d,%H:%M:%S:%f'. If we want to use it with milliseconds 'msecs' element,
177
- # we need to disable the duplicate milliseconds.
178
- if disable_duplicate_ms:
179
- datefmt = '%Y-%m-%d,%H:%M:%S'
180
-
181
153
  # Create the logging formatter.
182
- return logging.Formatter(formatter, style=style, datefmt=datefmt)
154
+ if use_nanoseconds or '%f' in datefmt:
155
+ return NanosecondsFormatter(formatter, style=style, datefmt=datefmt, use_nanoseconds=use_nanoseconds)
156
+ else:
157
+ return logging.Formatter(formatter, style=style, datefmt=datefmt)
158
+
159
+
160
+ def get_formatter_string(formatter) -> str:
161
+ """
162
+ Function to get the formatter string from the 'logging.Formatter'.
163
+
164
+ :param formatter: logging.Formatter, formatter to convert to string.
165
+ :return: str, formatter string.
166
+ """
167
+
168
+ # noinspection PyProtectedMember
169
+ return formatter._fmt