How to manage logging in curses

前端 未结 3 1122
栀梦
栀梦 2021-01-02 00:07

I created a simple UI for my application using curses and I also include logs (logging) in my modules using herarchy structure (logmain, logmain.child1) and so on.

I

相关标签:
3条回答
  • 2021-01-02 00:19

    You can create your own Handler class to emit log messages to a curses pad or window:

    try:
        unicode
        _unicode = True
    except NameError:
        _unicode = False
    
    class CursesHandler(logging.Handler):
        def __init__(self, screen):
            logging.Handler.__init__(self)
            self.screen = screen
        def emit(self, record):
            try:
                msg = self.format(record)
                screen = self.screen
                fs = "\n%s"
                if not _unicode: #if no unicode support...
                    screen.addstr(fs % msg)
                    screen.refresh()
                else:
                    try:
                        if (isinstance(msg, unicode) ):
                            ufs = u'\n%s'
                            try:
                                screen.addstr(ufs % msg)
                                screen.refresh()
                            except UnicodeEncodeError:
                                screen.addstr((ufs % msg).encode(code))
                                screen.refresh()
                        else:
                            screen.addstr(fs % msg)
                            screen.refresh()
                    except UnicodeError:
                        screen.addstr(fs % msg.encode("UTF-8"))
                        screen.refresh()
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                self.handleError(record)
    

    (This was basically copied from logging.StreamHandler.) The window or pad needs to be initialized to allow automatic scrolling etc.:

    screen.nodelay(1)
    maxy, maxx = screen.getmaxyx()
    begin_x = 2; begin_y = maxy-5
    height = 5; width = maxx-4
    win = curses.newwin(height, width, begin_y, begin_x)
    curses.setsyx(-1, -1)
    screen.addstr("Testing my curses app")
    screen.refresh()
    win.refresh()
    win.scrollok(True)
    win.idlok(True)
    win.leaveok(True)
    mh = CursesHandler(win)
    mh.setFormatter(formatterDisplay)
    logger.addHandler(mh)
    

    Here, screen is the main curses screen.

    0 讨论(0)
  • 2021-01-02 00:24

    This code should work out of the box, The above didn't work for me.

    import logging
    import curses
    import time
    from curses import wrapper
    
    class CursesHandler(logging.Handler):
        def __init__(self, screen):
            logging.Handler.__init__(self)
            self.screen = screen
        def emit(self, record):
            try:
                msg = self.format(record)
                screen = self.screen
                fs = "\n%s"
                screen.addstr(fs % msg)
                screen.box()
                screen.refresh()
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                raise
    
    def MainWindow(screen):
        _unicode = True
        win = screen.subwin(0,0)
        win.box()
        win.addstr(2,2,"Testing my curses app")
        win1 = win.subwin(0,0)
    
        win1.getch()
        win1.refresh()
        MAX_ROW, MAX_COL = win1.getmaxyx()
        win1.scrollok(True)
        win1.idlok(True)
        win1.leaveok(True)
        win1.setscrreg(4, MAX_ROW - 3)
        win1.addstr(4, 4, "")
    
    
        mh = CursesHandler(win1)
        formatter = logging.Formatter(' %(asctime) -25s - %(name) -15s - %(levelname) -10s - %(message)s')
        formatterDisplay = logging.Formatter('  %(asctime)-8s|%(name)-12s|%(levelname)-6s|%(message)-s', '%H:%M:%S')
        mh.setFormatter(formatterDisplay)
        logger = logging.getLogger('Test Logger')
        logger.addHandler(mh)
    
        i = 1
        while True:
            logger.error('message ' + str(i))
            time.sleep(.128)
            i+=1;
    
    
    
    if __name__=="__main__":
        wrapper(MainWindow)
    
    0 讨论(0)
  • 2021-01-02 00:27

    Thanks to @zeeMonkeez I solved the problem. Below the complete code example:

    import logging
    import curses
    import time
    
    class CursesHandler(logging.Handler):
        def __init__(self, screen):
            logging.Handler.__init__(self)
            self.screen = screen
        def emit(self, record):
            try:
                msg = self.format(record)
                screen = self.screen
                fs = "\n%s"
                if not _unicode: #if no unicode support...
                    screen.addstr(fs % msg)
                    screen.refresh()
                else:
                    try:
                        if (isinstance(msg, unicode) ):
                            ufs = u'\n%s'
                            try:
                                screen.addstr(ufs % msg)
                                screen.refresh()
                            except UnicodeEncodeError:
                                screen.addstr((ufs % msg).encode(code))
                                screen.refresh()
                        else:
                            screen.addstr(fs % msg)
                            screen.refresh()
                    except UnicodeError:
                        screen.addstr(fs % msg.encode("UTF-8"))
                        screen.refresh()
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                self.handleError(record)
    
    
    try:
        _unicode = True
        screen = curses.initscr()
        screen.nodelay(1)
        maxy, maxx = screen.getmaxyx()
        begin_x = 2; begin_y = maxy-5
        height = 5; width = maxx-4
        win = curses.newwin(height, width, begin_y, begin_x)
        curses.setsyx(-1, -1)
        screen.addstr("Testing my curses app")
        screen.refresh()
        win.refresh()
        win.scrollok(True)
        win.idlok(True)
        win.leaveok(True)
        mh = CursesHandler(win)
        formatter = logging.Formatter('%(asctime) -25s - %(name) -15s - %(levelname) -10s - %(message)s')
        formatterDisplay = logging.Formatter('%(asctime)-8s|%(name)-12s|%(levelname)-6s|%(message)-s', '%H:%M:%S')
        mh.setFormatter(formatterDisplay)
        logger = logging.getLogger('myLog')
        logger.addHandler(mh)
    
    
        for i in range(10):
            logger.error('message ' + str(i))
            time.sleep(1)
    
    
        curses.curs_set(1)
        curses.nocbreak()
        curses.echo()
        curses.endwin()
    
    except NameError:
        _unicode = False
    
    0 讨论(0)
提交回复
热议问题