@@ -26,8 +26,8 @@ To configure your environment for developing with the multicast library, follow
26
26
Key steps include:
27
27
28
28
1 . Ensuring you have a supported version of Python installed.
29
- 2 . Use pip to install (e.g., ` pip install multicast ` )
30
- 3 . Verify the installation works:
29
+ 2 . Using pip to install (e.g., ` pip install multicast ` )
30
+ 3 . Verifying the installation works:
31
31
32
32
| _ in ` Python ` _ | _ in ` bash ` _ |
33
33
| ---------------| -------------|
@@ -145,8 +145,8 @@ handler = logging.StreamHandler() # example trivial log handler
145
145
multicast_logging_sink.addHandler(handler)
146
146
147
147
# imports
148
- from multiprocessing import Process as Process
149
148
import multicast
149
+ from multiprocessing import Process
150
150
import random # for random port
151
151
152
152
# Multicast group address and port
@@ -180,6 +180,7 @@ Low-level with example handler:
180
180
# imports
181
181
import multicast
182
182
import random # for random port
183
+ import functools # for decorator func metadata
183
184
184
185
# Multicast group address and port
185
186
MCAST_GRP = " 224.0.0.1" # Replace with your multicast group address (use IPv4 dotted notation)
@@ -195,7 +196,6 @@ MCAST_PORT = int(random.SystemRandom().randint(49152, 65535)) # Replace with yo
195
196
# Windows users must use option 1 or 2 for now.
196
197
# This address is per socket (e.g., can be chosen per socket even if on a single interface)
197
198
198
-
199
199
# Options for multicast listener
200
200
listener_options = {
201
201
" is_daemon" : False , # bool: enable/disable daemon mode
@@ -207,7 +207,6 @@ listener_options = {
207
207
208
208
# Example setup for Low-Level use-case
209
209
# Define a decorator to loop until able to print a string result of enough length
210
- import functools
211
210
212
211
213
212
def printLoopStub (func ):
@@ -256,8 +255,8 @@ _and elsewhere (e.g., in another module or even on another system); an example f
256
255
257
256
``` python3
258
257
# imports
259
- from multiprocessing import Process as Process
260
258
import multicast
259
+ from multiprocessing import Process
261
260
262
261
# Multicast group address and port
263
262
MCAST_GRP = " 224.0.0.1" # Replace with your multicast group address (use IPv4 dotted notation)
@@ -295,7 +294,7 @@ finally:
295
294
if p:
296
295
p.join() # if not already handled don't forget to join the process and other overhead
297
296
# hint: if you use a loop and need to know the exit code
298
- didWork = (p is not None and int ( p.exitcode) <= int ( 0 ) ) # e.g. check for success
297
+ didWork = (p is not None and p.exitcode <= 0 ) # e.g. check for success
299
298
300
299
```
301
300
@@ -306,6 +305,80 @@ finally:
306
305
307
306
See also [ USAGE Guide] ( ./USAGE.md )
308
307
308
+ ### Why does multicast module logging require explicit handler setup instead of just basicConfig?
309
+
310
+ The multicast module uses a null log handler by default as part of its logging architecture. This
311
+ means that simply calling ` logging.basicConfig(level=logging.INFO) ` is insufficient to display the
312
+ ` multicast ` module's log records, as there's no active handler to capture and output them.
313
+
314
+ To see multicast module logging output, you must explicitly add a log handler:
315
+
316
+ ``` mermaid
317
+
318
+ sequenceDiagram
319
+ participant Python as Your Python Code
320
+ participant multicast as Multicast Module
321
+ participant logging as `logging` module
322
+
323
+ Python-->>logging: import logging
324
+ opt setup custom log handler
325
+ create participant Handler as Your Explicit Log Handler
326
+ Python-->>Handler: create `logger` object
327
+ Python-->>logging: add custom log handler
328
+ end
329
+ Python-->>multicast: import multicast
330
+ multicast-->>logging: add default logging.NullHandler log handler
331
+ multicast-->>logging: logs any multicast module output
332
+ opt has added custom log handler
333
+ logging->>Handler: handle logging
334
+ Handler->>logging: the handler logic
335
+ end
336
+ multicast-->>Python: initialized
337
+ loop main stuff
338
+ alt doing whatever
339
+ Python-->>Python: Your Non-multicast logic
340
+ else using multicast
341
+ Python-->>multicast: make API call to multicast
342
+ opt module has log output
343
+ multicast-->>logging: logs any multicast module output
344
+ opt has handler
345
+ logging->>Handler: handle logging
346
+ Handler->>logging: the handler logic
347
+ end
348
+ end
349
+ multicast-->>Python: reply to API call
350
+ end
351
+ end
352
+ Python-xPython: done
353
+ opt has custom log handler
354
+ destroy Handler
355
+ Python--xHandler: cleanup
356
+ end
357
+ ```
358
+
359
+ #### Required approach - explicit handler setup
360
+
361
+ > [ !IMPORTANT]
362
+ > ` logging ` must be setup _ before_ importing ` multicast ` or the ` NullHandler ` setup by ` multicast `
363
+ > will be first and still be-able to intercept the module's ` logging.LogRecords ` just as it
364
+ > normally would.
365
+
366
+ ```
367
+ import logging
368
+ multicast_logging_sink = logging.getLogger()
369
+ multicast_logging_sink.setLevel(logging.INFO) # optional, otherwise the module is very quiet
370
+ handler = logging.StreamHandler() # replace with your explicit handler
371
+ multicast_logging_sink.addHandler(handler)
372
+ ```
373
+
374
+ This explicit setup ensures that:
375
+
376
+ * The log level is set appropriately (e.g., ` logging.INFO ` )
377
+ * An active handler (e.g., ` StreamHandler ` ) is added to capture module log records
378
+ * The multicast module's log output becomes visible to users
379
+ * While logging.basicConfig() might seem simpler, it won't work with the multicast module's logging
380
+ architecture and will result in no visible log output from the library.
381
+
309
382
### How do I run and interpret the test suite for this project?
310
383
311
384
To run the test suite, follow the instructions in the [ Testing Guide] ( ./Testing.md ) .
0 commit comments