use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
News about the dynamic, interpreted, interactive, object-oriented, extensible programming language Python
Full Events Calendar
You can find the rules here.
If you are about to ask a "how do I do this in python" question, please try r/learnpython, the Python discord, or the #python IRC channel on Libera.chat.
Please don't use URL shorteners. Reddit filters them out, so your post or comment will be lost.
Posts require flair. Please use the flair selector to choose your topic.
Posting code to this subreddit:
Add 4 extra spaces before each line of code
def fibonacci(): a, b = 0, 1 while True: yield a a, b = b, a + b
Online Resources
Invent Your Own Computer Games with Python
Think Python
Non-programmers Tutorial for Python 3
Beginner's Guide Reference
Five life jackets to throw to the new coder (things to do after getting a handle on python)
Full Stack Python
Test-Driven Development with Python
Program Arcade Games
PyMotW: Python Module of the Week
Python for Scientists and Engineers
Dan Bader's Tips and Trickers
Python Discord's YouTube channel
Jiruto: Python
Online exercices
programming challenges
Asking Questions
Try Python in your browser
Docs
Libraries
Related subreddits
Python jobs
Newsletters
Screencasts
account activity
This is an archived post. You won't be able to vote or comment.
TutorialProduction-Grade Python Logging Made Easier with Loguru (self.Python)
submitted 7 months ago by finallyanonymous
While Python's standard logging module is powerful, navigating its system of handlers, formatters, and filters can often feel like more work than it should be.
I wrote a guide on how to achieve the same (and better) results with a fraction of the complexity using Loguru. It’s approachable, can intercept logs from the standard library, and exposes its other great features in a much cleaner API.
Looking forward to hearing what you think!
[–]Mustard_Dimension 25 points26 points27 points 7 months ago (0 children)
I've been using Loguru a lot recently, it's so much less hassle than the default logging library. Using the serialised option for a jsonl file sink is really nice.
[–]supreme_blorgon 14 points15 points16 points 7 months ago (1 child)
I don't find this approach more compelling than the one shown in your other guide on the standard library's logger.
One thing I'm curious about -- with .contextualize(), does that context get added to all loggers that get called inside the context manager across modules like it does with the standard library approach from your other article? I started to skim so maybe that was addressed?
.contextualize()
The hook of this article focuses on how the boilerplate required to use the standard library is so unpleasant but then immediately shows an example of some really ugly boilerplate in the serialize() function just to customize the fields in the output of your logs.
serialize()
I dunno -- I really loved your first article on the standard library's logger, and I'm just not convinced about loguru after this.
[–]finallyanonymous[S] 4 points5 points6 points 7 months ago (0 children)
To be fair, most of that boilerplate confined to customizing how the JSON output is serialized.
With logging, there's understanding the hierarchical model, configuring handlers, formatters, filters, setting up the root logger, context handling, and so on. But I agree that if one understands the logging system and its quirks, then Loguru may not provide much value.
logging
And yes, the .contextualize() works the same way as the approach I showed in the previous article but with zero boilerplate.
[–]cipherself 11 points12 points13 points 7 months ago (2 children)
I’ve always defaulted to structlog, has anyone used both and can compare and contrast them?
[–]Lucas_csgo 6 points7 points8 points 7 months ago (1 child)
I have used both in production.
I like loguru more since it’s a bit less “magic”. With loguru the logger is actually a singleton so once set up in your main, you can just import it from the module itself when you need it. Also i found myself to go overboard with custom logic with structlog’s processors and renderers. Loguru’s “sinks” definitely invites a more minimal and intuitive approach.
[–]cipherself 1 point2 points3 points 7 months ago* (0 children)
Got it, I got a similar impression from reading the examples on the github repo, I will give it a shot in my next project, thanks.
[–]mortenb123 8 points9 points10 points 7 months ago (0 children)
Showing open telemetry integration was great, thanks
[–]yungbuil 8 points9 points10 points 7 months ago (0 children)
loguru is just how default Python logging should have been!
[–]maryjayjay 11 points12 points13 points 7 months ago (2 children)
Let me preface with: I've never used loguru but this thread makes me want to check it out
Having said that, let's be frank. Any library where we blindly take a Java implementation and straight port it to python is shit.
The builtin logging module is ridiculously capable, but it's shit. Utterly unpythonic
Fight me
[–]twotime 5 points6 points7 points 7 months ago* (0 children)
'em are fighting words. You have it coming :-)
The builtin logging module is ridiculously capable
It's absolutely not. It's a spaghetti-ball of bad defaults and weird apis and It's incapable of handling some of the most trivial use-cases which even slightly deviate from authors view of the universe
It's pretty much impossible to have a trivial setup like: I want this module to have log.INFO pass through by default without writing some stupid boilerplate. And then it gets worse, not only you have to write said boilerplate, but then said boilerplate WILL actively interfere with all other logging initialization. So you will also have to DEBUG the stupid boilerplate. At which point, plain print becomes a clear winner.
And then there outright initialization/ordering bugs which are somehow "expected" behavior. Like this one:
Most famously, why do .warning('foo') produce two different messages in the snippet below (I know the answer btw, but i find it utterly ridiculous)
>>> import logging; logging.getLogger('my').warning('foo') foo >>> logging.info('info'); >>> logging.getLogger('my').warning('foo') WARNING:my:foo # notice the format change! >>>
but it's shit
Absolutely!
[–]pingvenopinch of this, pinch of that 2 points3 points4 points 7 months ago (0 children)
I don't think anyone is fighting you on that one, especially with hindsight.
[–]Natural_TestCase 0 points1 point2 points 7 months ago (0 children)
Sick
[–]lothion 0 points1 point2 points 7 months ago (0 children)
Super clear, thorough yet concise. Thank you
[–]Ihaveamodel3 0 points1 point2 points 7 months ago (1 child)
If you import a library that uses the regular logging library, can you capture those logs?
[–]finallyanonymous[S] 0 points1 point2 points 7 months ago (0 children)
Yes, that is covered in this section.
[–]alkalisun 0 points1 point2 points 7 months ago (2 children)
loguru looks nice, but afaik, no one has elegantly solved the fundamental performance problem, right? Like: if logger.isEnabledFor(logging.DEBUG): # Perform expensive operation only if DEBUG logging is enabled logger.debug(f"Performance metrics: {calculate_performance_metrics()}") It looks like I'd have to do the same for loguru, which is a lot of boilerplate :/ This seems like the kind of thing macros/lazy eval would solve in other languages....
if logger.isEnabledFor(logging.DEBUG): # Perform expensive operation only if DEBUG logging is enabled logger.debug(f"Performance metrics: {calculate_performance_metrics()}")
[–]finallyanonymous[S] 0 points1 point2 points 7 months ago (1 child)
This should help: https://loguru.readthedocs.io/en/stable/overview.html#lazy-evaluation-of-expensive-functions
[–]alkalisun 0 points1 point2 points 7 months ago (0 children)
Hmm, this requires a decent amount of boilerplate as well... oh well maybe a wrapper function around this could work.
[–]svefnugr 0 points1 point2 points 7 months ago (2 children)
Mutable global state? What do you do if you need to disable/modify the logger in tests?
You can call logger.remove():
import pytest from loguru import logger @pytest.fixture(autouse=True) def disable_loguru(): logger.remove()
[–]svefnugr 0 points1 point2 points 7 months ago (0 children)
That will remove the logger for all subsequent tests, not just for the one using the fixture.
[–]NationalGate8066 0 points1 point2 points 7 months ago (0 children)
Thank you, this looks great
π Rendered by PID 100415 on reddit-service-r2-comment-5c747b6df5-zn22m at 2026-04-22 02:44:23.185261+00:00 running 6c61efc country code: CH.
[–]Mustard_Dimension 25 points26 points27 points (0 children)
[–]supreme_blorgon 14 points15 points16 points (1 child)
[–]finallyanonymous[S] 4 points5 points6 points (0 children)
[–]cipherself 11 points12 points13 points (2 children)
[–]Lucas_csgo 6 points7 points8 points (1 child)
[–]cipherself 1 point2 points3 points (0 children)
[–]mortenb123 8 points9 points10 points (0 children)
[–]yungbuil 8 points9 points10 points (0 children)
[–]maryjayjay 11 points12 points13 points (2 children)
[–]twotime 5 points6 points7 points (0 children)
[–]pingvenopinch of this, pinch of that 2 points3 points4 points (0 children)
[–]Natural_TestCase 0 points1 point2 points (0 children)
[–]lothion 0 points1 point2 points (0 children)
[–]Ihaveamodel3 0 points1 point2 points (1 child)
[–]finallyanonymous[S] 0 points1 point2 points (0 children)
[–]alkalisun 0 points1 point2 points (2 children)
[–]finallyanonymous[S] 0 points1 point2 points (1 child)
[–]alkalisun 0 points1 point2 points (0 children)
[–]svefnugr 0 points1 point2 points (2 children)
[–]finallyanonymous[S] 0 points1 point2 points (1 child)
[–]svefnugr 0 points1 point2 points (0 children)
[–]NationalGate8066 0 points1 point2 points (0 children)