Repository: mkdocs/mkdocs

Issue:
Is there a way to see exactly which `page_markdown` event is being ran for each plugin?
We have this warning being printed out when debug logging is enabled, right before the build "hangs" on a specific file:

```
[ DEBUG    ][ mkdocs.plugins ][ plugins.py:517  ] Running 6 `page_markdown` events
```

But it doesn't tell me which of our plugins it is currently running / which plugin is causing the build to stall.

Could we potentially add another debug print (or alter the existing one) to show which `page_markdown` event is being ran? Or is it up to each plugin to add another debug print within their individual `page_markdown` method(s)?


Discussion:
I think what I'm asking for is to add one more `debug` print here within the loop of [line 505 of the `mkdocs/plugins.py` file](https://github.com/mkdocs/mkdocs/blob/master/mkdocs/plugins.py#L505) that includes the name of the plugin that is being ran...something like:

```
            log.debug(f"Running `{name}` event for `{method.__module__.__str__()}`")
```
There is currently no way to do it. Indeed you can just edit MkDocs like this to achieve this effect.

```patch
diff --git a/mkdocs/plugins.py b/mkdocs/plugins.py
index eeb7139e3..faef28683 100644
--- a/mkdocs/plugins.py
+++ b/mkdocs/plugins.py
@@ -503,6 +503,7 @@ class PluginCollection(dict, MutableMapping[str, BasePlugin]):
         if events:
             log.debug(f'Running {len(events)} `{name}` events')
         for method in events:
+            log.debug(f"Running `{name}` event from '{method.__module__}'")
             if pass_item:
                 result = method(item, **kwargs)
             else:
```

And I intend to add something a bit more robust for the next release

Resolving patch:
diff --git a/mkdocs/plugins.py b/mkdocs/plugins.py
--- a/mkdocs/plugins.py
+++ b/mkdocs/plugins.py
@@ -454,12 +454,20 @@ class PluginCollection(dict, MutableMapping[str, BasePlugin]):
     def __init__(self, *args, **kwargs) -> None:
         super().__init__(*args, **kwargs)
         self.events: dict[str, list[Callable]] = {k: [] for k in EVENTS}
+        self._event_origins: dict[Callable, str] = {}
 
-    def _register_event(self, event_name: str, method: Callable) -> None:
+    def _register_event(
+        self, event_name: str, method: Callable, plugin_name: str | None = None
+    ) -> None:
         """Register a method for an event."""
         utils.insort(
             self.events[event_name], method, key=lambda m: -getattr(m, 'mkdocs_priority', 0)
         )
+        if plugin_name:
+            try:
+                self._event_origins[method] = plugin_name
+            except TypeError:  # If the method is somehow not hashable.
+                pass
 
     def __getitem__(self, key: str) -> BasePlugin:
         return super().__getitem__(key)
@@ -470,7 +478,7 @@ def __setitem__(self, key: str, value: BasePlugin) -> None:
         for event_name in (x for x in dir(value) if x.startswith('on_')):
             method = getattr(value, event_name, None)
             if callable(method):
-                self._register_event(event_name[3:], method)
+                self._register_event(event_name[3:], method, plugin_name=key)
 
     @overload
     def run_event(self, name: str, **kwargs) -> Any:
@@ -490,10 +498,10 @@ def run_event(self, name: str, item=None, **kwargs):
         be modified by the event method.
         """
         pass_item = item is not None
-        events = self.events[name]
-        if events:
-            log.debug(f'Running {len(events)} `{name}` events')
-        for method in events:
+        for method in self.events[name]:
+            if log.getEffectiveLevel() <= logging.DEBUG:
+                plugin_name = self._event_origins.get(method, '<unknown>')
+                log.debug(f"Running `{name}` event from plugin '{plugin_name}'")
             if pass_item:
                 result = method(item, **kwargs)
             else:


Test patch: