Package: thelogger
TheLoggerEasy logging, timing and email notifications of code execution.Installation$ pip install theloggerLoggingmy_script.py:fromtheloggerimportlg# log messageslg.info('Hello World')lg.warning('warning message')lg.error('error message')# start logging messages to a filelg.reset(file='./demo_log.txt')# shorthand convenience methods for logging messageslg.i('this is an info message')lg.w('this is a warning message')# remove log handlerslg.close()lg.i('nothing is logged because there are no log handlers')# add default log handlerslg.reset()Output to Console:[I 2021-11-13 08:50:36] Hello World
[W 2021-11-13 08:50:36] warning message
[E 2021-11-13 08:50:36] error message
[I 2021-11-13 08:50:36] this is an info message
[W 2021-11-13 08:50:36] this is a warning messageOutput to demo_log.txt:[I 2021-11-13 08:50:36 my_script:12] this is an info message
[W 2021-11-13 08:50:36 my_script:13] this is a warning messageEmail Notificationsfromtheloggerimportlg,notify# decorate your func with @notify and pass in your email address@notify(email='my_email@gmail.com')defconcat_str(arg1,arg2=''):returnf'{arg1}{arg2}'# when concat_str is finished executing you will receive an email with the detailsmy_str=concat_str('hello','world')# pass a logger object to log the function execution details@notify(email='my_email@gmail.com',logger=lg)defconcat_str(arg1,arg2=''):returnf'{arg1}{arg2}'my_str=concat_str('hello','world')# include a remote host address if your organization has gmail blocked@notify(email='my_email@gmail.com',logger=lg,host='mail.abc.com')defconcat_str(arg1,arg2=''):returnf'{arg1}{arg2}'my_str=concat_str('hello','world')# quick test to see if you're able to receive emailsnotify('my_email@gmail.com',test=True)# set the default arguments for the notify decoratornotify=notify(email='my_email@gmail.com',logger=lg,setdefault=True)# now you can decorate functions w/o passing the args to @notify each time@notifydefconcat_str(arg1,arg2=''):returnf'{arg1}{arg2}'my_str=concat_str('hello','world')Example Email:"Free" Logging of ScriptsLeverage TheLogger to easily log a program's execution details without typing out any log messages. See below example script and log file.my_program.py:importnumpyasnpimportpandasaspdfromtheloggerimportnotify,lglg=lg.reset(file='my_program.log')notify=notify(setdefault=True,logger=lg)@notifydefget_data(arg1):data=pd.DataFrame(np.random.randint(0,100,size=(10**7,50)))returndata@notifydefwrangle_data(data):data2=data.iloc[0:5,0:5]+1returndata2@notifydefdistribute_data(data2):print(data2)@notifydefexecute_program(program_name):data=get_data('my_arg')data2=wrangle_data(data)distribute_data(data2)return'success'execute_program('my_program')Output to my_program.log:[I 2022-04-19 20:43:56 my_program:36] Starting: execute_program('my_program')...
[I 2022-04-19 20:43:56 my_program:31] Starting: data = get_data('my_arg')...
[I 2022-04-19 20:43:59 my_program:31] Finished: data = get_data('my_arg')...
[I 2022-04-19 20:44:00 my_program:31] Inputs and Output of get_data:
| Variable   | Type                          | Length   | String                                                      |
|------------|-------------------------------|----------|-------------------------------------------------------------|
| arg1       | 'str'                         | 6        | my_arg                                                      |
| output     | 'pandas.core.frame.DataFrame' | 10000000 | cols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ... |
Elapsed Time: 0:00:03.479504
[I 2022-04-19 20:44:00 my_program:32] Starting: data2 = wrangle_data(data)...
[I 2022-04-19 20:44:00 my_program:32] Finished: data2 = wrangle_data(data)...
[I 2022-04-19 20:44:00 my_program:32] Inputs and Output of wrangle_data:
| Variable   | Type                          | Length   | String                                                      |
|------------|-------------------------------|----------|-------------------------------------------------------------|
| data       | 'pandas.core.frame.DataFrame' | 10000000 | cols: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, ... |
| output     | 'pandas.core.frame.DataFrame' | 5        | cols: 0, 1, 2, 3, 4...                                      |
Elapsed Time: 0:00:00.000718
[I 2022-04-19 20:44:00 my_program:33] Starting: distribute_data(data2)...
[I 2022-04-19 20:44:00 my_program:33] Finished: distribute_data(data2)...
[I 2022-04-19 20:44:00 my_program:33] Inputs and Output of distribute_data:
| Variable   | Type                          | Length   | String                 |
|------------|-------------------------------|----------|------------------------|
| data2      | 'pandas.core.frame.DataFrame' | 5        | cols: 0, 1, 2, 3, 4... |
| output     | 'NoneType'                    | nan      | None                   |
Elapsed Time: 0:00:00.004332
[I 2022-04-19 20:44:00 my_program:36] Finished: execute_program('my_program')...
[I 2022-04-19 20:44:00 my_program:36] Inputs and Output of execute_program:
| Variable     | Type   | Length   | String     |
|--------------|--------|----------|------------|
| program_name | 'str'  | 10       | my_program |
| output       | 'str'  | 7        | success    |
Elapsed Time: 0:00:03.69315