Skip to content

Conversation

@parth-soni07
Copy link
Contributor

What was wrong?

Fix logging standardization in core modules (Phase 1)

Issue #906

Changes

  • Updated 31 core modules to use logging.getLogger(name)
  • Verified module-specific logging control works correctly
  • Ensured no import errors or functionality changes
  • Introduced test suit to make sure things are working as expected

Network & Host (4 files)

  • libp2p/network/swarm.py
  • libp2p/host/basic_host.py
  • libp2p/host/ping.py
  • libp2p/host/autonat/autonat.py

Transport & Stream Muxer (6 files)

  • libp2p/transport/tcp/tcp.py
  • libp2p/transport/websocket/listener.py
  • libp2p/transport/websocket/autotls.py
  • libp2p/transport/transport_registry.py
  • libp2p/stream_muxer/yamux/yamux.py
  • libp2p/stream_muxer/mplex/mplex.py

Pubsub (4 files)

  • libp2p/pubsub/pubsub.py
  • libp2p/pubsub/floodsub.py
  • libp2p/pubsub/gossipsub.py
  • libp2p/pubsub/validators.py

Relay Circuit v2 (5 files)

  • libp2p/relay/circuit_v2/transport.py
  • libp2p/relay/circuit_v2/protocol.py
  • libp2p/relay/circuit_v2/discovery.py
  • libp2p/relay/circuit_v2/utils.py
  • libp2p/relay/circuit_v2/nat.py

Discovery (8 files)

  • libp2p/discovery/bootstrap/bootstrap.py
  • libp2p/discovery/bootstrap/utils.py
  • libp2p/discovery/mdns/mdns.py
  • libp2p/discovery/mdns/listener.py
  • libp2p/discovery/mdns/broadcaster.py
  • libp2p/discovery/random_walk/random_walk.py
  • libp2p/discovery/random_walk/rt_refresh_manager.py
  • libp2p/discovery/upnp/upnp.py

Protocol Muxer (1 file)

  • libp2p/protocol_muxer/multiselect_client.py

Utils & IO (3 files)

  • libp2p/io/trio.py
  • libp2p/utils/version.py
  • libp2p/utils/varint.py

Test Files Created (1 file)

  • tests/utils/test_logger_standardization.py

Change Summary

Total Files Changed: 32 files (31 source files + 1 test file)

Change Pattern

Before:

logger = logging.getLogger("libp2p.network.swarm")

After:

logger = logging.getLogger(__name__)

Benefits

  1. Consistency: All modules now use the standard Python logging pattern
  2. Maintainability: Logger names automatically match module paths
  3. Best Practices: Follows Python logging recommendations

Testing

A comprehensive test suite was created in tests/utils/test_logger_standardization.py that verifies:

  • Logger names match module paths
  • Logger inheritance works correctly
  • All 31 updated modules have correct logger names

@parth-soni07
Copy link
Contributor Author

CCing @seetadev @pacrob @acul71

@acul71
Copy link
Contributor

acul71 commented Jan 5, 2026

Thanks @parth-soni07 for this PR.

Findings

  1. Missing newsfragment (BLOCKER): No newsfragment file for issue Logger Standardization in Core Modules (Phase 1) #906. This blocks approval.

  2. Quality: The PR standardizes logger names across 31 core modules using logging.getLogger(__name__), following Python best practices.

  3. Test coverage: Added 11 test cases covering all updated modules and logging behavior.

  4. Bug fix: Corrects an incorrect logger name in basic_host.py (was libp2p.network.basic_host, now libp2p.host.basic_host).

  5. All checks pass:

    • ✅ Linting: All checks passed
    • ✅ Type checking: Passed
    • ✅ Tests: 1822 passed, 15 skipped, 0 failures
    • ✅ Documentation: Build successful

Recommendation

Can you add a newsfragment file (newsfragments/906.internal.rst) ? See https://github.com/libp2p/py-libp2p/blob/main/newsfragments/README.md

@parth-soni07
Copy link
Contributor Author

parth-soni07 commented Jan 6, 2026

Thanks @parth-soni07 for this PR.

Findings

  1. Missing newsfragment (BLOCKER): No newsfragment file for issue Logger Standardization in Core Modules (Phase 1) #906. This blocks approval.

  2. Quality: The PR standardizes logger names across 31 core modules using logging.getLogger(__name__), following Python best practices.

  3. Test coverage: Added 11 test cases covering all updated modules and logging behavior.

  4. Bug fix: Corrects an incorrect logger name in basic_host.py (was libp2p.network.basic_host, now libp2p.host.basic_host).

  5. All checks pass:

    • ✅ Linting: All checks passed
    • ✅ Type checking: Passed
    • ✅ Tests: 1822 passed, 15 skipped, 0 failures
    • ✅ Documentation: Build successful

Recommendation

Can you add a newsfragment file (newsfragments/906.internal.rst) ? See https://github.com/libp2p/py-libp2p/blob/main/newsfragments/README.md

hey @acul71 , thanks for the feedback, I have added the newsfragment in the PR now. I think for the rest we are good to go!

@pacrob
Copy link
Member

pacrob commented Jan 7, 2026

It looks like this handles everything that was touched in #902 . Can that one be closed once this is merged?

Searching for logging.getLogger, I see that you've updated most locations, but there are still a few that use the explicit naming such as in kad_dht. Is there a reason not to do everything here, or do you have a Phase 2 planned?

We can also close #84 once this merges.

@seetadev
Copy link
Contributor

seetadev commented Jan 7, 2026

@pacrob : Thank you so much for your review, inputs and feedback. Appreciate it 👍

Yes — this PR is intended to cover everything touched in #902, so we can definitely close that once this is merged. Did discuss in detail with @parth-soni07 before he started working on this PR.

Great catch on the remaining logging.getLogger usages, especially in kad_dht. There’s no strong reason to leave those out.

@parth-soni07 : Wish if you could completed the feedback points shared by @pacrob in this PR as well so we end up fully consistent. Appreciate your efforts.

Wish to also share that @acul71 and @sumanjeet0012 are in favor of consolidating everything here in this PR.

@pacrob : +1, Agreed on closing #84 as well once this lands. Thanks for the careful review. Appreciate your great support.

@parth-soni07
Copy link
Contributor Author

Hey @pacrob, thanks for the feedback, yes I do have a plan for phase 2 or we can include those changes in this PR as well if you approve as there are some cases including the kad_dht which needs your attention before we update them. Here are the points that need yours & @seetadev's decision before we proceed:

Logger Standardization: Special Cases

Core Objective

We've standardized 31 core modules to use logging.getLogger(__name__). However, 9 files still use non-standard logger names. This document identifies what needs to be decided before we can standardize them.


Quick Summary

Special Case Files Affected External Dependencies Decision Needed
Example Loggers 7 files (kad_dht + pubsub) Yes - 2 files Standardize or keep?
Records Validator 1 file None Safe to fix?
Async Service 1 file Yes - 2 files Standardize naming?

Total Files to Update: 9 source files + 4 dependent files (if standardizing)


1. Example Loggers (7 files)

Current Logger Names

  • libp2p/kad_dht/kad_dht.py"kademlia-example.kad_dht"
  • libp2p/kad_dht/value_store.py"kademlia-example.value_store"
  • libp2p/kad_dht/provider_store.py"kademlia-example.provider_store"
  • libp2p/kad_dht/peer_routing.py"kademlia-example.peer_routing"
  • libp2p/kad_dht/routing_table.py"kademlia-example.routing_table"
  • libp2p/kad_dht/utils.py"kademlia-example.utils"
  • libp2p/pubsub/utils.py"pubsub-example.utils"

Where These Are Used

kademlia-example. loggers:*

  1. examples/kademlia/kademlia.py (lines 90, 106-107)

    logger = logging.getLogger("kademlia-example")
    # ...
    child_logger = logging.getLogger(f"kademlia-example.{module}")
  2. docs/examples.kademlia.rst - Documentation shows example log output with these names

pubsub-example.utils:

  • No external usage found (only within the module)

What Changes If We Standardize

Source Files (7 files):

# Change from:
logger = logging.getLogger("kademlia-example.kad_dht")

# To:
logger = logging.getLogger(__name__)  # "libp2p.kad_dht.kad_dht"

Dependent Files (need updates):

  1. examples/kademlia/kademlia.py - Update logger names:

    # Change from:
    logger = logging.getLogger("kademlia-example")
    child_logger = logging.getLogger(f"kademlia-example.{module}")
    
    # To:
    logger = logging.getLogger("libp2p.kad_dht")
    child_logger = logging.getLogger(f"libp2p.kad_dht.{module}")
  2. docs/examples.kademlia.rst - Update example log output to show new logger names

Questions for Decision

  • Why the -example suffix? Historical reason?
  • OK to standardize (might act as a breaking change for examples)?
  • Update examples/docs or keep old names?

2. Records Validator (1 file)

Current Logger Name

  • libp2p/records/validator.py"records-validator"

What's Wrong

Problems with current logger name:

  1. Missing libp2p. prefix - Should be "libp2p.records.validator" not "records-validator"
  2. Wrong format - Uses hyphen - instead of dots . (Python logging convention)
  3. Doesn't match module path - Module is at libp2p.records.validator but logger doesn't reflect this
  4. Cannot use LIBP2P_DEBUG - LIBP2P_DEBUG=records.validator:DEBUG won't work (needs libp2p.* prefix)

Note: The logger is defined but not currently used in the file (no logger.debug(), logger.info(), etc. calls found).

What Changes If We Standardize

Source File (1 file):

# Change from:
logger = logging.getLogger("records-validator")

# To:
logger = logging.getLogger(__name__)  # "libp2p.records.validator"

Result:

  • Logger name becomes: "libp2p.records.validator" (matches module path)
  • Works with LIBP2P_DEBUG=records.validator:DEBUG
  • Consistent with all other standardized modules

Dependent Files:

  • None - Safe to update (no breaking changes)

Questions for Decision

  • Intentional naming or oversight/bug?

3. Async Service Manager (1 file)

Current Logger Name

  • libp2p/tools/async_service/base.py"async_service.Manager" (class-level logger)

Where This Is Used

  1. examples/bitswap/bitswap.py (line 33)

    logging.getLogger("async_service.Manager").setLevel(logging.WARNING)
  2. examples/doc-examples/example_mplex_timeouts.py (lines 50, 383)

    logging.getLogger("async_service").setLevel(logging.ERROR)
    # ...
    logging.getLogger("async_service").setLevel(logging.DEBUG)

What Changes If We Standardize

Source File (1 file):

Option A: Keep class-level, fix name

# Change from:
logger = logging.getLogger("async_service.Manager")

# To:
logger = logging.getLogger(f"{__name__}.Manager")  # "libp2p.tools.async_service.base.Manager"
# OR
logger = logging.getLogger("libp2p.tools.async_service.Manager")

Option B: Move to module-level

# At module level:
logger = logging.getLogger(__name__)  # "libp2p.tools.async_service.base"

# Use in class: logger.debug(...) instead of self.logger.debug(...)

Dependent Files (need updates):

  1. examples/bitswap/bitswap.py - Update logger name
  2. examples/doc-examples/example_mplex_timeouts.py - Update logger name

Questions for Decision

  • Why class-level logger? Multiple classes need different loggers?
  • Keep class-level or move to module-level?
  • Preferred naming: libp2p.tools.async_service.base.Manager or libp2p.tools.async_service.Manager?

Summary: What Needs to Be Updated

If We Standardize Everything:

Source Files (9 files):

  • 6 files in libp2p/kad_dht/
  • 1 file in libp2p/pubsub/ (utils.py)
  • 1 file in libp2p/records/ (validator.py)
  • 1 file in libp2p/tools/async_service/ (base.py)

Dependent Files (4 files):

  • examples/kademlia/kademlia.py
  • examples/bitswap/bitswap.py
  • examples/doc-examples/example_mplex_timeouts.py
  • docs/examples.kademlia.rst

Total: 13 files (9 source + 4 dependent)

Next Steps

Once I get feedback on the 3 questions above I'll update all files accordingly.
Also CCing @acul71 & @sumanjeet0012 to also have a look to the same. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants