We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Adding loguru compatiblity with pytest caplog
## Description
`caplog` fixture in pytest captures the logging output for testing if appropriate warnings have been raised.

By default pytest uses the standard `logging` module, but since we are using `loguru` appropriate patching needs to be added.

## Additional Context
https://loguru.readthedocs.io/en/stable/resources/migration.html#making-things-work-with-pytest-and-caplog


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/syft/logger.py`
Content:
```
1 # stdlib
2 import os
3 from typing import Any
4 from typing import Callable
5 from typing import NoReturn
6 from typing import TextIO
7 from typing import Union
8 
9 # third party
10 from loguru import logger
11 
12 LOG_FORMAT = "[{time}][{level}][{module}]][{process.id}] {message}"
13 
14 logger.remove()
15 DEFAULT_SINK = "syft_{time}.log"
16 
17 
18 def remove() -> None:
19     logger.remove()
20 
21 
22 def add(
23     sink: Union[None, str, os.PathLike, TextIO] = None,
24     level: str = "ERROR",
25 ) -> None:
26     sink = DEFAULT_SINK if sink is None else sink
27     try:
28         logger.add(
29             sink=sink,
30             format=LOG_FORMAT,
31             enqueue=True,
32             colorize=False,
33             diagnose=True,
34             backtrace=True,
35             rotation="10 MB",
36             retention="1 day",
37             level=level,
38         )
39     except BaseException:
40         logger.add(
41             sink=sink,
42             format=LOG_FORMAT,
43             enqueue=True,
44             colorize=False,
45             diagnose=True,
46             backtrace=True,
47             level=level,
48         )
49 
50 
51 def traceback_and_raise(e: Any, verbose: bool = False) -> NoReturn:
52     try:
53         if verbose:
54             logger.opt(lazy=True).exception(e)
55         else:
56             logger.opt(lazy=True).critical(e)
57     except BaseException as ex:
58         logger.debug("failed to print exception", ex)
59     if not issubclass(type(e), Exception):
60         e = Exception(e)
61     raise e
62 
63 
64 def create_log_and_print_function(level: str) -> Callable:
65     def log_and_print(*args: Any, **kwargs: Any) -> None:
66         try:
67             method = getattr(logger.opt(lazy=True), level, None)
68             if "print" in kwargs and kwargs["print"] is True:
69                 del kwargs["print"]
70                 print(*args, **kwargs)
71                 if "end" in kwargs:
72                     # clean up extra end for printing
73                     del kwargs["end"]
74 
75             if method is not None:
76                 method(*args, **kwargs)
77             else:
78                 raise Exception(f"no method {level} on logger")
79         except BaseException as e:
80             msg = f"failed to log exception. {e}"
81             try:
82                 logger.debug(msg)
83             except Exception as e:
84                 print(f"{msg}. {e}")
85 
86     return log_and_print
87 
88 
89 def traceback(*args: Any, **kwargs: Any) -> None:
90     return create_log_and_print_function(level="exception")(*args, **kwargs)
91 
92 
93 def critical(*args: Any, **kwargs: Any) -> None:
94     return create_log_and_print_function(level="critical")(*args, **kwargs)
95 
96 
97 def error(*args: Any, **kwargs: Any) -> None:
98     return create_log_and_print_function(level="error")(*args, **kwargs)
99 
100 
101 def warning(*args: Any, **kwargs: Any) -> None:
102     return create_log_and_print_function(level="warning")(*args, **kwargs)
103 
104 
105 def info(*args: Any, **kwargs: Any) -> None:
106     return create_log_and_print_function(level="info")(*args, **kwargs)
107 
108 
109 def debug(*args: Any, **kwargs: Any) -> None:
110     return create_log_and_print_function(level="debug")(*args, **kwargs)
111 
112 
113 def trace(*args: Any, **kwargs: Any) -> None:
114     return create_log_and_print_function(level="trace")(*args, **kwargs)
115
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/syft/logger.py b/src/syft/logger.py
--- a/src/syft/logger.py
+++ b/src/syft/logger.py
@@ -1,4 +1,5 @@
 # stdlib
+import logging
 import os
 from typing import Any
 from typing import Callable
@@ -20,7 +21,7 @@
 
 
 def add(
-    sink: Union[None, str, os.PathLike, TextIO] = None,
+    sink: Union[None, str, os.PathLike, TextIO, logging.Handler] = None,
     level: str = "ERROR",
 ) -> None:
     sink = DEFAULT_SINK if sink is None else sink
@@ -40,7 +41,6 @@
         logger.add(
             sink=sink,
             format=LOG_FORMAT,
-            enqueue=True,
             colorize=False,
             diagnose=True,
             backtrace=True,

{"golden_diff": "diff --git a/src/syft/logger.py b/src/syft/logger.py\n--- a/src/syft/logger.py\n+++ b/src/syft/logger.py\n@@ -1,4 +1,5 @@\n # stdlib\n+import logging\n import os\n from typing import Any\n from typing import Callable\n@@ -20,7 +21,7 @@\n \n \n def add(\n-    sink: Union[None, str, os.PathLike, TextIO] = None,\n+    sink: Union[None, str, os.PathLike, TextIO, logging.Handler] = None,\n     level: str = \"ERROR\",\n ) -> None:\n     sink = DEFAULT_SINK if sink is None else sink\n@@ -40,7 +41,6 @@\n         logger.add(\n             sink=sink,\n             format=LOG_FORMAT,\n-            enqueue=True,\n             colorize=False,\n             diagnose=True,\n             backtrace=True,\n", "issue": "Adding loguru compatiblity with pytest caplog\n## Description\r\n`caplog` fixture in pytest captures the logging output for testing if appropriate warnings have been raised.\r\n\r\nBy default pytest uses the standard `logging` module, but since we are using `loguru` appropriate patching needs to be added.\r\n\r\n## Additional Context\r\nhttps://loguru.readthedocs.io/en/stable/resources/migration.html#making-things-work-with-pytest-and-caplog\r\n\n", "before_files": [{"content": "# stdlib\nimport os\nfrom typing import Any\nfrom typing import Callable\nfrom typing import NoReturn\nfrom typing import TextIO\nfrom typing import Union\n\n# third party\nfrom loguru import logger\n\nLOG_FORMAT = \"[{time}][{level}][{module}]][{process.id}] {message}\"\n\nlogger.remove()\nDEFAULT_SINK = \"syft_{time}.log\"\n\n\ndef remove() -> None:\n    logger.remove()\n\n\ndef add(\n    sink: Union[None, str, os.PathLike, TextIO] = None,\n    level: str = \"ERROR\",\n) -> None:\n    sink = DEFAULT_SINK if sink is None else sink\n    try:\n        logger.add(\n            sink=sink,\n            format=LOG_FORMAT,\n            enqueue=True,\n            colorize=False,\n            diagnose=True,\n            backtrace=True,\n            rotation=\"10 MB\",\n            retention=\"1 day\",\n            level=level,\n        )\n    except BaseException:\n        logger.add(\n            sink=sink,\n            format=LOG_FORMAT,\n            enqueue=True,\n            colorize=False,\n            diagnose=True,\n            backtrace=True,\n            level=level,\n        )\n\n\ndef traceback_and_raise(e: Any, verbose: bool = False) -> NoReturn:\n    try:\n        if verbose:\n            logger.opt(lazy=True).exception(e)\n        else:\n            logger.opt(lazy=True).critical(e)\n    except BaseException as ex:\n        logger.debug(\"failed to print exception\", ex)\n    if not issubclass(type(e), Exception):\n        e = Exception(e)\n    raise e\n\n\ndef create_log_and_print_function(level: str) -> Callable:\n    def log_and_print(*args: Any, **kwargs: Any) -> None:\n        try:\n            method = getattr(logger.opt(lazy=True), level, None)\n            if \"print\" in kwargs and kwargs[\"print\"] is True:\n                del kwargs[\"print\"]\n                print(*args, **kwargs)\n                if \"end\" in kwargs:\n                    # clean up extra end for printing\n                    del kwargs[\"end\"]\n\n            if method is not None:\n                method(*args, **kwargs)\n            else:\n                raise Exception(f\"no method {level} on logger\")\n        except BaseException as e:\n            msg = f\"failed to log exception. {e}\"\n            try:\n                logger.debug(msg)\n            except Exception as e:\n                print(f\"{msg}. {e}\")\n\n    return log_and_print\n\n\ndef traceback(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"exception\")(*args, **kwargs)\n\n\ndef critical(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"critical\")(*args, **kwargs)\n\n\ndef error(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"error\")(*args, **kwargs)\n\n\ndef warning(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"warning\")(*args, **kwargs)\n\n\ndef info(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"info\")(*args, **kwargs)\n\n\ndef debug(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"debug\")(*args, **kwargs)\n\n\ndef trace(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"trace\")(*args, **kwargs)\n", "path": "src/syft/logger.py"}], "after_files": [{"content": "# stdlib\nimport logging\nimport os\nfrom typing import Any\nfrom typing import Callable\nfrom typing import NoReturn\nfrom typing import TextIO\nfrom typing import Union\n\n# third party\nfrom loguru import logger\n\nLOG_FORMAT = \"[{time}][{level}][{module}]][{process.id}] {message}\"\n\nlogger.remove()\nDEFAULT_SINK = \"syft_{time}.log\"\n\n\ndef remove() -> None:\n    logger.remove()\n\n\ndef add(\n    sink: Union[None, str, os.PathLike, TextIO, logging.Handler] = None,\n    level: str = \"ERROR\",\n) -> None:\n    sink = DEFAULT_SINK if sink is None else sink\n    try:\n        logger.add(\n            sink=sink,\n            format=LOG_FORMAT,\n            enqueue=True,\n            colorize=False,\n            diagnose=True,\n            backtrace=True,\n            rotation=\"10 MB\",\n            retention=\"1 day\",\n            level=level,\n        )\n    except BaseException:\n        logger.add(\n            sink=sink,\n            format=LOG_FORMAT,\n            colorize=False,\n            diagnose=True,\n            backtrace=True,\n            level=level,\n        )\n\n\ndef traceback_and_raise(e: Any, verbose: bool = False) -> NoReturn:\n    try:\n        if verbose:\n            logger.opt(lazy=True).exception(e)\n        else:\n            logger.opt(lazy=True).critical(e)\n    except BaseException as ex:\n        logger.debug(\"failed to print exception\", ex)\n    if not issubclass(type(e), Exception):\n        e = Exception(e)\n    raise e\n\n\ndef create_log_and_print_function(level: str) -> Callable:\n    def log_and_print(*args: Any, **kwargs: Any) -> None:\n        try:\n            method = getattr(logger.opt(lazy=True), level, None)\n            if \"print\" in kwargs and kwargs[\"print\"] is True:\n                del kwargs[\"print\"]\n                print(*args, **kwargs)\n                if \"end\" in kwargs:\n                    # clean up extra end for printing\n                    del kwargs[\"end\"]\n\n            if method is not None:\n                method(*args, **kwargs)\n            else:\n                raise Exception(f\"no method {level} on logger\")\n        except BaseException as e:\n            msg = f\"failed to log exception. {e}\"\n            try:\n                logger.debug(msg)\n            except Exception as e:\n                print(f\"{msg}. {e}\")\n\n    return log_and_print\n\n\ndef traceback(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"exception\")(*args, **kwargs)\n\n\ndef critical(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"critical\")(*args, **kwargs)\n\n\ndef error(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"error\")(*args, **kwargs)\n\n\ndef warning(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"warning\")(*args, **kwargs)\n\n\ndef info(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"info\")(*args, **kwargs)\n\n\ndef debug(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"debug\")(*args, **kwargs)\n\n\ndef trace(*args: Any, **kwargs: Any) -> None:\n    return create_log_and_print_function(level=\"trace\")(*args, **kwargs)\n", "path": "src/syft/logger.py"}]}