httpdbg 0.27.0__tar.gz → 0.28.0__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.
Files changed (75) hide show
  1. {httpdbg-0.27.0 → httpdbg-0.28.0}/PKG-INFO +1 -1
  2. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/__init__.py +1 -1
  3. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/__main__.py +4 -0
  4. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/args.py +13 -0
  5. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/env.py +3 -1
  6. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/generic.py +11 -11
  7. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/socket.py +22 -20
  8. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/utils.py +3 -3
  9. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/initiator.py +3 -3
  10. httpdbg-0.28.0/httpdbg/log.py +59 -0
  11. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/records.py +3 -3
  12. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/utils.py +0 -11
  13. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/app.py +2 -2
  14. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg.egg-info/PKG-INFO +1 -1
  15. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg.egg-info/SOURCES.txt +1 -0
  16. {httpdbg-0.27.0 → httpdbg-0.28.0}/LICENSE +0 -0
  17. {httpdbg-0.27.0 → httpdbg-0.28.0}/README.md +0 -0
  18. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/exception.py +0 -0
  19. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/__init__.py +0 -0
  20. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/aiohttp.py +0 -0
  21. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/all.py +0 -0
  22. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/external.py +0 -0
  23. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/httpx.py +0 -0
  24. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/pytest.py +0 -0
  25. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/requests.py +0 -0
  26. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/hooks/urllib3.py +0 -0
  27. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/mode_console.py +0 -0
  28. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/mode_module.py +0 -0
  29. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/mode_script.py +0 -0
  30. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/preview.py +0 -0
  31. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/server.py +0 -0
  32. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/__init__.py +0 -0
  33. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/api.py +0 -0
  34. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/api.js +0 -0
  35. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/column.css +0 -0
  36. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/configuration.js +0 -0
  37. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/detail.css +0 -0
  38. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/favicon.ico +0 -0
  39. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/filter.js +0 -0
  40. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/chevron-direction-top-outline-icon.svg +0 -0
  41. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/download-install-line-icon.svg +0 -0
  42. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/engine-gears-icon.svg +0 -0
  43. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/files-papers-outline-icon.svg +0 -0
  44. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/filter-outline-icon.svg +0 -0
  45. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/information-mark-circle-outline-icon.svg +0 -0
  46. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/math-multiplication-icon.svg +0 -0
  47. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/push-pin-green-icon.svg +0 -0
  48. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/question-mark-round-line-icon.svg +0 -0
  49. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/recycle-bin-line-icon.svg +0 -0
  50. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/icons/wait-sandclock-icon.svg +0 -0
  51. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/index.htm +0 -0
  52. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/main.js +0 -0
  53. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/mustache.min.js +0 -0
  54. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/render.js +0 -0
  55. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/style.css +0 -0
  56. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg/webapp/static/table.css +0 -0
  57. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg.egg-info/dependency_links.txt +0 -0
  58. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg.egg-info/entry_points.txt +0 -0
  59. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg.egg-info/requires.txt +0 -0
  60. {httpdbg-0.27.0 → httpdbg-0.28.0}/httpdbg.egg-info/top_level.txt +0 -0
  61. {httpdbg-0.27.0 → httpdbg-0.28.0}/pyproject.toml +0 -0
  62. {httpdbg-0.27.0 → httpdbg-0.28.0}/setup.cfg +0 -0
  63. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_api.py +0 -0
  64. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_cli.py +0 -0
  65. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_context_manager.py +0 -0
  66. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_hook_aiohttp.py +0 -0
  67. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_hook_httpx.py +0 -0
  68. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_hook_requests.py +0 -0
  69. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_hook_urllib3.py +0 -0
  70. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_initiator.py +0 -0
  71. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_mode_console.py +0 -0
  72. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_mode_module_pytest.py +0 -0
  73. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_mode_script.py +0 -0
  74. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_preview.py +0 -0
  75. {httpdbg-0.27.0 → httpdbg-0.28.0}/tests/test_server.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: httpdbg
3
- Version: 0.27.0
3
+ Version: 0.28.0
4
4
  Summary: A very simple tool to debug HTTP(S) client requests
5
5
  Author-email: cle-b <cle@tictac.pm>
6
6
  License: Apache-2.0
@@ -3,6 +3,6 @@ from httpdbg.hooks.all import httprecord
3
3
  from httpdbg.records import HTTPRecords
4
4
 
5
5
 
6
- __version__ = "0.27.0"
6
+ __version__ = "0.28.0"
7
7
 
8
8
  __all__ = ["httprecord", "HTTPRecords"]
@@ -5,6 +5,7 @@ import time
5
5
  from httpdbg import __version__
6
6
  from httpdbg.args import read_args
7
7
  from httpdbg.hooks.all import httprecord
8
+ from httpdbg.log import set_env_for_logging
8
9
  from httpdbg.server import httpdbg_srv
9
10
  from httpdbg.mode_console import run_console
10
11
  from httpdbg.mode_module import run_module
@@ -18,6 +19,9 @@ def print_msg(msg):
18
19
 
19
20
 
20
21
  def pyhttpdbg(params, subparams, test_mode=False):
22
+
23
+ set_env_for_logging(params.log_level, params.log)
24
+
21
25
  url = f"http://{params.host}:{params.port}/{'?hi=on' if params.console else ''}"
22
26
 
23
27
  print_msg(f" httpdbg - HTTP(S) requests available at {url}")
@@ -1,7 +1,10 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import argparse
3
+ from pathlib import Path
3
4
  from typing import List, Tuple
4
5
 
6
+ from httpdbg.log import LogLevel
7
+
5
8
 
6
9
  def read_args(args: List[str]) -> Tuple[argparse.Namespace, List[str]]:
7
10
  httpdbg_args = args
@@ -49,6 +52,16 @@ def read_args(args: List[str]) -> Tuple[argparse.Namespace, List[str]]:
49
52
  help="stop the server even if the requests have not been read",
50
53
  )
51
54
 
55
+ parser.add_argument(
56
+ "--log-level",
57
+ type=LogLevel,
58
+ choices=LogLevel,
59
+ default=LogLevel.WARNING,
60
+ help="The log level",
61
+ )
62
+
63
+ parser.add_argument("--log", type=Path, help="Path to the log file.")
64
+
52
65
  actions = parser.add_mutually_exclusive_group()
53
66
 
54
67
  actions.add_argument(
@@ -1,4 +1,6 @@
1
1
  HTTPDBG_CURRENT_INITIATOR = "HTTPDBG_CURRENT_INITIATOR"
2
2
  HTTPDBG_CURRENT_TAG = "HTTPDBG_CURRENT_TAG"
3
- HTTPDBG_LOG = "HTTPDBG_LOG"
4
3
  HTTPDBG_SUBPROCESS_DIR = "HTTPDBG_SUBPROCESS_DIR"
4
+
5
+ HTTPDBG_LOG_LEVEL = "HTTPDBG_LOG_LEVEL"
6
+ HTTPDBG_LOG_PATH = "HTTPDBG_LOG_PATH"
@@ -15,11 +15,11 @@ from httpdbg.hooks.utils import decorate
15
15
  from httpdbg.hooks.utils import undecorate
16
16
  from httpdbg.initiator import httpdbg_initiator
17
17
  from httpdbg.records import HTTPRecords
18
- from httpdbg.utils import logger
18
+ from httpdbg.log import logger
19
19
 
20
20
 
21
21
  def set_hook_for_generic_async(records: HTTPRecords, method: Any):
22
- logger.info(f"SET_HOOK_FOR_GENERIC_ASYNC {method}")
22
+ logger().info(f"SET_HOOK_FOR_GENERIC_ASYNC {method}")
23
23
 
24
24
  async def hook(*args, **kwargs):
25
25
  with httpdbg_initiator(
@@ -33,7 +33,7 @@ def set_hook_for_generic_async(records: HTTPRecords, method: Any):
33
33
 
34
34
 
35
35
  def set_hook_for_generic(records: HTTPRecords, method: Any):
36
- logger.info(f"SET_HOOK_FOR_GENERIC {method}")
36
+ logger().info(f"SET_HOOK_FOR_GENERIC {method}")
37
37
 
38
38
  def hook(*args, **kwargs):
39
39
  with httpdbg_initiator(
@@ -56,11 +56,11 @@ def hook_generic(
56
56
  initiators = []
57
57
 
58
58
  for initiator in initiators:
59
- logger.info(f"HOOK_GENERIC add initiator - {initiator}")
59
+ logger().info(f"HOOK_GENERIC add initiator - {initiator}")
60
60
  hooks += list_callables_from_package(records, initiator)
61
61
 
62
62
  try:
63
- logger.info(
63
+ logger().info(
64
64
  f"HOOK_GENERIC add initiator - hooks - {[hook.__httpdbg__.__name__ for hook in hooks]}"
65
65
  )
66
66
  except Exception:
@@ -77,7 +77,7 @@ def list_callables_from_package(records: HTTPRecords, package: str) -> List[Any]
77
77
  callables = []
78
78
 
79
79
  try:
80
- logger.info(f"LIST_CALLABLES_FROM_PACKAGE {package}")
80
+ logger().info(f"LIST_CALLABLES_FROM_PACKAGE {package}")
81
81
 
82
82
  callables += list_callables_from_module(records, package)
83
83
 
@@ -96,7 +96,7 @@ def list_callables_from_package(records: HTTPRecords, package: str) -> List[Any]
96
96
  records, f"{package}.{file_or_dir.name}"
97
97
  )
98
98
  except Exception as ex:
99
- logger.info(f"LIST_CALLABLES_FROM_PACKAGE {package} - error - {str(ex)}")
99
+ logger().info(f"LIST_CALLABLES_FROM_PACKAGE {package} - error - {str(ex)}")
100
100
 
101
101
  return callables
102
102
 
@@ -105,7 +105,7 @@ def list_callables_from_module(records: HTTPRecords, module: str) -> List[Any]:
105
105
  callables = []
106
106
 
107
107
  try:
108
- logger.info(f"LIST_CALLABLES_FROM_MODULE {module}")
108
+ logger().info(f"LIST_CALLABLES_FROM_MODULE {module}")
109
109
 
110
110
  imported_module = importlib.import_module(module)
111
111
 
@@ -141,7 +141,7 @@ def list_callables_from_module(records: HTTPRecords, module: str) -> List[Any]:
141
141
  records, imported_module, module, name
142
142
  )
143
143
  except Exception as ex:
144
- logger.info(f"LIST_CALLABLES_FROM_MODULE {module} - error - {str(ex)}")
144
+ logger().info(f"LIST_CALLABLES_FROM_MODULE {module} - error - {str(ex)}")
145
145
 
146
146
  return callables
147
147
 
@@ -155,7 +155,7 @@ def list_callables_from_class(
155
155
  callables = []
156
156
 
157
157
  try:
158
- logger.info(f"LIST_CALLABLES_FROM_CLASS {module}.{classname}")
158
+ logger().info(f"LIST_CALLABLES_FROM_CLASS {module}.{classname}")
159
159
  for name in imported_module.__dict__[classname].__dict__.keys():
160
160
  from_module = getattr(
161
161
  imported_module.__dict__[classname].__dict__[name], "__module__", ""
@@ -192,7 +192,7 @@ def list_callables_from_class(
192
192
  setattr(imported_module.__dict__[classname], name, hook)
193
193
  callables.append(hook)
194
194
  except Exception as ex:
195
- logger.info(
195
+ logger().info(
196
196
  f"LIST_CALLABLES_FROM_CLASS {module}.{classname} - error - {str(ex)}"
197
197
  )
198
198
 
@@ -13,7 +13,7 @@ from httpdbg.hooks.utils import decorate
13
13
  from httpdbg.hooks.utils import undecorate
14
14
  from httpdbg.records import HTTPRecord
15
15
  from httpdbg.records import HTTPRecords
16
- from httpdbg.utils import logger
16
+ from httpdbg.log import logger
17
17
 
18
18
 
19
19
  def set_hook_for_socket_init(records, method):
@@ -29,7 +29,7 @@ def set_hook_for_socket_connect(records, method):
29
29
  def hook(self, address):
30
30
  socketdata = records.get_socket_data(self, force_new=True)
31
31
  if socketdata:
32
- logger.info(
32
+ logger().info(
33
33
  f"CONNECT - self={self} id={id(self)} socketdata={socketdata} address={address}"
34
34
  )
35
35
 
@@ -67,13 +67,13 @@ def set_hook_for_ssl_wrap_socket(records, method):
67
67
 
68
68
  raise
69
69
 
70
- logger.info(
70
+ logger().info(
71
71
  f"WRAP_SOCKET - {type(sock)}={id(sock)} {type(sslsocket)}={id(sslsocket)}"
72
72
  )
73
73
 
74
74
  socketdata = records.move_socket_data(sslsocket, sock)
75
75
  if socketdata:
76
- logger.info(f"WRAP_SOCKET * - socketdata={socketdata}")
76
+ logger().info(f"WRAP_SOCKET * - socketdata={socketdata}")
77
77
 
78
78
  return sslsocket
79
79
 
@@ -94,13 +94,13 @@ def set_hook_for_sslcontext_wrap_socket(records, method):
94
94
 
95
95
  raise
96
96
 
97
- logger.info(
97
+ logger().info(
98
98
  f"WRAP_SOCKET (SSLContext) - {type(self)}={id(self)} {type(sock)}={id(sock)} {type(sslsocket)}={id(sslsocket)}"
99
99
  )
100
100
 
101
101
  socketdata = records.move_socket_data(sslsocket, sock)
102
102
  if socketdata:
103
- logger.info(f"WRAP_SOCKET (SSLContext) * - socketdata={socketdata}")
103
+ logger().info(f"WRAP_SOCKET (SSLContext) * - socketdata={socketdata}")
104
104
 
105
105
  return sslsocket
106
106
 
@@ -121,13 +121,13 @@ def set_hook_for_socket_wrap_bio(records, method):
121
121
 
122
122
  raise
123
123
 
124
- logger.info(
124
+ logger().info(
125
125
  f"WRAP_SOCKET_BIO - {type(self)}={id(self)} {type(sslobject)}={id(sslobject)}"
126
126
  )
127
127
 
128
128
  socketdata = records.get_socket_data(sslobject, self)
129
129
  if socketdata:
130
- logger.info(f"WRAP_SOCKET_BIO * - socketdata={socketdata}")
130
+ logger().info(f"WRAP_SOCKET_BIO * - socketdata={socketdata}")
131
131
 
132
132
  return sslobject
133
133
 
@@ -138,7 +138,7 @@ def set_hook_for_socket_recv_into(records, method):
138
138
  def hook(self, buffer, *args, **kwargs):
139
139
  socketdata = records.get_socket_data(self)
140
140
  if socketdata:
141
- logger.info(
141
+ logger().info(
142
142
  f"RECV_INTO - self={self} id={id(self)} socketdata={socketdata} args={args} kwargs={kwargs}"
143
143
  )
144
144
 
@@ -150,7 +150,9 @@ def set_hook_for_socket_recv_into(records, method):
150
150
  raise
151
151
 
152
152
  if socketdata and socketdata.record:
153
- logger.info(f"RECV_INTO (after) - id={id(self)} buffer={(b''+buffer)[:20]}")
153
+ logger().info(
154
+ f"RECV_INTO (after) - id={id(self)} buffer={(b''+buffer)[:20]}"
155
+ )
154
156
  socketdata.record.response.rawdata += buffer[:nbytes]
155
157
 
156
158
  return nbytes
@@ -162,7 +164,7 @@ def set_hook_for_socket_recv(records, method):
162
164
  def hook(self, bufsize, *args, **kwargs):
163
165
  socketdata = records.get_socket_data(self)
164
166
  if socketdata:
165
- logger.info(
167
+ logger().info(
166
168
  f"RECV - self={self} id={id(self)} socketdata={socketdata} bufsize={bufsize} args={args} kwargs={kwargs}"
167
169
  )
168
170
 
@@ -185,7 +187,7 @@ def set_hook_for_socket_sendall(records, method):
185
187
  def hook(self, bytes, *args, **kwargs):
186
188
  socketdata = records.get_socket_data(self, request=True)
187
189
  if socketdata:
188
- logger.info(
190
+ logger().info(
189
191
  f"SENDALL - self={self} id={id(self)} socketdata={socketdata} bytes={(b''+bytes)[:20]} type={type(bytes)} len={len(bytes)} args={args} kwargs={kwargs}"
190
192
  )
191
193
 
@@ -196,7 +198,7 @@ def set_hook_for_socket_sendall(records, method):
196
198
  socketdata.rawdata += bytes
197
199
  http_detected = socketdata.http_detected()
198
200
  if http_detected:
199
- logger.info("SENDALL - http detected")
201
+ logger().info("SENDALL - http detected")
200
202
  socketdata.record = HTTPRecord(tbegin=socketdata.tbegin)
201
203
  socketdata.record.initiator = records.get_initiator()
202
204
  socketdata.record.address = socketdata.address
@@ -220,7 +222,7 @@ def set_hook_for_socket_send(records, method):
220
222
  def hook(self, bytes, *args, **kwargs):
221
223
  socketdata = records.get_socket_data(self, request=True)
222
224
  if socketdata:
223
- logger.info(
225
+ logger().info(
224
226
  f"SEND - self={self} id={id(self)} socketdata={socketdata} bytes={(b''+bytes)[:20]} args={args} kwargs={kwargs}"
225
227
  )
226
228
 
@@ -253,7 +255,7 @@ def set_hook_for_socket_send(records, method):
253
255
 
254
256
  def set_hook_for_asyncio_create_connection(records, method):
255
257
  async def hook(self, *args, **kwargs):
256
- logger.info(
258
+ logger().info(
257
259
  f"CREATE_CONNECTION - self={self} id={id(self)} args={args} kwargs={kwargs}"
258
260
  )
259
261
  r = await method(self, *args, **kwargs)
@@ -266,7 +268,7 @@ def set_hook_for_asyncio_create_connection(records, method):
266
268
  socketdata = records.get_socket_data(
267
269
  ssl_object, sock, force_new=True
268
270
  ) # to link the cnx info to the sslobject
269
- logger.info(
271
+ logger().info(
270
272
  f"CREATE_CONNECTION - ssl_object ssl_object={ssl_object} ssl_objectid={id(ssl_object)} socketdata={socketdata}"
271
273
  )
272
274
  return r
@@ -276,10 +278,10 @@ def set_hook_for_asyncio_create_connection(records, method):
276
278
 
277
279
  def set_hook_for_sslobject_write(records, method):
278
280
  def hook(self, buf, *args, **kwargs):
279
- logger.info(f"WRITE - {type(self)}={id(self)} buf={(b'' + buf)[:20]}")
281
+ logger().info(f"WRITE - {type(self)}={id(self)} buf={(b'' + buf)[:20]}")
280
282
  socketdata = records.get_socket_data(self, request=True)
281
283
  if socketdata:
282
- logger.info(f"WRITE * - socketdata={socketdata}")
284
+ logger().info(f"WRITE * - socketdata={socketdata}")
283
285
 
284
286
  try:
285
287
  size = method(self, buf, *args, **kwargs)
@@ -310,10 +312,10 @@ def set_hook_for_sslobject_write(records, method):
310
312
 
311
313
  def set_hook_for_sslobject_read(records, method):
312
314
  def hook(self, *args, **kwargs):
313
- logger.info(f"READ - {type(self)}={id(self)}")
315
+ logger().info(f"READ - {type(self)}={id(self)}")
314
316
  socketdata = records.get_socket_data(self)
315
317
  if socketdata:
316
- logger.info(f"READ * - socketdata={socketdata}")
318
+ logger().info(f"READ * - socketdata={socketdata}")
317
319
 
318
320
  try:
319
321
  r = method(self, *args, **kwargs)
@@ -1,7 +1,7 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  import inspect
3
3
 
4
- from httpdbg.utils import logger
4
+ from httpdbg.log import logger
5
5
 
6
6
 
7
7
  def getcallargs(original_method, *args, **kwargs):
@@ -15,7 +15,7 @@ def getcallargs(original_method, *args, **kwargs):
15
15
  inspect.signature(original_method).bind_partial(*args, **kwargs).arguments
16
16
  )
17
17
  except Exception as ex:
18
- logger.info(f"getcallargs - exception {str(ex)}")
18
+ logger().info(f"getcallargs - exception {str(ex)}")
19
19
  # TypeError('too many positional arguments') may occur when using pytest (seems related to teardown_method)
20
20
  callargs = {}
21
21
  i = 0
@@ -24,7 +24,7 @@ def getcallargs(original_method, *args, **kwargs):
24
24
  callargs[f"_positional_argument{i}"] = arg
25
25
 
26
26
  callargs.update(kwargs)
27
- logger.info(f"getcallargs {original_method} - {[arg for arg in callargs]}")
27
+ logger().info(f"getcallargs {original_method} - {[arg for arg in callargs]}")
28
28
  return callargs
29
29
 
30
30
 
@@ -12,7 +12,7 @@ from httpdbg.env import HTTPDBG_CURRENT_INITIATOR
12
12
  from httpdbg.env import HTTPDBG_CURRENT_TAG
13
13
  from httpdbg.hooks.utils import getcallargs
14
14
  from httpdbg.utils import get_new_uuid
15
- from httpdbg.utils import logger
15
+ from httpdbg.log import logger
16
16
 
17
17
 
18
18
  class Initiator(object):
@@ -127,7 +127,7 @@ def get_current_instruction(
127
127
  short_stack += f"{instruction}\n"
128
128
  stack = []
129
129
  except Exception as ex:
130
- logger.info(
130
+ logger().info(
131
131
  f"GET_CURRENT_INSTRUCTION [{str(extracted_stack)}] - error - {str(ex)}"
132
132
  )
133
133
 
@@ -175,7 +175,7 @@ def extract_short_stack_from_file(
175
175
  if end_of_instruction_found and stop_if_instruction_ends:
176
176
  break
177
177
  except Exception as ex:
178
- logger.info(
178
+ logger().info(
179
179
  f"EXTRACT_SHORT_STACK_FROM_FILE {filename} lineno={lineno} before={before} after={after}- error - {str(ex)}"
180
180
  )
181
181
 
@@ -0,0 +1,59 @@
1
+ from enum import Enum
2
+ from functools import cache
3
+ import logging
4
+ import os
5
+ from pathlib import Path
6
+ from typing import Union
7
+
8
+ from httpdbg.env import HTTPDBG_LOG_LEVEL
9
+ from httpdbg.env import HTTPDBG_LOG_PATH
10
+
11
+
12
+ class LogLevel(Enum):
13
+ NOTSET = "notset"
14
+ DEBUG = "debug"
15
+ INFO = "info"
16
+ WARNING = "warning"
17
+ ERROR = "error"
18
+ CRITICAL = "critical"
19
+
20
+
21
+ def set_env_for_logging(log_level: LogLevel, path: Union[Path, None]):
22
+
23
+ os.environ[HTTPDBG_LOG_LEVEL] = str(
24
+ {
25
+ "NOTSET": logging.NOTSET,
26
+ "DEBUG": logging.DEBUG,
27
+ "INFO": logging.INFO,
28
+ "WARNING": logging.WARNING,
29
+ "ERROR": logging.ERROR,
30
+ "CRITICAL": logging.CRITICAL,
31
+ }[log_level.value.upper()]
32
+ )
33
+
34
+ if path:
35
+ os.environ[HTTPDBG_LOG_PATH] = str(path)
36
+
37
+
38
+ @cache
39
+ def logger() -> logging.Logger:
40
+
41
+ logger = logging.getLogger()
42
+ log_level = int(os.environ.get(HTTPDBG_LOG_LEVEL, logging.WARNING))
43
+ logger.setLevel(log_level)
44
+
45
+ formatter = logging.Formatter(
46
+ "¤ %(asctime)s.%(msecs)03d (%(process)d) [%(levelname)s] %(message)s",
47
+ datefmt="%H:%M:%S",
48
+ )
49
+
50
+ if HTTPDBG_LOG_PATH in os.environ:
51
+ file_handler = logging.FileHandler(os.environ[HTTPDBG_LOG_PATH])
52
+ file_handler.setFormatter(formatter)
53
+ logger.addHandler(file_handler)
54
+ else:
55
+ console_handler = logging.StreamHandler()
56
+ console_handler.setFormatter(formatter)
57
+ logger.addHandler(console_handler)
58
+
59
+ return logger
@@ -20,7 +20,7 @@ from httpdbg.utils import get_new_uuid
20
20
  from httpdbg.utils import chunked_to_bytes
21
21
  from httpdbg.utils import list_cookies_headers_request_simple_cookies
22
22
  from httpdbg.utils import list_cookies_headers_response_simple_cookies
23
- from httpdbg.utils import logger
23
+ from httpdbg.log import logger
24
24
 
25
25
 
26
26
  class SocketRawData(object):
@@ -38,7 +38,7 @@ class SocketRawData(object):
38
38
 
39
39
  @rawdata.setter
40
40
  def rawdata(self, value: bytes) -> None:
41
- logger.info(
41
+ logger().info(
42
42
  f"SocketRawData id={self.id} newdata={value[:20]!r} len={len(value)}"
43
43
  )
44
44
  self._rawdata = value
@@ -407,6 +407,6 @@ class HTTPRecords:
407
407
 
408
408
  def del_socket_data(self, obj):
409
409
  if id(obj) in self._sockets:
410
- logger.info(f"SocketRawData del id={id(obj)}")
410
+ logger().info(f"SocketRawData del id={id(obj)}")
411
411
  self._sockets[id(obj)] = None
412
412
  del self._sockets[id(obj)]
@@ -1,20 +1,9 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  from http.cookies import SimpleCookie
3
- import logging
4
- import os
5
3
  import secrets
6
4
  import string
7
5
  from typing import List
8
6
 
9
- from httpdbg.env import HTTPDBG_LOG
10
-
11
- logger = logging.getLogger("httpdbg")
12
- logger.setLevel(100)
13
- log_level = os.environ.get(HTTPDBG_LOG)
14
- if log_level is not None:
15
- logging.basicConfig(level=int(log_level), format="%(message)s")
16
- logger.setLevel(int(log_level))
17
-
18
7
 
19
8
  def get_new_uuid() -> str:
20
9
  # important - the uuid must be compatible with method naming rules
@@ -9,7 +9,7 @@ import re
9
9
  from urllib.parse import urlparse, parse_qs
10
10
 
11
11
  from httpdbg import __version__
12
- from httpdbg.utils import logger
12
+ from httpdbg.log import logger
13
13
  from httpdbg.webapp.api import RequestListPayload, RequestPayload
14
14
 
15
15
 
@@ -18,7 +18,7 @@ def silently_catch_error():
18
18
  try:
19
19
  yield
20
20
  except Exception as ex:
21
- logger.info(f"HttpbgHTTPRequestHandler - silently_catch_error - {str(ex)}")
21
+ logger().info(f"HttpbgHTTPRequestHandler - silently_catch_error - {str(ex)}")
22
22
 
23
23
 
24
24
  class HttpbgHTTPRequestHandler(BaseHTTPRequestHandler):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: httpdbg
3
- Version: 0.27.0
3
+ Version: 0.28.0
4
4
  Summary: A very simple tool to debug HTTP(S) client requests
5
5
  Author-email: cle-b <cle@tictac.pm>
6
6
  License: Apache-2.0
@@ -8,6 +8,7 @@ httpdbg/args.py
8
8
  httpdbg/env.py
9
9
  httpdbg/exception.py
10
10
  httpdbg/initiator.py
11
+ httpdbg/log.py
11
12
  httpdbg/mode_console.py
12
13
  httpdbg/mode_module.py
13
14
  httpdbg/mode_script.py
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes