METADATA 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. Metadata-Version: 2.3
  2. Name: loguru
  3. Version: 0.7.3
  4. Summary: Python logging made (stupidly) simple
  5. Keywords: loguru,logging,logger,log
  6. Author-email: Delgan <delgan.py@gmail.com>
  7. Requires-Python: >=3.5,<4.0
  8. Description-Content-Type: text/markdown
  9. Classifier: Development Status :: 5 - Production/Stable
  10. Classifier: Topic :: System :: Logging
  11. Classifier: Intended Audience :: Developers
  12. Classifier: Natural Language :: English
  13. Classifier: License :: OSI Approved :: MIT License
  14. Classifier: Operating System :: OS Independent
  15. Classifier: Programming Language :: Python
  16. Classifier: Programming Language :: Python :: 3
  17. Classifier: Programming Language :: Python :: 3.5
  18. Classifier: Programming Language :: Python :: 3.6
  19. Classifier: Programming Language :: Python :: 3.7
  20. Classifier: Programming Language :: Python :: 3.8
  21. Classifier: Programming Language :: Python :: 3.9
  22. Classifier: Programming Language :: Python :: 3.10
  23. Classifier: Programming Language :: Python :: 3.11
  24. Classifier: Programming Language :: Python :: 3.12
  25. Classifier: Programming Language :: Python :: 3.13
  26. Classifier: Programming Language :: Python :: 3 :: Only
  27. Classifier: Programming Language :: Python :: Implementation :: PyPy
  28. Classifier: Programming Language :: Python :: Implementation :: CPython
  29. Requires-Dist: colorama>=0.3.4 ; sys_platform=='win32'
  30. Requires-Dist: aiocontextvars>=0.2.0 ; python_version<'3.7'
  31. Requires-Dist: win32-setctime>=1.0.0 ; sys_platform=='win32'
  32. Requires-Dist: pre-commit==4.0.1 ; extra == "dev" and ( python_version>='3.9')
  33. Requires-Dist: tox==3.27.1 ; extra == "dev" and ( python_version<'3.8')
  34. Requires-Dist: tox==4.23.2 ; extra == "dev" and ( python_version>='3.8')
  35. Requires-Dist: pytest==6.1.2 ; extra == "dev" and ( python_version<'3.8')
  36. Requires-Dist: pytest==8.3.2 ; extra == "dev" and ( python_version>='3.8')
  37. Requires-Dist: pytest-cov==2.12.1 ; extra == "dev" and ( python_version<'3.8')
  38. Requires-Dist: pytest-cov==5.0.0 ; extra == "dev" and ( python_version>='3.8' and python_version<'3.9')
  39. Requires-Dist: pytest-cov==6.0.0 ; extra == "dev" and ( python_version>='3.9')
  40. Requires-Dist: pytest-mypy-plugins==1.9.3 ; extra == "dev" and ( python_version>='3.6' and python_version<'3.8')
  41. Requires-Dist: pytest-mypy-plugins==3.1.0 ; extra == "dev" and ( python_version>='3.8')
  42. Requires-Dist: colorama==0.4.5 ; extra == "dev" and ( python_version<'3.8')
  43. Requires-Dist: colorama==0.4.6 ; extra == "dev" and ( python_version>='3.8')
  44. Requires-Dist: freezegun==1.1.0 ; extra == "dev" and ( python_version<'3.8')
  45. Requires-Dist: freezegun==1.5.0 ; extra == "dev" and ( python_version>='3.8')
  46. Requires-Dist: exceptiongroup==1.1.3 ; extra == "dev" and ( python_version>='3.7' and python_version<'3.11')
  47. Requires-Dist: mypy==v0.910 ; extra == "dev" and ( python_version<'3.6')
  48. Requires-Dist: mypy==v0.971 ; extra == "dev" and ( python_version>='3.6' and python_version<'3.7')
  49. Requires-Dist: mypy==v1.4.1 ; extra == "dev" and ( python_version>='3.7' and python_version<'3.8')
  50. Requires-Dist: mypy==v1.13.0 ; extra == "dev" and ( python_version>='3.8')
  51. Requires-Dist: Sphinx==8.1.3 ; extra == "dev" and ( python_version>='3.11')
  52. Requires-Dist: sphinx-rtd-theme==3.0.2 ; extra == "dev" and ( python_version>='3.11')
  53. Requires-Dist: myst-parser==4.0.0 ; extra == "dev" and ( python_version>='3.11')
  54. Requires-Dist: build==1.2.2 ; extra == "dev" and ( python_version>='3.11')
  55. Requires-Dist: twine==6.0.1 ; extra == "dev" and ( python_version>='3.11')
  56. Project-URL: Changelog, https://github.com/Delgan/loguru/blob/master/CHANGELOG.rst
  57. Project-URL: Documentation, https://loguru.readthedocs.io/en/stable/index.html
  58. Project-URL: Homepage, https://github.com/Delgan/loguru
  59. Provides-Extra: dev
  60. <p align="center">
  61. <a href="#readme">
  62. <img alt="Loguru logo" src="https://raw.githubusercontent.com/Delgan/loguru/master/docs/_static/img/logo.png">
  63. <!-- Logo credits: Sambeet from Pixaday -->
  64. <!-- Logo fonts: Comfortaa + Raleway -->
  65. </a>
  66. </p>
  67. <p align="center">
  68. <a href="https://pypi.python.org/pypi/loguru"><img alt="Pypi version" src="https://img.shields.io/pypi/v/loguru.svg"></a>
  69. <a href="https://pypi.python.org/pypi/loguru"><img alt="Python versions" src="https://img.shields.io/badge/python-3.5%2B%20%7C%20PyPy-blue.svg"></a>
  70. <a href="https://loguru.readthedocs.io/en/stable/index.html"><img alt="Documentation" src="https://img.shields.io/readthedocs/loguru.svg"></a>
  71. <a href="https://github.com/Delgan/loguru/actions/workflows/tests.yml?query=branch:master"><img alt="Build status" src="https://img.shields.io/github/actions/workflow/status/Delgan/loguru/tests.yml?branch=master"></a>
  72. <a href="https://codecov.io/gh/delgan/loguru/branch/master"><img alt="Coverage" src="https://img.shields.io/codecov/c/github/delgan/loguru/master.svg"></a>
  73. <a href="https://app.codacy.com/gh/Delgan/loguru/dashboard"><img alt="Code quality" src="https://img.shields.io/codacy/grade/be7337df3c0d40d1929eb7f79b1671a6.svg"></a>
  74. <a href="https://github.com/Delgan/loguru/blob/master/LICENSE"><img alt="License" src="https://img.shields.io/github/license/delgan/loguru.svg"></a>
  75. </p>
  76. <p align="center">
  77. <a href="#readme">
  78. <img alt="Loguru logo" src="https://raw.githubusercontent.com/Delgan/loguru/master/docs/_static/img/demo.gif">
  79. </a>
  80. </p>
  81. ______________________________________________________________________
  82. **Loguru** is a library which aims to bring enjoyable logging in Python.
  83. Did you ever feel lazy about configuring a logger and used `print()` instead?... I did, yet logging is fundamental to every application and eases the process of debugging. Using **Loguru** you have no excuse not to use logging from the start, this is as simple as `from loguru import logger`.
  84. Also, this library is intended to make Python logging less painful by adding a bunch of useful functionalities that solve caveats of the standard loggers. Using logs in your application should be an automatism, **Loguru** tries to make it both pleasant and powerful.
  85. <!-- end-of-readme-intro -->
  86. ## Installation
  87. ```
  88. pip install loguru
  89. ```
  90. ## Features
  91. - [Ready to use out of the box without boilerplate](#ready-to-use-out-of-the-box-without-boilerplate)
  92. - [No Handler, no Formatter, no Filter: one function to rule them all](#no-handler-no-formatter-no-filter-one-function-to-rule-them-all)
  93. - [Easier file logging with rotation / retention / compression](#easier-file-logging-with-rotation--retention--compression)
  94. - [Modern string formatting using braces style](#modern-string-formatting-using-braces-style)
  95. - [Exceptions catching within threads or main](#exceptions-catching-within-threads-or-main)
  96. - [Pretty logging with colors](#pretty-logging-with-colors)
  97. - [Asynchronous, Thread-safe, Multiprocess-safe](#asynchronous-thread-safe-multiprocess-safe)
  98. - [Fully descriptive exceptions](#fully-descriptive-exceptions)
  99. - [Structured logging as needed](#structured-logging-as-needed)
  100. - [Lazy evaluation of expensive functions](#lazy-evaluation-of-expensive-functions)
  101. - [Customizable levels](#customizable-levels)
  102. - [Better datetime handling](#better-datetime-handling)
  103. - [Suitable for scripts and libraries](#suitable-for-scripts-and-libraries)
  104. - [Entirely compatible with standard logging](#entirely-compatible-with-standard-logging)
  105. - [Personalizable defaults through environment variables](#personalizable-defaults-through-environment-variables)
  106. - [Convenient parser](#convenient-parser)
  107. - [Exhaustive notifier](#exhaustive-notifier)
  108. - <s>[10x faster than built-in logging](#10x-faster-than-built-in-logging)</s>
  109. ## Take the tour
  110. ### Ready to use out of the box without boilerplate
  111. The main concept of Loguru is that **there is one and only one** [`logger`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger).
  112. For convenience, it is pre-configured and outputs to `stderr` to begin with (but that's entirely configurable).
  113. ```python
  114. from loguru import logger
  115. logger.debug("That's it, beautiful and simple logging!")
  116. ```
  117. The [`logger`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger) is just an interface which dispatches log messages to configured handlers. Simple, right?
  118. ### No Handler, no Formatter, no Filter: one function to rule them all
  119. How to add a handler? How to set up logs formatting? How to filter messages? How to set level?
  120. One answer: the [`add()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.add) function.
  121. ```python
  122. logger.add(sys.stderr, format="{time} {level} {message}", filter="my_module", level="INFO")
  123. ```
  124. This function should be used to register [sinks](https://loguru.readthedocs.io/en/stable/api/logger.html#sink) which are responsible for managing [log messages](https://loguru.readthedocs.io/en/stable/api/logger.html#message) contextualized with a [record dict](https://loguru.readthedocs.io/en/stable/api/logger.html#record). A sink can take many forms: a simple function, a string path, a file-like object, a coroutine function or a built-in Handler.
  125. Note that you may also a previously added handler by using the identifier returned while adding it. This is particularly useful if you want to supersede the default `stderr` handler: just call [`logger.remove()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.remove) to make a fresh start.
  126. ### Easier file logging with rotation / retention / compression
  127. If you want to send logged messages to a file, you just have to use a string path as the sink. It can be automatically timed too for convenience:
  128. ```python
  129. logger.add("file_{time}.log")
  130. ```
  131. It is also [easily configurable](https://loguru.readthedocs.io/en/stable/api/logger.html#file) if you need rotating logger, if you want to remove older logs, or if you wish to compress your files at closure.
  132. ```python
  133. logger.add("file_1.log", rotation="500 MB") # Automatically rotate too big file
  134. logger.add("file_2.log", rotation="12:00") # New file is created each day at noon
  135. logger.add("file_3.log", rotation="1 week") # Once the file is too old, it's rotated
  136. logger.add("file_X.log", retention="10 days") # Cleanup after some time
  137. logger.add("file_Y.log", compression="zip") # Save some loved space
  138. ```
  139. ### Modern string formatting using braces style
  140. Loguru favors the much more elegant and powerful `{}` formatting over `%`, logging functions are actually equivalent to `str.format()`.
  141. ```python
  142. logger.info("If you're using Python {}, prefer {feature} of course!", 3.6, feature="f-strings")
  143. ```
  144. ### Exceptions catching within threads or main
  145. Have you ever seen your program crashing unexpectedly without seeing anything in the log file? Did you ever notice that exceptions occurring in threads were not logged? This can be solved using the [`catch()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.catch) decorator / context manager which ensures that any error is correctly propagated to the [`logger`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger).
  146. ```python
  147. @logger.catch
  148. def my_function(x, y, z):
  149. # An error? It's caught anyway!
  150. return 1 / (x + y + z)
  151. ```
  152. ### Pretty logging with colors
  153. Loguru automatically adds colors to your logs if your terminal is compatible. You can define your favorite style by using [markup tags](https://loguru.readthedocs.io/en/stable/api/logger.html#color) in the sink format.
  154. ```python
  155. logger.add(sys.stdout, colorize=True, format="<green>{time}</green> <level>{message}</level>")
  156. ```
  157. ### Asynchronous, Thread-safe, Multiprocess-safe
  158. All sinks added to the [`logger`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger) are thread-safe by default. They are not multiprocess-safe, but you can `enqueue` the messages to ensure logs integrity. This same argument can also be used if you want async logging.
  159. ```python
  160. logger.add("somefile.log", enqueue=True)
  161. ```
  162. Coroutine functions used as sinks are also supported and should be awaited with [`complete()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.complete).
  163. ### Fully descriptive exceptions
  164. Logging exceptions that occur in your code is important to track bugs, but it's quite useless if you don't know why it failed. Loguru helps you identify problems by allowing the entire stack trace to be displayed, including values of variables (thanks [`better_exceptions`](https://github.com/Qix-/better-exceptions) for this!).
  165. The code:
  166. ```python
  167. # Caution, "diagnose=True" is the default and may leak sensitive data in prod
  168. logger.add("out.log", backtrace=True, diagnose=True)
  169. def func(a, b):
  170. return a / b
  171. def nested(c):
  172. try:
  173. func(5, c)
  174. except ZeroDivisionError:
  175. logger.exception("What?!")
  176. nested(0)
  177. ```
  178. Would result in:
  179. ```none
  180. 2018-07-17 01:38:43.975 | ERROR | __main__:nested:10 - What?!
  181. Traceback (most recent call last):
  182. File "test.py", line 12, in <module>
  183. nested(0)
  184. └ <function nested at 0x7f5c755322f0>
  185. > File "test.py", line 8, in nested
  186. func(5, c)
  187. │ └ 0
  188. └ <function func at 0x7f5c79fc2e18>
  189. File "test.py", line 4, in func
  190. return a / b
  191. │ └ 0
  192. └ 5
  193. ZeroDivisionError: division by zero
  194. ```
  195. Note that this feature won't work on default Python REPL due to unavailable frame data.
  196. See also: [Security considerations when using Loguru](https://loguru.readthedocs.io/en/stable/resources/recipes.html#security-considerations-when-using-loguru).
  197. ### Structured logging as needed
  198. Want your logs to be serialized for easier parsing or to pass them around? Using the `serialize` argument, each log message will be converted to a JSON string before being sent to the configured sink.
  199. ```python
  200. logger.add(custom_sink_function, serialize=True)
  201. ```
  202. Using [`bind()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.bind) you can contextualize your logger messages by modifying the `extra` record attribute.
  203. ```python
  204. logger.add("file.log", format="{extra[ip]} {extra[user]} {message}")
  205. context_logger = logger.bind(ip="192.168.0.1", user="someone")
  206. context_logger.info("Contextualize your logger easily")
  207. context_logger.bind(user="someone_else").info("Inline binding of extra attribute")
  208. context_logger.info("Use kwargs to add context during formatting: {user}", user="anybody")
  209. ```
  210. It is possible to modify a context-local state temporarily with [`contextualize()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.contextualize):
  211. ```python
  212. with logger.contextualize(task=task_id):
  213. do_something()
  214. logger.info("End of task")
  215. ```
  216. You can also have more fine-grained control over your logs by combining [`bind()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.bind) and `filter`:
  217. ```python
  218. logger.add("special.log", filter=lambda record: "special" in record["extra"])
  219. logger.debug("This message is not logged to the file")
  220. logger.bind(special=True).info("This message, though, is logged to the file!")
  221. ```
  222. Finally, the [`patch()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.patch) method allows dynamic values to be attached to the record dict of each new message:
  223. ```python
  224. logger.add(sys.stderr, format="{extra[utc]} {message}")
  225. logger = logger.patch(lambda record: record["extra"].update(utc=datetime.utcnow()))
  226. ```
  227. ### Lazy evaluation of expensive functions
  228. Sometime you would like to log verbose information without performance penalty in production, you can use the [`opt()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.opt) method to achieve this.
  229. ```python
  230. logger.opt(lazy=True).debug("If sink level <= DEBUG: {x}", x=lambda: expensive_function(2**64))
  231. # By the way, "opt()" serves many usages
  232. logger.opt(exception=True).info("Error stacktrace added to the log message (tuple accepted too)")
  233. logger.opt(colors=True).info("Per message <blue>colors</blue>")
  234. logger.opt(record=True).info("Display values from the record (eg. {record[thread]})")
  235. logger.opt(raw=True).info("Bypass sink formatting\n")
  236. logger.opt(depth=1).info("Use parent stack context (useful within wrapped functions)")
  237. logger.opt(capture=False).info("Keyword arguments not added to {dest} dict", dest="extra")
  238. ```
  239. ### Customizable levels
  240. Loguru comes with all standard [logging levels](https://loguru.readthedocs.io/en/stable/api/logger.html#levels) to which [`trace()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.trace) and [`success()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.success) are added. Do you need more? Then, just create it by using the [`level()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.level) function.
  241. ```python
  242. new_level = logger.level("SNAKY", no=38, color="<yellow>", icon="🐍")
  243. logger.log("SNAKY", "Here we go!")
  244. ```
  245. ### Better datetime handling
  246. The standard logging is bloated with arguments like `datefmt` or `msecs`, `%(asctime)s` and `%(created)s`, naive datetimes without timezone information, not intuitive formatting, etc. Loguru [fixes it](https://loguru.readthedocs.io/en/stable/api/logger.html#time):
  247. ```python
  248. logger.add("file.log", format="{time:YYYY-MM-DD at HH:mm:ss} | {level} | {message}")
  249. ```
  250. ### Suitable for scripts and libraries
  251. Using the logger in your scripts is easy, and you can [`configure()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.configure) it at start. To use Loguru from inside a library, remember to never call [`add()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.add) but use [`disable()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.disable) instead so logging functions become no-op. If a developer wishes to see your library's logs, they can [`enable()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.enable) it again.
  252. ```python
  253. # For scripts
  254. config = {
  255. "handlers": [
  256. {"sink": sys.stdout, "format": "{time} - {message}"},
  257. {"sink": "file.log", "serialize": True},
  258. ],
  259. "extra": {"user": "someone"}
  260. }
  261. logger.configure(**config)
  262. # For libraries, should be your library's `__name__`
  263. logger.disable("my_library")
  264. logger.info("No matter added sinks, this message is not displayed")
  265. # In your application, enable the logger in the library
  266. logger.enable("my_library")
  267. logger.info("This message however is propagated to the sinks")
  268. ```
  269. For additional convenience, you can also use the [`loguru-config`](https://github.com/erezinman/loguru-config) library to setup the `logger` directly from a configuration file.
  270. ### Entirely compatible with standard logging
  271. Wish to use built-in logging `Handler` as a Loguru sink?
  272. ```python
  273. handler = logging.handlers.SysLogHandler(address=('localhost', 514))
  274. logger.add(handler)
  275. ```
  276. Need to propagate Loguru messages to standard `logging`?
  277. ```python
  278. class PropagateHandler(logging.Handler):
  279. def emit(self, record: logging.LogRecord) -> None:
  280. logging.getLogger(record.name).handle(record)
  281. logger.add(PropagateHandler(), format="{message}")
  282. ```
  283. Want to intercept standard `logging` messages toward your Loguru sinks?
  284. ```python
  285. class InterceptHandler(logging.Handler):
  286. def emit(self, record: logging.LogRecord) -> None:
  287. # Get corresponding Loguru level if it exists.
  288. level: str | int
  289. try:
  290. level = logger.level(record.levelname).name
  291. except ValueError:
  292. level = record.levelno
  293. # Find caller from where originated the logged message.
  294. frame, depth = inspect.currentframe(), 0
  295. while frame and (depth == 0 or frame.f_code.co_filename == logging.__file__):
  296. frame = frame.f_back
  297. depth += 1
  298. logger.opt(depth=depth, exception=record.exc_info).log(level, record.getMessage())
  299. logging.basicConfig(handlers=[InterceptHandler()], level=0, force=True)
  300. ```
  301. ### Personalizable defaults through environment variables
  302. Don't like the default logger formatting? Would prefer another `DEBUG` color? [No problem](https://loguru.readthedocs.io/en/stable/api/logger.html#env):
  303. ```bash
  304. # Linux / OSX
  305. export LOGURU_FORMAT="{time} | <lvl>{message}</lvl>"
  306. # Windows
  307. setx LOGURU_DEBUG_COLOR "<green>"
  308. ```
  309. ### Convenient parser
  310. It is often useful to extract specific information from generated logs, this is why Loguru provides a [`parse()`](https://loguru.readthedocs.io/en/stable/api/logger.html#loguru._logger.Logger.parse) method which helps to deal with logs and regexes.
  311. ```python
  312. pattern = r"(?P<time>.*) - (?P<level>[0-9]+) - (?P<message>.*)" # Regex with named groups
  313. caster_dict = dict(time=dateutil.parser.parse, level=int) # Transform matching groups
  314. for groups in logger.parse("file.log", pattern, cast=caster_dict):
  315. print("Parsed:", groups)
  316. # {"level": 30, "message": "Log example", "time": datetime(2018, 12, 09, 11, 23, 55)}
  317. ```
  318. ### Exhaustive notifier
  319. Loguru can easily be combined with the great [`apprise`](https://github.com/caronc/apprise) library (must be installed separately) to receive an e-mail when your program fail unexpectedly or to send many other kind of notifications.
  320. ```python
  321. import apprise
  322. # Define the configuration constants.
  323. WEBHOOK_ID = "123456790"
  324. WEBHOOK_TOKEN = "abc123def456"
  325. # Prepare the object to send Discord notifications.
  326. notifier = apprise.Apprise()
  327. notifier.add(f"discord://{WEBHOOK_ID}/{WEBHOOK_TOKEN}")
  328. # Install a handler to be alerted on each error.
  329. # You can filter out logs from "apprise" itself to avoid recursive calls.
  330. logger.add(notifier.notify, level="ERROR", filter={"apprise": False})
  331. ```
  332. <s>
  333. ### 10x faster than built-in logging
  334. </s>
  335. Although logging impact on performances is in most cases negligible, a zero-cost logger would allow to use it anywhere without much concern. In an upcoming release, Loguru's critical functions will be implemented in C for maximum speed.
  336. <!-- end-of-readme-usage -->
  337. ## Documentation
  338. - [API Reference](https://loguru.readthedocs.io/en/stable/api/logger.html)
  339. - [Help & Guides](https://loguru.readthedocs.io/en/stable/resources.html)
  340. - [Type hints](https://loguru.readthedocs.io/en/stable/api/type_hints.html)
  341. - [Contributing](https://loguru.readthedocs.io/en/stable/project/contributing.html)
  342. - [License](https://loguru.readthedocs.io/en/stable/project/license.html)
  343. - [Changelog](https://loguru.readthedocs.io/en/stable/project/changelog.html)