0

I know there are plenty of question about redirecting stderr in python, but i can't seem to make them work in my application.

Just for you to understand the background, I have a logger called myLogger from the logging module which output to both a file and a stream ( which output to a QTextEdit widget ) thanks to logging.FileHandler and logging.StreamHandler. Since I am at the debug stage of development, I also want to write to the same file the traceback of errors that may occur during deployment/test phase.

Here is my code, which output nothing except a Segmentation fault : 11.

class streamToLogger( ):

    def __init__( self, name = None ):
        self._logger = logging.getLogger( name )

    def write( self, text, level = logging.CRITICAL ):
        if text != "\n":
            self._logger.log( level, text )

    def flush( self ):
        for handler in self._logger.handlers:
            handler.flush( )

class Example( QWidget ):

    def __init__( self ):
        super( ).__init__( )
        #UIStream = streamToUI()
        l = myLogger( config, None )
        sys.stderr = streamToLogger( "myLogger" ) 
        self._initUI( )

    def _initUI( self ):
        self.btn = QPushButton( 'Button', self )
        self.btn.resize( self.btn.sizeHint( ) )
        self.btn.move( 50, 50 )       
        self.btn.clicked.connect( self._raiseError )

        self.setGeometry( 300, 300, 300, 200 )
        self.setWindowTitle( 'Test Raise error log' )    
        self.show()

    @pyqtSlot()    
    def _raiseError( self ):
        a = 1 / 0

if __name__ == '__main__':
    app = QApplication( sys.argv )
    ex = Example( )
    sys.exit( app.exec_( ) )

Edit

Here is the code of myLogger class :

class myLogger():

    def __init__( self, configObject, stream = None ):
            self.logger = logging.getLogger( "myLogger" )
            self.logger.setLevel( logging.DEBUG )
            self._format = "%(asctime)s - %(levelname)s - %(threadName)s, %(funcName)s - %(message)s" 
            self._level = 10
            self.streamHandler = self._setStreamHandler( stream  ) 
            self.logger.addHandler( self.streamHandler )
            self.fileHandler = self._setFileHandler()
            self.logger.addHandler( self.fileHandler )

        def _setFileHandler( self ):
            fileName = "testLog.log"
            tempHandler = logging.FileHandler( fileName, mode = "a+" )
            myFormatter = logging.Formatter( self._format ) 
            tempHandler.setFormatter( myFormatter )
            tempHandler.setLevel( self._level )
            return tempHandler

        def _setStreamHandler( self, stream ):
            tempHandler = logging.StreamHandler( stream )
            myFormatter = logging.Formatter( self._format ) 
            tempHandler.setFormatter( myFormatter )
            level = 10
            tempHandler.setLevel( self._level )
            return tempHandler
Nessy W.
  • 151
  • 2
  • 10
  • Are you using threads anywhere? – three_pineapples Jan 14 '16 at 22:02
  • @three_pineapples Not in this simple test code (but in the targeted code I will). Or at least not explicitly ( i am not using any of the thread module or any QThread stuff here, but maybe the logging module is ?) – Nessy W. Jan 18 '16 at 10:30
  • Ok. Well firstly, this will be very difficult to answer without a [MCVE] so that the problem can be reproduced. I don't know how easy it will be to cut down your code to something self contained though. The reason I bring up threads is because you cannot directly access a GUI widget from another thread, as it will cause segfaults. If you were using your logging from another thread, I suspect it would be thread unsafe. See [this](http://stackoverflow.com/q/21071448/1994235) SO question and answer for details and a solution. – three_pineapples Jan 18 '16 at 20:39
  • Sorry for late comment. I've update the question with the logger class code. @three_pineapples I do not directly update my GUI, I use pyqt signal and slot mechanism to do so with a stream class (the write function emit the signal). I did see this SO question but I could not manage to make it work in my case. Anyway, this applies to the general code. I'd like to make this example work first ! – Nessy W. Jan 26 '16 at 13:08

0 Answers0