python - Suspend the formatting of the logger, then go back to it -
i have logging configuration log file , console:
logging.basicconfig(filename=logfile, filemode='w', level=numlevel, format='%(asctime)s - %(levelname)s - %(name)s:%(funcname)s - %(message)s') # add console messages console = logging.streamhandler() console.setlevel(logging.info) consoleformatter = logging.formatter('%(asctime)s - %(levelname)s - %(message)s') console.setformatter(consoleformatter) logging.getlogger('').addhandler(console)
at point in script, need interact user printing summary , asking confirmation. summary produced prints in loop. suspend current format of console logs, can printout 1 big block of text question @ end , wait user input. still want of logged file!
the function in module, tried following :
logger = logging.getlogger(__name__) def summaryfunc: logger.info('normal logging business') clearformatter = logging.formatter('%(message)s') logger.setformatter(clearformatter) logger.info('\n##########################################') logger.info('summary starts here')
which yields error: attributeerror: 'logger' object has no attribute 'setformatter'
i understand logger logger, not handler, i'm not sure on how things work...
edit:
following answers, problem turned : how can suspend logging console when interacting user, while still being able log file. ie: suspend streamhandler. since happening in module, specifics of handlers defined elsewhere, here how did :
logger.debug('normal logging file , console') root_logger = logging.getlogger() stream_handler = root_logger.handlers[1] root_logger.removehandler(stream_handler) print('user interaction') logger.info('logging file only') root_logger.addhandler(stream_handler) logger.info('back logging both file , console')
this relies on streamhandler being second in list returned handlers
believe case because it's in order added handlers root logger...
i agree vinay should use print
normal program output , use logging
logging purpose. however, if still want switch formatting in middle, switch back, here how it:
import logging def summarize(): console_handler.setformatter(logging.formatter('%(message)s')) logger.info('here report') console_handler.setformatter(console_formatter) numlevel = logging.debug logfile = 's2.log' logger = logging.getlogger(__name__) logger.setlevel(logging.debug) console_handler = logging.streamhandler() console_formatter = logging.formatter('%(asctime)s - %(levelname)s - %(message)s') console_handler.setformatter(console_formatter) logger.addhandler(console_handler) file_handler = logging.filehandler(filename=logfile, mode='w') file_formatter = logging.formatter('%(asctime)s - %(levelname)s - %(name)s:%(funcname)s - %(message)s') file_handler.setformatter(file_formatter) logger.addhandler(file_handler) logger.info('before summary') summarize() logger.info('after summary')
discussion
- the script creates logger object , assigned 2 handlers: 1 console , 1 file.
- in function
summarize()
, switched in new formatter console handler, logging, switched back. - again, let me remind should not use
logging
display normal program output.
update
if want suppress console logging, turn on. here suggestion:
def interact(): # remove console handler handler in logger.handlers: if not isinstance(handler, logging.filehandler): saved_handler = handler logger.removehandler(handler) break # interact logger.info('to file only') # add console handler logger.addhandler(saved_handler)
note did not test handlers against logging.streamhandler
since logging.filehandler
derived logging.streamhandler
. therefore, removed handlers not filehandler
. before removing, saved handler later restoration.
update 2: .handlers = []
in main script, if have:
logger = logging.getlogger(__name__) # __name__ == '__main__'
then in module, do:
logger = logging.getlogger(__name__) # __name__ == module's name, not '__main__'
the problem is, in script, __name__ == '__main__'
, in module, __name__ == <the module's name>
, not '__main__'
. in order achieve consistency, need make name , use them in both places:
logger = logging.getlogger('myscript')
Comments
Post a Comment