0
# Debug and Logging
1
2
Debugging utilities and logging functions for tracing WebSocket communication, protocol analysis, and troubleshooting connection issues. The logging system provides fine-grained control over debug output and protocol tracing.
3
4
## Capabilities
5
6
### Trace Control
7
8
Enable and configure WebSocket protocol tracing for debugging and development.
9
10
```python { .api }
11
def enableTrace(
12
traceable: bool,
13
handler: logging.StreamHandler = logging.StreamHandler(),
14
level: str = "DEBUG",
15
) -> None:
16
"""
17
Enable or disable WebSocket protocol tracing.
18
19
Parameters:
20
- traceable: True to enable tracing, False to disable
21
- handler: Logging handler for trace output (default: StreamHandler to stdout)
22
- level: Logging level for trace messages (default: "DEBUG")
23
24
Note: When enabled, shows detailed frame-level communication,
25
connection events, and protocol analysis information.
26
"""
27
```
28
29
### Logging Status Check
30
31
Check if different logging levels are enabled for conditional logging operations.
32
33
```python { .api }
34
def isEnabledForError() -> bool:
35
"""
36
Check if ERROR level logging is enabled.
37
38
Returns:
39
bool: True if error logging is active
40
"""
41
42
def isEnabledForDebug() -> bool:
43
"""
44
Check if DEBUG level logging is enabled.
45
46
Returns:
47
bool: True if debug logging is active
48
"""
49
50
def isEnabledForTrace() -> bool:
51
"""
52
Check if trace logging is enabled.
53
54
Returns:
55
bool: True if trace logging is active (via enableTrace)
56
"""
57
```
58
59
### Logging Functions
60
61
Structured logging functions for different message types and severity levels.
62
63
```python { .api }
64
def dump(title: str, message: str) -> None:
65
"""
66
Output formatted debug dump with title and content.
67
68
Parameters:
69
- title: Section title for the dump
70
- message: Content to dump
71
72
Note: Only outputs when tracing is enabled
73
"""
74
75
def error(msg: str) -> None:
76
"""
77
Log error message.
78
79
Parameters:
80
- msg: Error message text
81
"""
82
83
def warning(msg: str) -> None:
84
"""
85
Log warning message.
86
87
Parameters:
88
- msg: Warning message text
89
"""
90
91
def debug(msg: str) -> None:
92
"""
93
Log debug message.
94
95
Parameters:
96
- msg: Debug message text
97
"""
98
99
def info(msg: str) -> None:
100
"""
101
Log informational message.
102
103
Parameters:
104
- msg: Information message text
105
"""
106
107
def trace(msg: str) -> None:
108
"""
109
Log trace message (only when tracing enabled).
110
111
Parameters:
112
- msg: Trace message text
113
114
Note: Only outputs when enableTrace(True) has been called
115
"""
116
```
117
118
## Usage Examples
119
120
### Basic Trace Enablement
121
122
```python
123
import websocket
124
125
# Enable basic tracing to see WebSocket communication
126
websocket.enableTrace(True)
127
128
# Now all WebSocket operations will show detailed trace output
129
ws = websocket.create_connection("ws://echo.websocket.events/")
130
ws.send("Hello, World!")
131
response = ws.recv()
132
print(f"Echo: {response}")
133
ws.close()
134
135
# Disable tracing
136
websocket.enableTrace(False)
137
```
138
139
### Custom Trace Configuration
140
141
```python
142
import websocket
143
import logging
144
import sys
145
146
# Create custom handler for trace output
147
trace_handler = logging.StreamHandler(sys.stderr)
148
trace_handler.setFormatter(logging.Formatter(
149
'[%(asctime)s] %(levelname)s: %(message)s'
150
))
151
152
# Enable tracing with custom handler and level
153
websocket.enableTrace(True, handler=trace_handler, level="INFO")
154
155
# Create connection - will show formatted trace output
156
ws = websocket.WebSocketApp("ws://echo.websocket.events/",
157
on_open=lambda ws: ws.send("Test message"))
158
ws.run_forever()
159
```
160
161
### File-Based Logging
162
163
```python
164
import websocket
165
import logging
166
167
# Set up file logging for WebSocket trace
168
file_handler = logging.FileHandler('websocket_trace.log')
169
file_handler.setFormatter(logging.Formatter(
170
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
171
))
172
173
# Enable tracing to file
174
websocket.enableTrace(True, handler=file_handler, level="DEBUG")
175
176
try:
177
ws = websocket.create_connection("ws://echo.websocket.events/")
178
ws.send("Logged message")
179
response = ws.recv()
180
ws.close()
181
print("Check websocket_trace.log for detailed trace")
182
except Exception as e:
183
print(f"Error: {e}")
184
```
185
186
### Conditional Logging Based on Status
187
188
```python
189
import websocket
190
191
def smart_logging_example():
192
# Check logging status before expensive operations
193
if websocket.isEnabledForDebug():
194
websocket.debug("Starting WebSocket connection analysis")
195
196
if websocket.isEnabledForTrace():
197
websocket.trace("Detailed protocol analysis enabled")
198
199
try:
200
ws = websocket.create_connection("ws://echo.websocket.events/")
201
202
if websocket.isEnabledForDebug():
203
websocket.debug(f"Connected to {ws.url}")
204
websocket.debug(f"Response headers: {ws.headers}")
205
206
ws.send("Test")
207
response = ws.recv()
208
209
if websocket.isEnabledForTrace():
210
websocket.trace(f"Received response: {response}")
211
212
ws.close()
213
214
except Exception as e:
215
if websocket.isEnabledForError():
216
websocket.error(f"Connection failed: {e}")
217
218
# Run with different logging levels
219
websocket.enableTrace(True, level="DEBUG")
220
smart_logging_example()
221
```
222
223
### Structured Debug Output
224
225
```python
226
import websocket
227
import json
228
229
def debug_connection_details(ws):
230
"""Output structured connection information."""
231
if websocket.isEnabledForDebug():
232
connection_info = {
233
"url": getattr(ws, 'url', 'unknown'),
234
"status": ws.getstatus() if hasattr(ws, 'getstatus') else None,
235
"subprotocol": ws.getsubprotocol() if hasattr(ws, 'getsubprotocol') else None,
236
"headers": dict(ws.getheaders()) if hasattr(ws, 'getheaders') and ws.getheaders() else {},
237
"ssl": ws.is_ssl() if hasattr(ws, 'is_ssl') else False
238
}
239
240
websocket.dump("Connection Details", json.dumps(connection_info, indent=2))
241
242
# Enable detailed tracing
243
websocket.enableTrace(True)
244
245
ws = websocket.create_connection("ws://echo.websocket.events/")
246
debug_connection_details(ws)
247
ws.close()
248
```
249
250
### Application-Level Logging Integration
251
252
```python
253
import websocket
254
import logging
255
256
# Set up application logging
257
app_logger = logging.getLogger("myapp.websocket")
258
app_logger.setLevel(logging.DEBUG)
259
260
# Create handler for application logs
261
app_handler = logging.StreamHandler()
262
app_handler.setFormatter(logging.Formatter(
263
'[%(name)s] %(levelname)s: %(message)s'
264
))
265
app_logger.addHandler(app_handler)
266
267
class LoggingWebSocketApp:
268
def __init__(self, url):
269
self.url = url
270
self.logger = app_logger
271
272
def connect(self):
273
self.logger.info(f"Connecting to {self.url}")
274
275
# Enable websocket library tracing
276
websocket.enableTrace(True, level="DEBUG")
277
278
ws = websocket.WebSocketApp(
279
self.url,
280
on_open=self.on_open,
281
on_message=self.on_message,
282
on_error=self.on_error,
283
on_close=self.on_close
284
)
285
286
ws.run_forever()
287
288
def on_open(self, ws):
289
self.logger.info("WebSocket connection established")
290
291
def on_message(self, ws, message):
292
self.logger.debug(f"Received message: {message[:100]}...")
293
294
def on_error(self, ws, error):
295
self.logger.error(f"WebSocket error: {error}")
296
297
def on_close(self, ws, close_status_code, close_msg):
298
self.logger.info(f"Connection closed: {close_status_code} - {close_msg}")
299
300
# Usage
301
app = LoggingWebSocketApp("ws://echo.websocket.events/")
302
app.connect()
303
```
304
305
### Performance Impact Analysis
306
307
```python
308
import websocket
309
import time
310
311
def measure_logging_overhead():
312
"""Measure performance impact of different logging levels."""
313
314
test_scenarios = [
315
{"name": "No logging", "trace": False},
316
{"name": "Error only", "trace": False, "level": "ERROR"},
317
{"name": "Debug enabled", "trace": False, "level": "DEBUG"},
318
{"name": "Full tracing", "trace": True, "level": "DEBUG"}
319
]
320
321
for scenario in test_scenarios:
322
print(f"\nTesting: {scenario['name']}")
323
324
# Configure logging
325
if scenario.get("trace"):
326
websocket.enableTrace(True, level=scenario.get("level", "DEBUG"))
327
else:
328
websocket.enableTrace(False)
329
330
# Measure connection and message exchange time
331
start_time = time.time()
332
333
try:
334
ws = websocket.create_connection("ws://echo.websocket.events/")
335
336
# Send multiple messages
337
for i in range(10):
338
ws.send(f"Test message {i}")
339
response = ws.recv()
340
341
ws.close()
342
343
elapsed = time.time() - start_time
344
print(f" Completed in {elapsed:.3f} seconds")
345
346
except Exception as e:
347
print(f" Error: {e}")
348
349
# Reset to default
350
websocket.enableTrace(False)
351
352
measure_logging_overhead()
353
```
354
355
### Custom Debug Dump Usage
356
357
```python
358
import websocket
359
360
def analyze_websocket_frames():
361
"""Demonstrate custom debug dump usage."""
362
websocket.enableTrace(True)
363
364
ws = websocket.WebSocket()
365
ws.connect("ws://echo.websocket.events/")
366
367
# Send test data
368
test_messages = [
369
"Short message",
370
"A" * 1000, # Long message
371
b"\x01\x02\x03\x04", # Binary data
372
]
373
374
for i, msg in enumerate(test_messages):
375
websocket.dump(f"Test Message {i+1}", f"Sending: {repr(msg)}")
376
377
if isinstance(msg, bytes):
378
ws.send_bytes(msg)
379
else:
380
ws.send(msg)
381
382
response = ws.recv()
383
websocket.dump(f"Response {i+1}", f"Received: {repr(response)}")
384
385
ws.close()
386
387
analyze_websocket_frames()
388
```
389
390
### Trace Output Filtering
391
392
```python
393
import websocket
394
import logging
395
import sys
396
397
class WebSocketTraceFilter(logging.Filter):
398
"""Custom filter for WebSocket trace messages."""
399
400
def __init__(self, include_frames=True, include_handshake=True):
401
super().__init__()
402
self.include_frames = include_frames
403
self.include_handshake = include_handshake
404
405
def filter(self, record):
406
message = record.getMessage()
407
408
# Filter frame-level messages
409
if not self.include_frames and ("++Sent raw:" in message or "++Rcv raw:" in message):
410
return False
411
412
# Filter handshake messages
413
if not self.include_handshake and "handshake" in message.lower():
414
return False
415
416
return True
417
418
# Create filtered handler
419
handler = logging.StreamHandler(sys.stdout)
420
handler.addFilter(WebSocketTraceFilter(include_frames=False, include_handshake=True))
421
422
# Enable tracing with filter
423
websocket.enableTrace(True, handler=handler, level="DEBUG")
424
425
# This will show handshake details but not frame-by-frame data
426
ws = websocket.create_connection("ws://echo.websocket.events/")
427
ws.send("Hello")
428
response = ws.recv()
429
ws.close()
430
```