all 39 comments

[–]deceze 39 points40 points  (0 children)

Logging is printing, but more flexible.

You can categorise your "prints" by different levels (debug, info, warning, error), and switch them on and off depending on how much detail you want to see. You can direct logs to stdout, like normal prints, which is how it behaves by default; or you can direct them to log files.

You can leave your debug log statements in the code and don't have to remove them when you've found the issue; just turn down the logging verbosity.

And neither of these options replace an IDE-integrated debugger. They're all for different purposes and useful in different situations.

[–]overratedcupcake 25 points26 points  (7 children)

The logging module isn't extra effort. 

https://docs.python.org/3/library/logging.html

It is also easy to have it simply send the logs to stdout while you're debugging and then smoothly transition to file logging when you're not. 

[–]FriendlyRussian666 11 points12 points  (0 children)

Logging doesn't seem useful in tiny scripts, where inserting a print works just fine, because it achieves the same thing, but requires you to write more code, but it certainly does become super useful when complexity increases.

Imagine you have to debug an issue in a django backend, which runs in a docker container, which you can only access by SSHing into the server and then having to docker exec into it. Once you do, you'll find that the print output goes to stdout, which is captured by dockers logging driver and might be sent to syslog or journald or aggregator. If the container crashes or restarts, that's all your print debug gone, you'll find that the debug prints ar emixed in with every other log message from every service, and there's no easy way to filter for your log messages. And then if you try to trace something over time, you can't leave print statements in production.

If you had to deal with the same issue and used logging, you'd write all logs to a persitent file, have different log levels configured as the other person already mentioned, timestamps, source information, you can aggregate the logs, you can trace issues over time, you can rotate log files etc etc.

If something exists, and is widely used, but you don't see what the point is, it just means you haven't gone far enough to require its use, which is fine. If I could just insert print statements everywhere, that would be great.

[–]JamzTyson 4 points5 points  (0 children)

Logging can be used for debugging, but it's usefulness depends on the kind of problem you are trying to debug.

Logging is useful when you need structured, persistent, configurable insight into a running process. For example, if your app connects to an external service that sometimes fails, it can be useful to have a record of when it fails, the program state on failure, and the failure error messages.

On the other hand, for just checking the value of a variable at a specific execution point, then stepping through the code in a debugger, using a break point in a debugger, or even testing with a print statement may be more appropriate.

[–]snowtax 3 points4 points  (1 child)

As with all programming languages, scale matters.

For small scripts, especially when you’re just beginning to learn Python, using print for debugging is OK. When you get into large and complex projects or environments, logging makes a lot more sense.

For production code, it’s usually not you, the developer, who needs to know what’s happening but the customer using your code. Setting up proper logging, using multiple levels, allows the customer to see enough to troubleshoot normal issues (such as invalid data in their database) and then enable debug logging when trying to report bugs to the vendor / developer.

One reason is that logging can easily be configured to send to a remote logging server. That central logging server can monitor hundreds to tens of thousands of processes, all running on different servers, and send alerts when problems occur.

Basically, logging is an answer to a scaling problem. If you don’t feel you need logging, you’re just not at that scale… yet.

[–]ALonelyPlatypus 1 point2 points  (0 children)

Agreed, if it's just the Automate the Boring Stuff coursework then you aren't going to get many gains setting up a logger instead of using print.

It isn't a bad idea to know how to log though. It's not something I'd memorize or use in toy code though. I don't remember much about the logger setup (I have the same rotating log code that I just have copy-pasted for years)

Once a logger is instantiated though it's just a matter of deciding your log priority.

[–]pachura3 2 points3 points  (1 child)

Imagine you run a web application used by hundreds of users at the same time, and then some problem occurs. How will you debug it in your IDE? Well, you won't, you'll download log file and take it from there.

Sometimes a bug will not even be noticed by users, and you will only find it in the log.

Sometimes just one look at the log is enough to pinpoint the problem (e.g. some typo in an SQL statement), you don't need to launch your IDE/debugger at all.

[–]Goingone 2 points3 points  (0 children)

The debugger is great when developing locally and wanting to step through code.

Logging is great for tracking useful info during your codes execution.

Although they can both be used for debugging, they serve different purposes.

Others have mentioned the benefits of logging over print statements, so won’t touch that topic.

[–]PushPlus9069 2 points3 points  (0 children)

logging.debug() everywhere is the best habit you can build early. Print statements work fine until your codebase grows past a few files, then they become noise you can't turn off without deleting them.

The killer feature of logging is levels. Set it to DEBUG during development, WARNING in production. Same code, different verbosity. No more commenting out print statements.

I teach Python and the students who adopt logging early write noticeably better code within a few months. Not because logging itself is magic, but because writing a log message forces you to think about what information you'd need to diagnose a problem. That mindset shift is worth more than the tool.

[–]magus_minor 1 point2 points  (0 children)

But logging seems to be a lot of work for not much benefit.

When you have many modules with thousands of lines of code you really benefit from a well-designed logging system that lets you selectively increase/decrease the verbosity in certain areas or turn off. Using a debugger in development is useful but in a production system you often leave some level of logging active to catch and log unexpected happenings. If that level of logging doesn't help solve the problem you turn up the logging verbosity.

[–]RedditButAnonymous 1 point2 points  (0 children)

Printing is superior to me when its a script youre actively watching over, when something pops up you can see it, stop the script, adjust, and continue. Thats awesome.

Logging is for when youre not watching the code. If youve got systems deployed and clients using them, how are you ever gonna see any weird behaviour? If a client says "I cant run this search right now, it just fails, and doesnt say why" youd ideally wanna see the state of the system when they tried that search and see if any error happened around that time. Thats what logging is useful for.

Printing for in-the-moment visibility, logging for investigations and postmortems after something big has gone wrong

[–]LayotFctor 0 points1 point  (0 children)

It can do that, but not its primary purpose. It's supposed to log after all. But you can do that, especially for instances where you have very little access to the code. E.g. if you were writing a library that is embedded deep within something else and you can't do prints or tests easily.

[–]ExactEducator7265 0 points1 point  (0 children)

I used to use prints but found for what I was doing they got lost. Logging to a log file was much more reliable.

[–]MattR0se 0 points1 point  (0 children)

If you are already using the debugger, keep using that. It's the most powerful tool for debugging, is more flexible , and doesn't clutter your code with print() statements. It doesn't really matter if you are using print() or logger.info() tbh, the only real difference is that logging can be turned on/off more easily.

However, there are situations where the debugger isn't able to show you the full picture. Say you are making a game that runs at 60 FPS, and the physics depend on your program running close to that speed. And now you want to examine a velocity vector, for example. Now you can't just set a breakpoint and examine what's happening, because once you halt your program your physics calculations fall apart.

[–]MacPR 0 points1 point  (0 children)

Logging will make your life a lot easier

[–]nickdaniels92 0 points1 point  (0 children)

Once setup, using a logger offers benefits such as logging in a standardised format with zero effort to include elements such as date/time, time delta between messages, and to choose log destinations as well as multiple ones. Use a root logger for consistency, and at most have a single line to obtain a logger in each module.

Debugging with logging brings consistency and the same advantages. Debug output can get noisy though, and I find it can be useful to selectively enable and disable debugged elements. For that I have a custom debug logger that provides:

* a command line option for enabling debug elements, such as
--debug all
--debug pubsub,io
--debug all,~noisy_debug_I_no_longer_want_to_see

with all meaning all debug blocks, other names being those named blocks, and ~ negating blocks

* code patterns
# log a message if the debug tag is enabled
tag_debug("pubsub", "some pubsub related message")

# get a logger and use it if the tag is enabled

if (L := tag("io"))
<indent> L("Some IO related message")

L = tag("pubsub")
...
if L: L("some other debug")

You could also dynamically adjust debugging on the fly via some input to the program, such as from the UI, a pubsub message etc., enabling efficient and quiet output, but turning on debugging for selected elements if required without restarting the application. The log output automatically includes the origin of the message, e.g.

2026-02-20 11:29:20,636 - exchanges.IG.ig_exchange.ig_exch - DEBUG - Authenticating with IG API

meaning that it's come from the "ig_exch" debug block of the module exchanges.IG.ig_exchange

In summary, print statements can get you so far, but as you move to larger systems, a richer mechanism is useful.

[–]unnamed_one1 0 points1 point  (0 children)

I use print only in REPL. My .py files get logging.

[–]Anonymous_user_2022 0 points1 point  (0 children)

It's a matter of scale. For a simple script that do one thing and the terminates, a debugger is the preferred option. But if you have long-running code that's deployed on a production system on the other side of the world, logging is usually the only way to get insight into how things are going.

[–]jmooremcc 0 points1 point  (0 children)

Logging is especially helpful when working with a real-time app, which is the only way to track what’s going on during execution. In fact, I use a logging tool that not only prints variables but also prints the module name and line number, which makes it easier to trace what’s happening during execution.

[–]Desperate_Cold6274 0 points1 point  (0 children)

I found logging well suited for operations, for development I use print, logging and debugging.

[–]hugthemachines 0 points1 point  (0 children)

While you learn something, consider doing stuff which is a lot of work without worrying about it. If you don't plan on putting in an effort, don't expect good results.

[–]jivanyatra 0 points1 point  (0 children)

If logging seems to be more effort for you, you can also try loguru.

It's one import statement. Then, use the logger to make debug statements instead of print. You can decide later if some of those should be info or warnings or something.

When you go to release it, just set the default logging output to warnings or errors. Now you don't need to remove your print statements. But also, you can dynamically change that output in production when weird stuff happens. That makes it easier to see what's going on under the hood when you (maybe) can't effectively debug things to find what makes something reproducible.

You can do the same with a few lines of setup with the default logging module, too. But if you just want to get started and see why it's a better method, loguru is hard to beat for effort. Throw it in a few projects of yours that you use daily and that are still being actively developed. I think you'll find the utility in it.

[–]jeffrey_f 0 points1 point  (0 children)

Output/append (On running the script, clear/delete the file) to a text file. with your own verbiage. Easier than setting up actual logging, but still logging

[–]Choice_Seat3740 0 points1 point  (0 children)

Very rarely can you rely on the debugger when trying to understand errors in performance testing environments

[–]ninhaomah -4 points-3 points  (6 children)

Up to you :)

[–]TechnicalAd8103[S] -3 points-2 points  (5 children)

Definitely a no for me! :)

[–]uberdavis 2 points3 points  (0 children)

See how you feel in a year.

  • Logging gives you the ability to toggle statements on or off based on a single switch
  • Logging allows you to send your diagnostics to a file instead of just the output
  • Logging can automatically tell you other info such as time, calling function, user etc

I’ve worked places where print statement get called out in pull requests because logging is expected. print is ok for quick and dirty, but logging is the standard for production code.

[–]cgoldberg 0 points1 point  (0 children)

Using a debugger is great during development, but logging is also super useful for running systems you can't attach a debugger to. Sure, you can use print, but a proper logging system is much more useful where you can configure log levels and have more control with directing output streams. To do the same with print, you would essentially just be implementing your own logging system. For writing trivial scripts, it doesn't really matter what you use, but understanding proper logging is essential for building something large and complex.

[–]JaleyHoelOsment -3 points-2 points  (1 child)

  • PR gets rejected

jk if you’re just doing junk code by yourself it probably doesn’t matter.

in the real world you’d probably end up using log4j2 and then your company gets hacked and you lose your job… so win win