Package: bbutils
bbutilsCollection of code I use frequently in many of my projects. Especially the logging feature.FeaturesLogging to console (colored) and file, in can be extended via additional writer via a plugin feature. The logging is done directly, but also can be done via a thread and a simple buffer.InstallationYou can install unqlite usingpip.pip install bbutilsBasic logging usageBelow is a sample designed to show some of the basic features and functionality of the logging library.Step 1: SetupTo begin, instantiate anLoggingobject.  Then do the setup vialog.setup(**kwargs).log = Logging()log.setup(app="example", level=3)Possible values for setup():app: Application nameuse_thread: use threaded outputinterval: update interval for threaded mode in secondslevel: verbose level (integer)index: dictionay with a lookup table for the different commands for each verbose levelVerbose level and the commandsindex = {0: ["INFORM", "WARN", "ERROR", "EXCEPTION", "TIMER", "PROGRESS"],1: ["INFORM", "DEBUG1", "WARN", "ERROR", "EXCEPTION", "TIMER", "PROGRESS"],2: ["INFORM", "DEBUG1", "DEBUG1", "WARN", "ERROR", "EXCEPTION", "TIMER", "PROGRESS"],3: ["INFORM", "DEBUG1", "DEBUG2", "DEBUG3", "WARN", "ERROR", "EXCEPTION", "TIMER", "PROGRESS"]}Step 2: Output writerconsolefile# We want console and file loggingconsole = log.get_writer("console")fileio = log.get_writer("file")# file name to log tofilename = os.path.abspath(os.path.normpath("{0:s}/run-tests.log".format(os.getcwd())))# setup file and console output, set filename and filler for space for readable output.console.setup(text_space=15)fileio.setup(text_space=15, filename=filename)Possible values for console.setup():text_space: number of space fillers for application name and tagseperator: seperator for tags and content, currently '|' as defaulterror_index: list of commands (seeVerbose level and the commands) redirected tostderrbar_len: length of progress barPossible values for file.setup():There are two modes for the file output. First is setting the filename directly. The second is setting filename, logname and logpath. The second enables to append a date and time value to the output filename.text_space: number of space fillers for application name and tagappend_data: continue old logfile (only for filename)filename: filename for logfile (excludeslogname,logpathandappend_datetime)logname: general name for logfile (example logname=example will result in a filename of /exaple_2020-01-01_00.00.00.log)logpath: path to store the logfile, works only withlognameappend_datetime: add datetime tolognameandlogpathStep 3: Register writerIts possible to create self written writer and use these. Look in bbutil.logging.types for theWriterclass and theMessageclass.# register the outputlog.register(console)log.register(fileio)Step 4: Use the classinform(tag: str, content: str)warn(tag: str, content: str)debug1(tag: str, content: str)debug2(tag: str, content: str)debug3(tag: str, content: str)error(content: str)exception(e: Exception)traceback()progress(limit: int, interval: int = 0)timer(content: str)Example for 'inform'log.inform("EXAMPLE", "example 1, this will be shown with every log level")

example         EXAMPLE        | example 1, this will be shown with every log levelexample.pySee filehereimport osimport timefrom bbutil.logging import Loggingif __name__ == '__main__':log = Logging()# Setup the logging, appicatio name is 'example', log level is 2log.setup(app="example", level=3)# We want console and file loggingconsole = log.get_writer("console")fileio = log.get_writer("file")# file name to log tofilename = os.path.abspath(os.path.normpath("{0:s}/run-tests.log".format(os.getcwd())))# setup file and console output, set filename and filler for space for readable output.console.setup(text_space=15)fileio.setup(text_space=15, filename=filename)# register the outputlog.register(console)log.register(fileio)# switch logging onlog.open()# example 1, this will be shown with every log levellog.inform("EXAMPLE", "example 1, this will be shown with every log level")# example 2, this will be shown with every log levellog.warn("EXAMPLE", "this will be shown with every log level")# error example, this will be shown with every log levellog.error("this will be shown with every log level!")# debug 1 example, this will be shown only with log level 1 and abovelog.debug1("DEBUG", "this will be shown only with log level 1 and above")# debug 2 example, this will be shown only with log level 2 and abovelog.debug2("DEBUG", "this will be shown only with log level 2 and above")# debug 3 example, this will be shown only with log level 3log.debug3("DEBUG", "this will be shown only with log level 3")# show exceptions, this will be shown with every log levellog.inform("EXCEPTIONS", "this will be shown with every log level")try:_ = 1 / 0except ZeroDivisionError as e:log.exception(e)# show traceback, this will be shown with every log levellog.inform("TRACEBACK", "this will be shown with every log level")try:_ = 1 / 0except ZeroDivisionError:log.traceback()# show a progress meter via console# first parameter: limit of the counter# second parameter: update interval# the update interval is there to prevent flickering, it also reduces the loadlog.inform("PROGRESS", "count from 0 to 1000 in 10 interval, set the value via set()")count1 = 0progress1 = log.progress(1000, 10)while True:progress1.set(count1)time.sleep(0.0001)count1 += 1if count1 > 1000:break# to remove the progress bar use clearlog.clear()# it also can be used backwardslog.inform("PROGRESS", "count from 1000 to 0 in 10 interval, set the value via set()")count2 = 1000progress2 = log.progress(1000, 10)progress2._counter = 1000while True:progress2.set(count2)time.sleep(0.0001)count2 -= 1if count2 == 0:break# to remove the progress bar use clearlog.clear()# now we use inc instead of setting the valuelog.inform("PROGRESS", "count from 0 to 1000 in 10 interval, set the value via inc()")count3 = 0progress3 = log.progress(1000, 10)while True:progress3.inc()time.sleep(0.0001)count3 += 1if count3 > 1000:break# to remove the progress bar use clearlog.clear()log.inform("MEASURE", "Measure time.sleep(3)")timer1 = log.timer("Measure something")time.sleep(3)timer1.stop()