Package: simplog
SimplogA simple, functional, opinionated logger for pythonMotivationI generally only need to implement simple logging in my services. For the most part, I don't need anything especially fancy,
but I do need to stick to a consistent format, to help log analyzers do their job.RequirementsCurrently this requires python 3 to run (developed against 3.6, but should compile under most recent versions)UsageThere are 3 main steps:Generate a loging function:log = logger.make_logger(print)Provide some input into logging function:log("The program is exploding", level='error', why='Value Error')Observe the results:2018-12-02T22:44:17.269137 level=error why="Value Error" msg="The program is exploding"Note that only level and message are requird. Level, in addition, has a default value ofinfo. All other values
to be logged can be provided as keyword arguments (see above), which will be logged inkey=valueformat. The current
system time is always provided as well, to help order the events.
In addition, there are some configuration possible that will make themselves useful in certain situations.BasicTypically, all I need is a print that goes to standard out. You can accomplish this via this approach:fromloggerimportmake_logger,refine_loggerfromuuidimportuuid4# Generate a logger functionmain_logger=make_logger()main_logger("This is happening on the mainline")# prints to standard out: 'dt level=info msg="This is happening on the mainline"'ctx_logger=refine_logger(main_logger,context=uuid4())ctx_logger("A configured logger")# prints to standard out: 'dt level=info context="ff088e2c-b127-4d8a-ba1d-347de59d302e" msg="A configured logger"'AdvancedIf you need something more robust, then there are some configuration opportunities.Preconfigre log valuesIf you want to ensure that consistent values are always provided with the logger, you can refine the logger via therefine_loggermethod. This will return a new logger that always have the supplied arugments when called. Note that
under the hood, this is just a call to functool'spartiallog=make_logger()rlog=refine_logger(log,confidence_level="100%")rlog("Things are going well")# Outputs: 2018-12-02T23:23:43.524875 level=info confidence_level=100% msg="Things are going well"# These values is overwritable as well:rlog("Things aren't looking so great",confidence_level="25%")# Outputs: 2018-12-02T23:24:07.786726 level=info confidence_level=25% msg="Things aren't looking so great"Output to somewhere elseThis project is meant to log to the console, but will accept any function that accepts a string as input.# Completely untested, but in theory this would workimportosdefmake_filewriter_function(output_path):writer=open(output_path,'a',0)# Writing in unhuffered modedefwrite_fn(s):writer.write(s)defclose_fn():os.close(writer)returnwrite_fn,close_fnwrite_fn,close_fn=make_filewriter_function('/var/log/my-script-log.log')log=logger.make_logger(write_fn)# ...close_fn()Change default labelsIf you don't likemsgandlevelyou can easily switch these when making the logger
If you want to add a label for the time, you can do that toocustom_log=logger.make_logger(print,message_label='message',level_label='logLevel',time_label='app_time')custom_log("Look at that!")# outputs: app_time=2018-12-02T23:06:59.566174 logLevel=info message="Look at that!"Forcing quotingBy default, any value that does not have a space in it will be left unquoted, while any string that does have a space will be double-quoted
(i.e."Expect values like this")
If you always make to make sure your values are quoted, you can do that by supplyingforce_quote=Truein the make_logger constructor.Serialize non-standard valuesIf you have some class you want to log, you'll need to supply your own serializer. Once you have that, you can pass the serialize func
using theto_string_funcparameter.DevelopmentThis project uses pipenv to aid development. Seehttps://pipenv.readthedocs.io/en/latest/for usage.Running testsThis project utilizes pytest for running unit tests. They can be run via:pipenvshellcdsimplog
python-mpytestTODOsMake a proper distributableTest & Optimize performanceSuport custom character escapes?Add in support for mypy