atomicshop 2.14.4__py3-none-any.whl → 2.14.6__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.
Potentially problematic release.
This version of atomicshop might be problematic. Click here for more details.
- atomicshop/__init__.py +1 -1
- atomicshop/datetimes.py +66 -0
- atomicshop/mitm/config_editor.py +37 -0
- atomicshop/mitm/initialize_engines.py +8 -2
- atomicshop/mitm/initialize_mitm_server.py +54 -12
- atomicshop/print_api.py +3 -2
- atomicshop/wrappers/loggingw/formatters.py +66 -40
- atomicshop/wrappers/loggingw/handlers.py +268 -15
- atomicshop/wrappers/loggingw/loggingw.py +132 -251
- atomicshop/wrappers/loggingw/reading.py +2 -2
- atomicshop/wrappers/psutilw/networks.py +40 -0
- atomicshop/wrappers/socketw/dns_server.py +16 -2
- {atomicshop-2.14.4.dist-info → atomicshop-2.14.6.dist-info}/METADATA +1 -1
- {atomicshop-2.14.4.dist-info → atomicshop-2.14.6.dist-info}/RECORD +17 -15
- {atomicshop-2.14.4.dist-info → atomicshop-2.14.6.dist-info}/LICENSE.txt +0 -0
- {atomicshop-2.14.4.dist-info → atomicshop-2.14.6.dist-info}/WHEEL +0 -0
- {atomicshop-2.14.4.dist-info → atomicshop-2.14.6.dist-info}/top_level.txt +0 -0
|
@@ -1,83 +1,34 @@
|
|
|
1
|
-
import os
|
|
2
1
|
import logging
|
|
3
|
-
import
|
|
2
|
+
import os
|
|
3
|
+
from typing import Literal, Union
|
|
4
4
|
|
|
5
5
|
from . import loggers, handlers, formatters
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
def
|
|
9
|
-
"""
|
|
10
|
-
Function to get a logger and set logging level.
|
|
11
|
-
|
|
12
|
-
:param logger_name: Name of the logger.
|
|
13
|
-
:param logging_level: 'int' or 'str', Logging level to set to the logger.
|
|
14
|
-
None: if None, the logger level will not be set.
|
|
15
|
-
:return: Logger.
|
|
16
|
-
"""
|
|
17
|
-
|
|
18
|
-
# Get the logger.
|
|
19
|
-
logger: logging.Logger = loggers.get_logger(logger_name)
|
|
20
|
-
# Set the logger level if it is not None.
|
|
21
|
-
if logging_level:
|
|
22
|
-
loggers.set_logging_level(logger, logging_level)
|
|
23
|
-
|
|
24
|
-
return logger
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
def get_logger_with_stream_handler(
|
|
28
|
-
logger_name: str, logging_level="DEBUG",
|
|
29
|
-
formatter: str = "%(levelname)s | %(threadName)s | %(name)s | %(message)s"
|
|
30
|
-
) -> logging.Logger:
|
|
31
|
-
"""
|
|
32
|
-
Function to get a logger and add StreamHandler to it.
|
|
33
|
-
|
|
34
|
-
:param logger_name: Name of the logger.
|
|
35
|
-
:param logging_level: 'int' or 'str', Logging level to set to the logger.
|
|
36
|
-
None: if None, the logger level will not be set.
|
|
37
|
-
:param formatter: Formatter to use for StreamHandler. It is template of how a message will look like.
|
|
38
|
-
:return: Logger.
|
|
39
|
-
"""
|
|
40
|
-
|
|
41
|
-
# Get the logger.
|
|
42
|
-
logger: logging.Logger = loggers.get_logger(logger_name)
|
|
43
|
-
# Set the logger level if it is not None.
|
|
44
|
-
if logging_level:
|
|
45
|
-
loggers.set_logging_level(logger, logging_level)
|
|
46
|
-
# Add StreamHandler to the logger.
|
|
47
|
-
add_stream_handler(logger, logging_level, formatter)
|
|
48
|
-
|
|
49
|
-
return logger
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def get_logger_with_timedfilehandler(
|
|
8
|
+
def create_logger(
|
|
53
9
|
logger_name: str,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
formatter_message_only, disable_duplicate_ms, when, interval, delay, encoding
|
|
63
|
-
)
|
|
64
|
-
|
|
65
|
-
return logger
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
def get_logger_with_stream_handler_and_timedfilehandler(
|
|
69
|
-
logger_name: str,
|
|
70
|
-
directory_path,
|
|
71
|
-
file_name: str = None,
|
|
72
|
-
file_extension: str = '.txt',
|
|
10
|
+
file_path: str = None,
|
|
11
|
+
directory_path: str = None,
|
|
12
|
+
add_stream: bool = False,
|
|
13
|
+
add_timedfile: bool = False,
|
|
14
|
+
file_type: Literal[
|
|
15
|
+
'txt',
|
|
16
|
+
'csv',
|
|
17
|
+
'json'] = 'txt',
|
|
73
18
|
logging_level="DEBUG",
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
19
|
+
formatter_streamhandler: Union[
|
|
20
|
+
Literal['MESSAGE', 'DEFAULT'],
|
|
21
|
+
str,
|
|
22
|
+
None] = None,
|
|
23
|
+
formatter_filehandler: Union[
|
|
24
|
+
Literal['MESSAGE', 'DEFAULT'],
|
|
25
|
+
str,
|
|
26
|
+
None] = None,
|
|
27
|
+
formatter_streamhandler_use_nanoseconds: bool = True,
|
|
28
|
+
formatter_filehandler_use_nanoseconds: bool = True,
|
|
78
29
|
when: str = "midnight",
|
|
79
30
|
interval: int = 1,
|
|
80
|
-
delay: bool =
|
|
31
|
+
delay: bool = False,
|
|
81
32
|
encoding=None,
|
|
82
33
|
header: str = None
|
|
83
34
|
) -> logging.Logger:
|
|
@@ -85,26 +36,37 @@ def get_logger_with_stream_handler_and_timedfilehandler(
|
|
|
85
36
|
Function to get a logger and add StreamHandler and TimedRotatingFileHandler to it.
|
|
86
37
|
|
|
87
38
|
:param logger_name: Name of the logger.
|
|
88
|
-
:param
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
:param
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
39
|
+
:param file_path: full path to the log file. If you don't want to use the file, set it to None.
|
|
40
|
+
You can set the directory_path only and then the 'logger_name' will be used as the file name with the
|
|
41
|
+
'file_type' as the file extension.
|
|
42
|
+
:param directory_path: full path to the directory where the log file will be saved.
|
|
43
|
+
:param add_stream: bool, If set to True, StreamHandler will be added to the logger.
|
|
44
|
+
:param add_timedfile: bool, If set to True, TimedRotatingFileHandler will be added to the logger.
|
|
45
|
+
:param file_type: string, file type of the log file. Default is 'txt'.
|
|
46
|
+
'txt': Text file.
|
|
47
|
+
'csv': CSV file.
|
|
48
|
+
'json': JSON file.
|
|
95
49
|
:param logging_level: str or int, Logging level for the handler, that will use the logger while initiated.
|
|
50
|
+
:param formatter_streamhandler: string, Formatter to use for StreamHandler. It is template of how a message will
|
|
51
|
+
look like.
|
|
52
|
+
None: No formatter will be used.
|
|
53
|
+
'DEFAULT': Default formatter will be used:
|
|
54
|
+
"%(levelname)s | %(threadName)s | %(name)s | %(message)s"
|
|
55
|
+
'MESSAGE': Formatter will be used only for the 'message' part.
|
|
56
|
+
string: Custom formatter, regular syntax for logging.Formatter.
|
|
96
57
|
:param formatter_filehandler: string, Formatter to use for handler. It is template of how a message will look like.
|
|
97
58
|
None: No formatter will be used.
|
|
98
|
-
'
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
59
|
+
'DEFAULT': Default formatter will be used for each file extension:
|
|
60
|
+
txt: "%(asctime)s | %(levelname)s | %(threadName)s | %(name)s | %(message)s"
|
|
61
|
+
csv: "%(asctime)s,%(levelname)s,%(threadName)s,%(name)s,%(message)s"
|
|
62
|
+
json: '{"time": "%(asctime)s", "level": "%(levelname)s", "thread": "%(threadName)s",
|
|
102
63
|
"logger": "%(name)s", "message": "%(message)s"}'
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
:param
|
|
106
|
-
|
|
107
|
-
|
|
64
|
+
'MESSAGE': Formatter will be used only for the 'message' part.
|
|
65
|
+
string: Custom formatter, regular syntax for logging.Formatter.
|
|
66
|
+
:param formatter_streamhandler_use_nanoseconds: bool, If set to True, the nanoseconds will be used
|
|
67
|
+
in the formatter in case you provide 'asctime' element.
|
|
68
|
+
:param formatter_filehandler_use_nanoseconds: bool, If set to True, the nanoseconds will be used
|
|
69
|
+
in the formatter in case you provide 'asctime' element.
|
|
108
70
|
:param when: string, When to rotate the log file. Default is 'midnight'.
|
|
109
71
|
[when="midnight"] is set to rotate the filename at midnight. This means that the current file name will be
|
|
110
72
|
added Yesterday's date to the end of the file and today's file will continue to write at the same
|
|
@@ -119,6 +81,7 @@ def get_logger_with_stream_handler_and_timedfilehandler(
|
|
|
119
81
|
:param encoding: string, Encoding to use for the log file. Default is None.
|
|
120
82
|
:param header: string, Header to write to the log file.
|
|
121
83
|
Example: "time,host,error"
|
|
84
|
+
Useful for 'csv' file type format.
|
|
122
85
|
|
|
123
86
|
:return: Logger.
|
|
124
87
|
|
|
@@ -130,198 +93,97 @@ def get_logger_with_stream_handler_and_timedfilehandler(
|
|
|
130
93
|
|
|
131
94
|
def main():
|
|
132
95
|
header: str = "time,host,error"
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
error_logger = loggingw.
|
|
136
|
-
logger_name=
|
|
137
|
-
|
|
96
|
+
output_log_file: str = "D:\\logs\\log_file.csv"
|
|
97
|
+
|
|
98
|
+
error_logger = loggingw.create_logger(
|
|
99
|
+
logger_name=f'{self.__class__.__name__}_CSV',
|
|
100
|
+
file_path=output_log_file,
|
|
101
|
+
add_timedfile=True,
|
|
102
|
+
file_type='csv',
|
|
103
|
+
formatter_filehandler='MESSAGE',
|
|
104
|
+
header=header
|
|
138
105
|
)
|
|
139
106
|
|
|
140
|
-
error_logger.info(
|
|
107
|
+
error_logger.info(error_message)
|
|
141
108
|
|
|
142
109
|
|
|
143
110
|
if __name__ == "__main__":
|
|
144
111
|
main()
|
|
145
|
-
"""
|
|
146
|
-
logger = get_logger_with_level(logger_name, logging_level)
|
|
147
|
-
add_stream_handler(logger, logging_level, formatter_streamhandler, formatter_message_only)
|
|
148
|
-
add_timedfilehandler_with_queuehandler(
|
|
149
|
-
logger, directory_path, file_name, file_extension, logging_level, formatter_filehandler,
|
|
150
|
-
formatter_message_only, disable_duplicate_ms, when, interval, delay, encoding, header
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
return logger
|
|
154
112
|
|
|
113
|
+
------------------------------
|
|
155
114
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
formatter: str = "%(levelname)s | %(threadName)s | %(name)s | %(message)s",
|
|
159
|
-
formatter_message_only: bool = False
|
|
160
|
-
):
|
|
161
|
-
"""
|
|
162
|
-
Function to add StreamHandler to logger.
|
|
163
|
-
Stream formatter will output messages to the console.
|
|
164
|
-
|
|
165
|
-
:param logger: Logger to add the handler to.
|
|
166
|
-
:param logging_level: Logging level for the handler, that will use the logger while initiated.
|
|
167
|
-
:param formatter: Formatter to use for StreamHandler. It is template of how a message will look like.
|
|
168
|
-
None: No formatter will be used.
|
|
169
|
-
'default': Default formatter will be used:
|
|
170
|
-
"%(levelname)s | %(threadName)s | %(name)s | %(message)s"
|
|
171
|
-
:param formatter_message_only: bool, If set to True, formatter will be used only for the 'message' part.
|
|
172
|
-
"""
|
|
173
|
-
|
|
174
|
-
# Getting the StreamHandler.
|
|
175
|
-
stream_handler = handlers.get_stream_handler()
|
|
176
|
-
# Setting log level for the handler, that will use the logger while initiated.
|
|
177
|
-
loggers.set_logging_level(stream_handler, logging_level)
|
|
178
|
-
|
|
179
|
-
# If formatter_message_only is set to True, then formatter will be used only for the 'message' part.
|
|
180
|
-
if formatter_message_only:
|
|
181
|
-
formatter = "%(message)s"
|
|
115
|
+
Example to use StreamHandler to output to console and TimedRotatingFileHandler to write to file:
|
|
116
|
+
from atomicshop.wrappers.loggingw import loggingw
|
|
182
117
|
|
|
183
|
-
# If formatter was provided, then it will be used.
|
|
184
|
-
if formatter:
|
|
185
|
-
logging_formatter = formatters.get_logging_formatter_from_string(formatter)
|
|
186
|
-
handlers.set_formatter(stream_handler, logging_formatter)
|
|
187
118
|
|
|
188
|
-
|
|
189
|
-
|
|
119
|
+
def main():
|
|
120
|
+
header: str = "time,host,error"
|
|
121
|
+
output_log_file: str = "D:\\logs\\log_file.txt"
|
|
122
|
+
|
|
123
|
+
error_logger = loggingw.create_logger(
|
|
124
|
+
logger_name=f'{self.__class__.__name__}',
|
|
125
|
+
file_path=output_log_file,
|
|
126
|
+
add_stream=True,
|
|
127
|
+
add_timedfile=True,
|
|
128
|
+
file_type='txt',
|
|
129
|
+
formatter_streamhandler='DEFAULT',
|
|
130
|
+
formatter_filehandler='DEFAULT'
|
|
131
|
+
)
|
|
190
132
|
|
|
191
|
-
|
|
192
|
-
loggers.set_propagation(logger)
|
|
133
|
+
error_logger.info(f"{datetime.now()},host1,/path/to/file,error message")
|
|
193
134
|
|
|
194
135
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
directory_path: str,
|
|
198
|
-
file_name_no_extension: str = None,
|
|
199
|
-
file_extension: str = '.txt',
|
|
200
|
-
logging_level="DEBUG",
|
|
201
|
-
formatter='default',
|
|
202
|
-
formatter_message_only: bool = False,
|
|
203
|
-
disable_duplicate_ms: bool = False,
|
|
204
|
-
when: str = 'midnight',
|
|
205
|
-
interval: int = 1,
|
|
206
|
-
delay: bool = True,
|
|
207
|
-
encoding=None,
|
|
208
|
-
header: str = None
|
|
209
|
-
):
|
|
210
|
-
"""
|
|
211
|
-
Function to add TimedRotatingFileHandler and QueueHandler to logger.
|
|
212
|
-
TimedRotatingFileHandler will output messages to the file through QueueHandler.
|
|
213
|
-
This is needed, since TimedRotatingFileHandler is not thread-safe, though official docs say it is.
|
|
214
|
-
|
|
215
|
-
:param logger: Logger to add the handler to.
|
|
216
|
-
:param directory_path: string, Path to the directory where the log file will be created.
|
|
217
|
-
:param file_name_no_extension: string, Name of the log file without file extension, since we add it through
|
|
218
|
-
separate argument. If not provided, logger name will be used.
|
|
219
|
-
:param file_extension: string, Extension of the log file. Default is '.txt'.
|
|
220
|
-
:param logging_level: str or int, Logging level for the handler, that will use the logger while initiated.
|
|
221
|
-
:param formatter: string, Formatter to use for handler. It is template of how a message will look like.
|
|
222
|
-
None: No formatter will be used.
|
|
223
|
-
'default': Default formatter will be used for each file extension:
|
|
224
|
-
.txt: "%(asctime)s | %(levelname)s | %(threadName)s | %(name)s | %(message)s"
|
|
225
|
-
.csv: "%(asctime)s,%(levelname)s,%(threadName)s,%(name)s,%(message)s"
|
|
226
|
-
.json: '{"time": "%(asctime)s", "level": "%(levelname)s", "thread": "%(threadName)s",
|
|
227
|
-
"logger": "%(name)s", "message": "%(message)s"}'
|
|
228
|
-
:param formatter_message_only: bool, If set to True, formatter will be used only for the 'message' part.
|
|
229
|
-
:param disable_duplicate_ms: bool, If set to True, duplicate milliseconds will be removed from formatter
|
|
230
|
-
'asctime' element.
|
|
231
|
-
:param when: string, When to rotate the log file. Default is 'midnight'.
|
|
232
|
-
[when="midnight"] is set to rotate the filename at midnight. This means that the current file name will be
|
|
233
|
-
added Yesterday's date to the end of the file and today's file will continue to write at the same
|
|
234
|
-
filename. Also, if the script finished working on 25.11.2021, the name of the log file will be "test.log"
|
|
235
|
-
If you run the script again on 28.11.2021, the logging module will take the last modification date of
|
|
236
|
-
the file "test.log" and assign a date to it: test.log.2021_11_25
|
|
237
|
-
The log filename of 28.11.2021 will be called "test.log" again.
|
|
238
|
-
:param interval: int, Interval to rotate the log file. Default is 1.
|
|
239
|
-
If 'when="midnight"' and 'interval=1', then the log file will be rotated every midnight.
|
|
240
|
-
If 'when="midnight"' and 'interval=2', then the log file will be rotated every 2nd midnights.
|
|
241
|
-
:param delay: bool, If set to True, the log file will be created only if there's something to write.
|
|
242
|
-
:param encoding: string, Encoding to use for the log file. Default is None.
|
|
243
|
-
:param header: string, Header to write to the log file.
|
|
244
|
-
Example: "time,host,error"
|
|
136
|
+
if __name__ == "__main__":
|
|
137
|
+
main()
|
|
245
138
|
"""
|
|
246
139
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
# Set log file path.
|
|
252
|
-
log_file_path = f'{directory_path}{os.sep}{file_name_no_extension}{file_extension}'
|
|
253
|
-
|
|
254
|
-
# Setting the TimedRotatingFileHandler, without adding it to the logger.
|
|
255
|
-
# It will be added to the QueueListener, which will use the TimedRotatingFileHandler to write logs.
|
|
256
|
-
# This is needed since there's a bug in TimedRotatingFileHandler, which won't let it be used with
|
|
257
|
-
# threads the same way it would be used for multiprocess.
|
|
258
|
-
|
|
259
|
-
# Creating file handler with log filename. At this stage the log file is created and locked by the handler,
|
|
260
|
-
# Unless we use "delay=True" to tell the class to write the file only if there's something to write.
|
|
261
|
-
|
|
262
|
-
if file_extension == ".csv":
|
|
263
|
-
# If file extension is CSV, we'll set the header to the file.
|
|
264
|
-
# This is needed since the CSV file will be rotated, and we'll need to set the header each time.
|
|
265
|
-
# We'll use the custom TimedRotatingFileHandlerWithHeader class.
|
|
266
|
-
file_handler = handlers.get_timed_rotating_file_handler_with_header(
|
|
267
|
-
log_file_path, when=when, interval=interval, delay=delay, encoding=encoding, header=header)
|
|
268
|
-
else:
|
|
269
|
-
file_handler = handlers.get_timed_rotating_file_handler(
|
|
270
|
-
log_file_path, when=when, interval=interval, delay=delay, encoding=encoding)
|
|
271
|
-
|
|
272
|
-
loggers.set_logging_level(file_handler, logging_level)
|
|
273
|
-
|
|
274
|
-
if formatter == "default":
|
|
275
|
-
# Create file formatter based on extension
|
|
276
|
-
if file_extension == ".txt":
|
|
277
|
-
formatter = formatters.DEFAULT_FORMATTER_TXT_FILE
|
|
278
|
-
elif file_extension == ".csv":
|
|
279
|
-
formatter = formatters.DEFAULT_FORMATTER_CSV_FILE
|
|
280
|
-
elif file_extension == ".json":
|
|
281
|
-
formatter = "%(message)s"
|
|
140
|
+
if not directory_path and not file_path:
|
|
141
|
+
raise ValueError("You need to provide 'directory_path' or 'file_path'.")
|
|
142
|
+
if directory_path and file_path:
|
|
143
|
+
raise ValueError("You can't provide both 'directory_path' and 'file_path'.")
|
|
282
144
|
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
145
|
+
if directory_path:
|
|
146
|
+
if directory_path.endswith(os.sep):
|
|
147
|
+
directory_path = directory_path[:-1]
|
|
286
148
|
|
|
287
|
-
|
|
288
|
-
if formatter:
|
|
289
|
-
# Convert string to Formatter object. Moved to newer styling of python 3: style='{'
|
|
290
|
-
logging_formatter = formatters.get_logging_formatter_from_string(
|
|
291
|
-
formatter, disable_duplicate_ms=disable_duplicate_ms)
|
|
292
|
-
# Setting the formatter in file handler.
|
|
293
|
-
handlers.set_formatter(file_handler, logging_formatter)
|
|
149
|
+
file_path = f"{directory_path}{os.sep}{logger_name}.{file_type}"
|
|
294
150
|
|
|
295
|
-
|
|
296
|
-
handlers.change_rotated_filename(file_handler, file_extension)
|
|
151
|
+
logger = get_logger_with_level(logger_name, logging_level)
|
|
297
152
|
|
|
298
|
-
|
|
299
|
-
|
|
153
|
+
if add_stream:
|
|
154
|
+
handlers.add_stream_handler(
|
|
155
|
+
logger=logger, logging_level=logging_level, formatter=formatter_streamhandler,
|
|
156
|
+
formatter_use_nanoseconds=formatter_streamhandler_use_nanoseconds)
|
|
300
157
|
|
|
301
|
-
|
|
302
|
-
|
|
158
|
+
if add_timedfile:
|
|
159
|
+
handlers.add_timedfilehandler_with_queuehandler(
|
|
160
|
+
logger=logger, file_path=file_path, logging_level=logging_level, formatter=formatter_filehandler,
|
|
161
|
+
formatter_use_nanoseconds=formatter_filehandler_use_nanoseconds, file_type=file_type,
|
|
162
|
+
when=when, interval=interval, delay=delay, encoding=encoding, header=header)
|
|
303
163
|
|
|
304
|
-
|
|
305
|
-
loggers.set_propagation(logger)
|
|
164
|
+
return logger
|
|
306
165
|
|
|
307
166
|
|
|
308
|
-
def
|
|
167
|
+
def get_logger_with_level(
|
|
168
|
+
logger_name: str,
|
|
169
|
+
logging_level="DEBUG"
|
|
170
|
+
) -> logging.Logger:
|
|
309
171
|
"""
|
|
310
|
-
Function to
|
|
311
|
-
QueueHandler will get the logs from the Queue and put them to the file that was set in the FileHandler.
|
|
172
|
+
Function to get a logger and set logging level.
|
|
312
173
|
|
|
313
|
-
:param
|
|
314
|
-
:
|
|
174
|
+
:param logger_name: Name of the logger.
|
|
175
|
+
:param logging_level: 'int' or 'str', Logging level to set to the logger.
|
|
176
|
+
None: if None, the logger level will not be set.
|
|
177
|
+
:return: Logger.
|
|
315
178
|
"""
|
|
316
179
|
|
|
317
|
-
#
|
|
318
|
-
|
|
319
|
-
#
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
handlers.start_queue_listener_for_file_handler(file_handler, queue_object)
|
|
180
|
+
# Get the logger.
|
|
181
|
+
logger: logging.Logger = loggers.get_logger(logger_name)
|
|
182
|
+
# Set the logger level if it is not None.
|
|
183
|
+
if logging_level:
|
|
184
|
+
loggers.set_logging_level(logger, logging_level)
|
|
323
185
|
|
|
324
|
-
return
|
|
186
|
+
return logger
|
|
325
187
|
|
|
326
188
|
|
|
327
189
|
def disable_default_logger():
|
|
@@ -340,3 +202,22 @@ def disable_default_logger():
|
|
|
340
202
|
|
|
341
203
|
# Disabling the default logger in Python
|
|
342
204
|
logging.disable(logging.CRITICAL)
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def get_datetime_format_string_from_logger_file_handlers(logger: logging.Logger) -> list:
|
|
208
|
+
"""
|
|
209
|
+
Function to get datetime format string from the logger's file handlers.
|
|
210
|
+
This is useful when you want to know the datetime format string that is used on file rotation.
|
|
211
|
+
:param logger: Logger to get the datetime format string from.
|
|
212
|
+
:return: List of datetime format strings.
|
|
213
|
+
"""
|
|
214
|
+
|
|
215
|
+
datetime_format_strings = []
|
|
216
|
+
|
|
217
|
+
for handler in logger.handlers:
|
|
218
|
+
if isinstance(handler, logging.FileHandler):
|
|
219
|
+
date_time_format_string = handlers.extract_datetime_format_from_file_handler(handler)
|
|
220
|
+
if date_time_format_string:
|
|
221
|
+
datetime_format_strings.append(date_time_format_string)
|
|
222
|
+
|
|
223
|
+
return datetime_format_strings
|
|
@@ -75,8 +75,8 @@ def get_logs_paths(
|
|
|
75
75
|
|
|
76
76
|
# Get the datetime object from the file name by the date pattern.
|
|
77
77
|
try:
|
|
78
|
-
datetime_object, date_string, timestamp_float =
|
|
79
|
-
current_file_name, date_pattern)
|
|
78
|
+
datetime_object, date_string, timestamp_float = (
|
|
79
|
+
datetimes.get_datetime_from_complex_string_by_pattern(current_file_name, date_pattern))
|
|
80
80
|
# ValueError will be raised if the date pattern does not match the file name.
|
|
81
81
|
except ValueError:
|
|
82
82
|
timestamp_float = 0
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
from typing import Union
|
|
2
|
+
import shlex
|
|
3
|
+
|
|
4
|
+
import psutil
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def get_process_using_port(port: int) -> Union[dict, None]:
|
|
8
|
+
"""
|
|
9
|
+
Function to find the process using the port.
|
|
10
|
+
:param port: Port number.
|
|
11
|
+
:return: dict['pid', 'name', 'cmdline'] or None.
|
|
12
|
+
"""
|
|
13
|
+
for proc in psutil.process_iter(['pid', 'name', 'cmdline']):
|
|
14
|
+
try:
|
|
15
|
+
connections = proc.connections(kind='inet')
|
|
16
|
+
for conn in connections:
|
|
17
|
+
if conn.laddr.port == port:
|
|
18
|
+
return {
|
|
19
|
+
'pid': proc.info['pid'],
|
|
20
|
+
'name': proc.info['name'],
|
|
21
|
+
'cmdline': shlex.join(proc.info['cmdline'])
|
|
22
|
+
}
|
|
23
|
+
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
24
|
+
pass
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_processes_using_port_list(ports: list) -> Union[dict, None]:
|
|
29
|
+
"""
|
|
30
|
+
Function to find the process using the port.
|
|
31
|
+
:param ports: List of port numbers.
|
|
32
|
+
:return: dict[port: {'pid', 'name', 'cmdline'}] or None.
|
|
33
|
+
"""
|
|
34
|
+
port_process_map = {}
|
|
35
|
+
for port in ports:
|
|
36
|
+
process_info = get_process_using_port(port)
|
|
37
|
+
if process_info:
|
|
38
|
+
port_process_map[port] = process_info
|
|
39
|
+
|
|
40
|
+
return port_process_map
|
|
@@ -6,11 +6,16 @@ import socket
|
|
|
6
6
|
|
|
7
7
|
from ...print_api import print_api
|
|
8
8
|
from ..loggingw import loggingw
|
|
9
|
+
from ..psutilw import networks
|
|
9
10
|
|
|
10
11
|
import dnslib
|
|
11
12
|
from dnslib import DNSRecord, DNSHeader, RR, A
|
|
12
13
|
|
|
13
14
|
|
|
15
|
+
class DnsPortInUseError(Exception):
|
|
16
|
+
pass
|
|
17
|
+
|
|
18
|
+
|
|
14
19
|
class DnsServer:
|
|
15
20
|
"""
|
|
16
21
|
DnsServer class is responsible to handle DNS Requests on port 53 based on configuration and send DNS Response back.
|
|
@@ -56,8 +61,12 @@ class DnsServer:
|
|
|
56
61
|
|
|
57
62
|
# Logger that logs all the DNS Requests and responses in DNS format. These entries will not present in
|
|
58
63
|
# network log of TCP Server module.
|
|
59
|
-
self.dns_full_logger = loggingw.
|
|
60
|
-
logger_name="dns",
|
|
64
|
+
self.dns_full_logger = loggingw.create_logger(
|
|
65
|
+
logger_name="dns",
|
|
66
|
+
directory_path=self.config['log']['logs_path'],
|
|
67
|
+
add_timedfile=True,
|
|
68
|
+
formatter_filehandler='DEFAULT'
|
|
69
|
+
)
|
|
61
70
|
|
|
62
71
|
def thread_worker_empty_dns_cache(self, function_sleep_time: int):
|
|
63
72
|
"""
|
|
@@ -78,6 +87,11 @@ class DnsServer:
|
|
|
78
87
|
:return: None.
|
|
79
88
|
"""
|
|
80
89
|
|
|
90
|
+
port_in_use = networks.get_processes_using_port_list([self.config['dns']['listening_port']])
|
|
91
|
+
if port_in_use:
|
|
92
|
+
for port, process_info in port_in_use.items():
|
|
93
|
+
raise DnsPortInUseError(f"Port [{port}] is already in use by process: {process_info}")
|
|
94
|
+
|
|
81
95
|
self.logger.info("DNS Server Module Started.")
|
|
82
96
|
|
|
83
97
|
# Define objects for global usage
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
atomicshop/__init__.py,sha256=
|
|
1
|
+
atomicshop/__init__.py,sha256=hybMlQ9qVeOgdPaVMdVvrp-rXkVt1Ifm1_zQ95KG2kM,123
|
|
2
2
|
atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
|
|
3
3
|
atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
|
|
4
4
|
atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
|
|
@@ -8,7 +8,7 @@ atomicshop/command_line_processing.py,sha256=u5yT9Ger_cu7ni5ID0VFlRbVD46ARHeNC9t
|
|
|
8
8
|
atomicshop/config_init.py,sha256=z2RXD_mw9nQlAOpuGry1h9QT-2LhNscXgGAktN3dCVQ,2497
|
|
9
9
|
atomicshop/console_output.py,sha256=AOSJjrRryE97PAGtgDL03IBtWSi02aNol8noDnW3k6M,4667
|
|
10
10
|
atomicshop/console_user_response.py,sha256=31HIy9QGXa7f-GVR8MzJauQ79E_ZqAeagF3Ks4GGdDU,3234
|
|
11
|
-
atomicshop/datetimes.py,sha256=
|
|
11
|
+
atomicshop/datetimes.py,sha256=Rmn-Ag36xRI1xbyoMs2fe1PB5hzb_UHEIwRVPppz0M0,18278
|
|
12
12
|
atomicshop/diff_check.py,sha256=RJvzJhyYAZyRPKVDk1dS7UwZCx0kq__WDZ6N0rNfZUY,27110
|
|
13
13
|
atomicshop/dns.py,sha256=h4uZKoz4wbBlLOOduL1GtRcTm-YpiPnGOEGxUm7hhOI,2140
|
|
14
14
|
atomicshop/domains.py,sha256=Rxu6JhhMqFZRcoFs69IoEd1PtYca0lMCG6F1AomP7z4,3197
|
|
@@ -26,7 +26,7 @@ atomicshop/keyboard_press.py,sha256=1W5kRtOB75fulVx-uF2yarBhW0_IzdI1k73AnvXstk0,
|
|
|
26
26
|
atomicshop/on_exit.py,sha256=Wf1iy2e0b0Zu7oRxrct3VkLdQ_x9B32-z_JerKTt9Z0,5493
|
|
27
27
|
atomicshop/pbtkmultifile_argparse.py,sha256=aEk8nhvoQVu-xyfZosK3ma17CwIgOjzO1erXXdjwtS4,4574
|
|
28
28
|
atomicshop/permissions.py,sha256=P6tiUKV-Gw-c3ePEVsst9bqWaHJbB4ZlJB4xbDYVpEs,4436
|
|
29
|
-
atomicshop/print_api.py,sha256=
|
|
29
|
+
atomicshop/print_api.py,sha256=j0bZ9b2rFKCcr0TVx1ARraVKeEs6JaaSgIlBdndy1nI,11600
|
|
30
30
|
atomicshop/process.py,sha256=U2gyRl0bw2138y-rOMABMVptRvAL81ZfX1JyfxJI_Oo,15973
|
|
31
31
|
atomicshop/python_file_patcher.py,sha256=kd3rBWvTcosLEk-7TycNdfKW9fZbe161iVwmH4niUo0,5515
|
|
32
32
|
atomicshop/python_functions.py,sha256=zJg4ogUwECxrDD7xdDN5JikIUctITM5lsyabr_ZNsRw,4435
|
|
@@ -120,10 +120,11 @@ atomicshop/file_io/xlsxs.py,sha256=v_dyg9GD4LqgWi6wA1QuWRZ8zG4ZwB6Dz52ytdcmmmI,2
|
|
|
120
120
|
atomicshop/file_io/xmls.py,sha256=zh3SuK-dNaFq2NDNhx6ivcf4GYCfGM8M10PcEwDSpxk,2104
|
|
121
121
|
atomicshop/mains/installs/pycharm.py,sha256=uYTfME7hOeNkAsOZxDDPj2hDqmkxrFqVV6Nv6xnYNVk,141
|
|
122
122
|
atomicshop/mitm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
123
|
+
atomicshop/mitm/config_editor.py,sha256=9ZwD6NGqgsr1f85NyFwWwM7FDut2vGQ4xari3vS9UT0,1130
|
|
123
124
|
atomicshop/mitm/connection_thread_worker.py,sha256=PQ8bwOgrPudYP5oPnSi_DWaKXOi038M8TMImlLkxuPI,20486
|
|
124
125
|
atomicshop/mitm/import_config.py,sha256=_V-IVJ7a1L6E-VOR4CDfZj-S1odbsIlBe13ij0NlpqY,7974
|
|
125
|
-
atomicshop/mitm/initialize_engines.py,sha256=
|
|
126
|
-
atomicshop/mitm/initialize_mitm_server.py,sha256=
|
|
126
|
+
atomicshop/mitm/initialize_engines.py,sha256=YnXPK1UKrmULnfL4zLo2LOpKWq-aGKzc9p3n8tfcYCM,8170
|
|
127
|
+
atomicshop/mitm/initialize_mitm_server.py,sha256=0xjHleUFecU8nyhzf5z8On-nZtL26A80prH4GHSqNc8,14611
|
|
127
128
|
atomicshop/mitm/message.py,sha256=u2U2f2SOHdBNU-6r1Ik2W14ai2EOwxUV4wVfGZA098k,1732
|
|
128
129
|
atomicshop/mitm/shared_functions.py,sha256=PaK_sbnEA5zo9k2ktEOKLmvo-6wRUunxzSNRr41uXIQ,1924
|
|
129
130
|
atomicshop/mitm/statistic_analyzer.py,sha256=ctsf-MBIUvG4-R0K4gFQyi_b42-VCq-5s7hgO9jMOes,38415
|
|
@@ -233,11 +234,11 @@ atomicshop/wrappers/factw/rest/statistics.py,sha256=vznwzKP1gEF7uXz3HsuV66BU9wrp
|
|
|
233
234
|
atomicshop/wrappers/factw/rest/status.py,sha256=4O3xS1poafwyUiLDkhyx4oMMe4PBwABuRPpOMnMKgIU,641
|
|
234
235
|
atomicshop/wrappers/fibratusw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
235
236
|
atomicshop/wrappers/fibratusw/install.py,sha256=PLVymDe0HuOvU0r2lje8BkQAgtiOWEeRO7n-1zKuL7A,3287
|
|
236
|
-
atomicshop/wrappers/loggingw/formatters.py,sha256=
|
|
237
|
-
atomicshop/wrappers/loggingw/handlers.py,sha256=
|
|
237
|
+
atomicshop/wrappers/loggingw/formatters.py,sha256=808R7K3e3ZJD2BXfqI6UMOyXGrCgt9SYh2Uv7sL_1KQ,7432
|
|
238
|
+
atomicshop/wrappers/loggingw/handlers.py,sha256=0n4Bqr9yQ7GiQOBYtSVFtCFBeEUfcvkaAFYgWY1E3Tg,18014
|
|
238
239
|
atomicshop/wrappers/loggingw/loggers.py,sha256=DHOOTAtqkwn1xgvLHSkOiBm6yFGNuQy1kvbhG-TDog8,2374
|
|
239
|
-
atomicshop/wrappers/loggingw/loggingw.py,sha256=
|
|
240
|
-
atomicshop/wrappers/loggingw/reading.py,sha256=
|
|
240
|
+
atomicshop/wrappers/loggingw/loggingw.py,sha256=irzlIYXTcCpSVjmb6NU6GJGCIy3V48ZVKNvKOlH70CU,9417
|
|
241
|
+
atomicshop/wrappers/loggingw/reading.py,sha256=yh7uNPxEdn6KsxSKrYny2C57XdI25F5gaByz77CO_pw,17038
|
|
241
242
|
atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
242
243
|
atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=QZg-R2iTQt7kFb8wNtnTmwraSGwvUs34JIasdbNa7ZU,5154
|
|
243
244
|
atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -253,6 +254,7 @@ atomicshop/wrappers/playwrightw/waits.py,sha256=308fdOu6YDqQ7K7xywj7R27sSmFanPBQ
|
|
|
253
254
|
atomicshop/wrappers/psutilw/cpus.py,sha256=w6LPBMINqS-T_X8vzdYkLS2Wzuve28Ydp_GafTCngrc,236
|
|
254
255
|
atomicshop/wrappers/psutilw/disks.py,sha256=3ZSVoommKH1TWo37j_83frB-NqXF4Nf5q5mBCX8G4jE,9221
|
|
255
256
|
atomicshop/wrappers/psutilw/memories.py,sha256=_S0aL8iaoIHebd1vOFrY_T9aROM5Jx2D5CvDh_4j0Vc,528
|
|
257
|
+
atomicshop/wrappers/psutilw/networks.py,sha256=Q2EtyemncDhDsNYZREME0nOIxM-jQqIktFN3i5HtSog,1294
|
|
256
258
|
atomicshop/wrappers/psutilw/psutilw.py,sha256=q3EwgprqyrR4zLCjl4l5DHFOQoukEvQMIPjNB504oQ0,21262
|
|
257
259
|
atomicshop/wrappers/psycopgw/psycopgw.py,sha256=XJvVf0oAUjCHkrYfKeFuGCpfn0Oxj3u4SbKMKA1508E,7118
|
|
258
260
|
atomicshop/wrappers/pywin32w/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -270,7 +272,7 @@ atomicshop/wrappers/socketw/accepter.py,sha256=HQC1EyZmyUtVEfFbaBkHCE-VZp6RWyd9m
|
|
|
270
272
|
atomicshop/wrappers/socketw/base.py,sha256=1vvg8EhRGvnxdrRAm1VJSLCXkm2SZDHRjdpTuhkH3Mg,1844
|
|
271
273
|
atomicshop/wrappers/socketw/certificator.py,sha256=SxCKFyBlwzs4uohugfBokOYQpZJyH8KY46m87Q23n6w,9017
|
|
272
274
|
atomicshop/wrappers/socketw/creator.py,sha256=C-l57G854HAtWJonVbgfQge290-Dg0Ov4aurJAWIKls,11199
|
|
273
|
-
atomicshop/wrappers/socketw/dns_server.py,sha256=
|
|
275
|
+
atomicshop/wrappers/socketw/dns_server.py,sha256=u4RSDIK4UR1aKOulwSGscchxYa7pTlPxMO-StHuBMag,42464
|
|
274
276
|
atomicshop/wrappers/socketw/exception_wrapper.py,sha256=_YDnzyEcUnV6VISU3bk-UPdnsMvHjKJBHwxLMTsxQu8,8495
|
|
275
277
|
atomicshop/wrappers/socketw/get_process.py,sha256=APw_oOXsuR5KljYesd4J8MuzR-kaw2ez3MN3oD_h9Qc,5226
|
|
276
278
|
atomicshop/wrappers/socketw/receiver.py,sha256=m8hXKOa8dqEQGUdcbYjshH8-j0CsMGRkge2ifYKhaAw,9050
|
|
@@ -281,8 +283,8 @@ atomicshop/wrappers/socketw/socket_server_tester.py,sha256=AhpurHJmP2kgzHaUbq5ey
|
|
|
281
283
|
atomicshop/wrappers/socketw/socket_wrapper.py,sha256=aXBwlEIJhFT0-c4i8iNlFx2It9VpCEpsv--5Oqcpxao,11624
|
|
282
284
|
atomicshop/wrappers/socketw/ssl_base.py,sha256=k4V3gwkbq10MvOH4btU4onLX2GNOsSfUAdcHmL1rpVE,2274
|
|
283
285
|
atomicshop/wrappers/socketw/statistics_csv.py,sha256=t3dtDEfN47CfYVi0CW6Kc2QHTEeZVyYhc57IYYh5nmA,826
|
|
284
|
-
atomicshop-2.14.
|
|
285
|
-
atomicshop-2.14.
|
|
286
|
-
atomicshop-2.14.
|
|
287
|
-
atomicshop-2.14.
|
|
288
|
-
atomicshop-2.14.
|
|
286
|
+
atomicshop-2.14.6.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
|
|
287
|
+
atomicshop-2.14.6.dist-info/METADATA,sha256=GxNk1sCw7qnOT6BX5QRiy9KCqX1KQfwt4lU0ESSxaos,10478
|
|
288
|
+
atomicshop-2.14.6.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
289
|
+
atomicshop-2.14.6.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
|
|
290
|
+
atomicshop-2.14.6.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|