omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello β€” I'm @olemoritz on Twitter.


    [sharing] logging_setup

    Pythonista
    5
    11
    11367
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • cook
      cook last edited by

      Didn't know about the logger module until I was reading this discussion initiated by @phuket2. Thanks @ccc for mentioning about the logging module.

      I've made logging_setup.py just for ease of use. I'm just sharing it if anyone wants to.

      This has a few defaults:

      • prints to a file (.txt b/c Pythonista doesn't open .log by default)
      • Note: if used in different scripts, the 'name' arg is important for logging to different files.
      • mode is set to overwrite (you can set it with keyword arg)
      • format looks like this: "DEBUG: this is a message." (can change with fmt keyword)

      A few benefits:

      • can have the log file in a tab in the editor
      • can use the 'Find' in editor to search the log
      • no console take-over when running your script

      Quick setup:

      import logging
      import logging_setup
      log = logging_setup.logging_setup('my_log') #use a unique name
      log.debug('a message for the log')
      log.error('oh no.')
      log.warning('oh no.')
      log.critical('call 911... or omz')
      log.info('well now it seems you have some mighty fine logging going on.')
      logging.shutdown() #necessary at the end of the script running
      

      I did test this with using it in a few different files at the same time. I didn't think it was going to work because of name spaces (ex: if you use log in two files and have imported one file into the other) - but it seems to work fine. One very important thing: if you do not use logging.shutdown() it will not work properly (seems that logs are carried over from before).

      Code:

      logging_setup.py

      JonB 1 Reply Last reply Reply Quote 2
      • ccc
        ccc last edited by

        Comments on the gist https://gist.github.com/danrcook/369bf95d2a4d857f00fc84a0c1f261a8

        1 Reply Last reply Reply Quote 1
        • cook
          cook last edited by

          @ccc yeah I havent really ventured out into making a project that incorporates more than one file yet. But of course when I do (and from now on) I think this sort of thing will be very nice. It's much better than cluttering up the console!!

          1 Reply Last reply Reply Quote 0
          • Phuket2
            Phuket2 last edited by

            @cook, just made a new post to that story you referenced. I think it's worth pointing though. Maybe everyone knows about that param, seen it a million times, maybe just not used it or thought about it.
            In my example below, I actually open a file. And maybe there is another file like object that is just a null device. I just didn't find it yet 😁

            Hmmm, I just come across something. It's sort of there, but not 100%.
            In py3 print has a file param.
            So you can do the below. It's still ok for a quick and dirty.

            # opening here with 'a', could use 'w'
            log = open('my_print_code.txt', 'a')
            
            pfile = log
            # does not print to console, prints to the log file (Just text)
            for i in range(0, 100):
            	print( i, file = pfile)
            
            # this prints to the console
            pfile = None
            for i in range(0, 10):
            	print( i, file = pfile)
            
            print('finshed') # file param not used, goes to sys.stdout
            log.close()
            
            1 Reply Last reply Reply Quote 1
            • dgelessus
              dgelessus last edited by

              Of course under Python 3 you can also just say

              def print(*args, **kwargs):
                  pass
              

              to hide the built-in print function and

              del print
              

              to get it back. Under Python 2 this doesn't work, because print is a special keyword there.

              Phuket2 1 Reply Last reply Reply Quote 0
              • Phuket2
                Phuket2 @dgelessus last edited by

                @dgelessus , True 😁 But is not a toggle switch from what I understand. Maybe it is.
                But I can still see your code would let me simplify my idea. Override the print (as you are doing) statement and use a global to redirect the output inside the overwritten print function. Then no need to provide the file param each time to the real print statements.
                Thanks πŸ‘

                1 Reply Last reply Reply Quote 0
                • JonB
                  JonB last edited by JonB

                  @Phuket2
                  If you reread the github thread, i provided a switch option -- adding a console.enabled which you can use wherever.

                  That might be useful for running someone else's chatty code, where they used print, but for your own code, logging really is the way to go, where the "switch" is the logging level... Here is a console version of logging.

                  import logging,sys
                  
                  # create logger
                  logger = logging.getLogger('pythonista')
                  
                  # pythonista does not clear logging handlers.
                  # so, we might have one setup already
                  if not logger.hasHandlers():
                  	# create console handler with a higher log level
                  	ch = logging.StreamHandler(stream=sys.stdout)
                  	# create formatter and add it to the handlers
                  	formatter = logging.Formatter('%(message)s')
                  	ch.setFormatter(formatter)
                  	# add the handlers to the logger
                  	logger.addHandler(ch)
                  
                  logger.setLevel(logging.INFO)
                  logger.debug('debug')
                  logger.warning('warning')
                  logger.info('info')
                  
                  Phuket2 1 Reply Last reply Reply Quote 0
                  • Phuket2
                    Phuket2 @JonB last edited by

                    @JonB , yeah yeah yeah.....
                    But I seen the comment monkey patch, my brain switched off. I don't know what a monkey patch is. But is sounds not good.

                    But ok,,it seems like monkey patch refers to overriding a built in function or maybe data type etc... But it sounds notorious than that.

                    Honestly, for lay people these words are scary. Sounds like some super black magic , then you just skip it. Now, I actually read below the money patch statement I can see you did give a more detailed example of the same thing.

                    Maybe monkey patch has more far reaching concepts than what. I just sort of figured out. But have to look it up I guess.
                    Today afternoon, 1:51am here already.

                    1 Reply Last reply Reply Quote 0
                    • JonB
                      JonB @cook last edited by

                      @cook
                      By the way, you should add a check for hasHandler before adding a handler. Pythonista's global clearing code does not stop or clear out loggers, so the old logger will still have its handlers. (in the past I wanted to have a logger that logged to a BytesIO, so I could control when log entries were dumped to the screen, and this caused me lots of trouble)

                      This seems to prevent the need for shutdown()... i think

                      1 Reply Last reply Reply Quote 1
                      • ccc
                        ccc last edited by

                        https://en.m.wikipedia.org/wiki/Monkey_patch

                        Phuket2 1 Reply Last reply Reply Quote 0
                        • Phuket2
                          Phuket2 @ccc last edited by

                          @ccc , thanks. 0k, it's not as scary as it sounds. I know it may seem like a simple think not to know about, but there are a lot of things to know about. Whilst it's good to know about, probably better I don't screw with it, at least for now anyway as @JonB points out. I can get into trouble many other ways 😬😱

                          But I love the quote on the wiki page you linked to.

                          'If it walks like a duck and talks like a duck, it’s a duck, right? So if this duck is not giving you the noise that you want, you’ve got to just punch that duck until it returns what you expect. "

                          1 Reply Last reply Reply Quote 0
                          • First post
                            Last post
                          Powered by NodeBB Forums | Contributors