#πŸ”’ Python3 logging to stdout

51 messages Β· Page 1 of 1 (latest)

crimson sluice
#

Using: Python3
Library: Logging (built-in)

How can I log the stdout/console using the normal functions .INFO(), .DEBUG() etc?

ocean agateBOT
#

@crimson sluice

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

crimson sluice
#

I have checked stackoverflow and there was one solution but this didn't work in my case and was from 12 years ago.

gilded mauve
ocean agateBOT
#

logging.info(msg, *args, **kwargs)```
Logs a message with level [`INFO`](https://docs.python.org/3/library/logging.html#logging.INFO) on the root logger. The arguments and behavior are otherwise the same as for [`debug()`](https://docs.python.org/3/library/logging.html#logging.debug).
proud quail
gilded mauve
#

Might need

#

!d logging.basicConfig

ocean agateBOT
#

logging.basicConfig(**kwargs)```
Does basic configuration for the logging system by creating a [`StreamHandler`](https://docs.python.org/3/library/logging.handlers.html#logging.StreamHandler) with a default [`Formatter`](https://docs.python.org/3/library/logging.html#logging.Formatter) and adding it to the root logger. The functions [`debug()`](https://docs.python.org/3/library/logging.html#logging.debug), [`info()`](https://docs.python.org/3/library/logging.html#logging.info), [`warning()`](https://docs.python.org/3/library/logging.html#logging.warning), [`error()`](https://docs.python.org/3/library/logging.html#logging.error) and [`critical()`](https://docs.python.org/3/library/logging.html#logging.critical) will call [`basicConfig()`](https://docs.python.org/3/library/logging.html#logging.basicConfig) automatically if no handlers are defined for the root logger.

This function does nothing if the root logger already has handlers configured, unless the keyword argument *force* is set to `True`.
crimson sluice
#

I have read it, but can I write logs to multiple files?

gilded mauve
#

Yes, this would require some complex setup

#

Well, something like that

#

I don't remember exactly

buoyant axle
#

Or you could just go sys.stderr = sys.stdout.

crimson sluice
#

Yeah maybe write it to /dev/stdin or smth

#

lemme try

gilded mauve
#

!d logging.handlers.RotatingFileHandler

ocean agateBOT
#

class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=False, errors=None)```
Returns a new instance of the [`RotatingFileHandler`](https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler) class. The specified file is opened and used as the stream for logging. If *mode* is not specified, `'a'` is used. If *encoding* is not `None`, it is used to open the file with that encoding. If *delay* is true, then file opening is deferred until the first call to [`emit()`](https://docs.python.org/3/library/logging.handlers.html#logging.handlers.RotatingFileHandler.emit). By default, the file grows indefinitely. If *errors* is provided, it determines how encoding errors are handled.
buoyant axle
#

... if you're talking about the default logger which writes to stderr if no other setup is done.

crimson sluice
#

The built in one

#

'logging'

#

Lemme post my basicConfig

gilded mauve
buoyant axle
#

Yes. But it can be told to do all sorted of logging, eg no ping's suggestions.

But by default it logs to stderr, and you could just point stderr at stdout.

crimson sluice
#
logging.basicConfig(
        filename='xxx.log', 
        level=logging.DEBUG
        format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S'
)
#

I would like it to write to the log file but also to the console

buoyant axle
#

Ok. That should log to xxx.log (instead of stderr IIRC).

#

Ah.

gilded mauve
#

E.g. A discord bot I have would post to console, write to a rotating file with different filename format to default, and simultaneously write to discord webhook for events

buoyant axle
#

You can add an additional handler to the deault logger. All the handlers get called for each logging call.

gilded mauve
#

It is mainly done by a json, with some python for custom handler implementation

crimson sluice
#

Let me try to handler one

gilded mauve
#

Basically, the idea is you can do anything, just 1: You need to know what you want
2: you might need to implement it

crimson sluice
#
logging.basicConfig(
        filename='xxx.log', 
        level=logging.DEBUG,
        format='%(asctime)s.%(msecs)03d %(levelname)s %(module)s - %(funcName)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S'
)
log = logging.getLogger(__name__).addHandler(logging.StreamHandler(sys.stdout))

When running log.info(""), it raises exception:

AttributeError: 'NoneType' object has no attribute 'info'
gilded mauve
#

!d logging.Logger.addHandler

ocean agateBOT
gilded mauve
#

It doesn't have chaining behaviour

crimson sluice
#

How do I fix that?

gilded mauve
#
log = logging.getLogger(__name__)
log.addHanfler(logging.StreamHandler(sys.stdout))
#

Just separate them

crimson sluice
#

oh okay, let me try that

#

GREAT!

#

It's working!

#

Thanks, it is printing to console now

gilded mauve
#

Next time, be specific about what you need help on

#

A generic question make it feel like you doesn't understand the concept

#

When you have a debugging problem

crimson sluice
#

Thanks, will do in the future!

#

!close

ocean agateBOT
#
Python help channel closed with !close

This help channel has been closed. Feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.