Package: log-added-func
log_added_func可以在程式碼中間插入想要的log，或者直接把裝飾器放在函數前，其會自動記錄其輸入和輸出資訊。Getting Started輸出的log會自動存取其log時間、file_name、func_name。輸出內容：%(asctime)s $ %(levelname)-10s $(mem_percent) $%(threadName)s $ %(filename)s $ %(funcName)s $ %(message)s客製化log：在想要的地方下Log，可以設定等級。通用型log：用裝飾器包裝，可以將該func運行error列印出來，也會列印輸入的參數和輸出的值。log的存放位置：當前執行的檔案目錄./logs_dir/Installing：pip install log_added_func相依套件concurrent-log-handlerpsutilpywin32 (If you are using Mac or Linux, ignore this key point.)Examples範例1:class內有錯誤raise的logfromlog_added_funcimportlogfromlog_added_funcimportlog_decoratorclassCalculator():def__init__(self,first=0,second=0):self.first=firstself.second=second# Initializing logger object to write custom logsself.logger_obj=log.get_logger()# let self.logger_obj remove from __dict__, it will not pickle.def__getstate__(self):d=dict(self.__dict__)deld['logger_obj']returnddef__setstate__(self,d):self.__dict__.update(d)# I *think* this is a safe way to do it@log_decorator.log_decorator()defadd(self,third=0,fourth=0):# writing custom logs specific to function, outside of log decorator, if neededself.logger_obj.critical("Add function custom log, outside decorator")self.logger_obj.error("Add function custom log, outside decorator")self.logger_obj.warning("Add function custom log, outside decorator")self.logger_obj.info("Add function custom log, outside decorator")self.logger_obj.debug("Add function custom log, outside decorator")try:returnself.first+self.second+third+fourthexcept:raise@log_decorator.log_decorator()defdivide(self):self.logger_obj.info("Divide function custom log, outside decorator")try:returnself.first/self.secondexcept:raiseif__name__=='__main__':calculator=Calculator(5,0)calculator.add(third=2,fourth=3)calculator.divide()輸出2023-01-11 12:19:42,012 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ add $ Arguments: <main.Calculator object at 0x000001969ABF2200>, third=2, fourth=3 - Begin function2023-01-11 12:19:42,017 $ CRITICAL   $ 64.6 $MainThread $ calculator_sample.py $ add $ Add function custom log, outside decorator2023-01-11 12:19:42,021 $ ERROR      $ 64.6 $MainThread $ calculator_sample.py $ add $ Add function custom log, outside decorator2023-01-11 12:19:42,025 $ WARNING    $ 64.6 $MainThread $ calculator_sample.py $ add $ Add function custom log, outside decorator2023-01-11 12:19:42,029 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ add $ Add function custom log, outside decorator2023-01-11 12:19:42,033 $ DEBUG      $ 64.6 $MainThread $ calculator_sample.py $ add $ Add function custom log, outside decorator2023-01-11 12:19:42,038 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ add $ Returned: - End function 102023-01-11 12:19:42,042 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ divide $ Arguments: <main.Calculator object at 0x000001969ABF2200> - Begin function2023-01-11 12:19:42,046 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ divide $ Divide function custom log, outside decorator2023-01-11 12:19:42,050 $ ERROR      $ 64.6 $MainThread $ calculator_sample.py $ divide $ Exception: division by zero範例2: 多進程放log，並且修改log檔名為test_log.logimportmultiprocessingasmpfromlog_added_funcimportlogfromlog_added_funcimportlog_decorator@log_decorator.log_decorator()deftask(num):logger_obj=log.get_logger(log_file_name='test_log')print('This is Process: ',num)logger_obj.info(f"This is Process:{num}")if__name__=='__main__':num_process=5process_list=[]foriinrange(num_process):process_list.append(mp.Process(target=task,args=(i,)))process_list[i].start()foriinrange(num_process):process_list[i].join()輸出2023-01-11 12:23:49,417 $ INFO       $ 64.7 $MainThread $ multiprocess_sample.py $ task $ This is Process: 12023-01-11 12:23:49,416 $ INFO       $ 64.7 $MainThread $ multiprocess_sample.py $ task $ This is Process: 02023-01-11 12:23:49,423 $ INFO       $ 64.7 $MainThread $ multiprocess_sample.py $ task $ This is Process: 22023-01-11 12:23:49,425 $ INFO       $ 64.7 $MainThread $ multiprocess_sample.py $ task $ This is Process: 32023-01-11 12:23:49,433 $ INFO       $ 64.7 $MainThread $ multiprocess_sample.py $ task $ This is Process: 4客製化log載入：fromlog_added_funcimportlogfromlog_added_funcimportlog_decorator初始化：logger_obj=log.get_logger()在想要的地方放log：logger_obj.info("Add function custom log, outside decorator")log輸出範例：2023-01-11 12:19:42,029 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ add $ Add function custom log, outside decorator設定等級：可以設定debug < info < warning < error < critical範例：logger_obj.warning("Add function custom log, outside decorator")通用型log載入：fromlog_added_funcimportlogfromlog_added_funcimportlog_decorator在想要的method放:@log_decorator.log_decorator()defsmaple():passlog輸出範例:2023-01-11 12:19:42,012 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ add $ Arguments: <main.Calculator object at 0x000001969ABF2200>, third=2, fourth=3 - Begin function2023-01-11 12:19:42,038 $ INFO       $ 64.6 $MainThread $ calculator_sample.py $ add $ Returned: - End function 10在通用型的其log等級會自動戴入，規則如下：沒有Error的正常都會是INFO等級。若有except則會是ERRPR等級其他說明可以設定log單檔儲存的大小1 * 1024 * 1024 = 1MBConcurrentRotatingFileHandler(logPath, maxBytes=50 * 1024 * 1024, backupCount=2)log存放的位置window: c:\logs_dir\linux: ./logs_dir/ # 當前目錄若要修改可以在log.py的get_logger調整log檔案名稱預設:main_log客製化:在初始化時設定get_logger(log_file_name="sample_name_log")通用型:@log_decorator.log_decorator(log_file_name="sample_name_log")log以資料夾存放預設:無資料夾若要依資料夾分類log也可以對get_logger下參數log_sub_dirlog也可以用類似print的方式show在terminal只要參數DEBUG_flag設為True即可，預設:False客製化:在初始化時設定get_logger(DEBUG_flag=True)通用型：@log_decorator.log_decorator(DEBUG_flag=True)log的等級寫入說明預設會寫入所有等級(debug < info < warning < error < critical)若要只寫入部分，可以將參數set_level設為想要的等級，e.g.設為"warning"那就是warning、error、critical才會寫入客製化:在初始化時設定get_logger(set_level="warning")通用型：@log_decorator.log_decorator(set_level="warning")縮減log資訊可透過hide_threadname_flag、hide_filename_flag、hide_funcname_flag省略log資訊，預設如下：get_logger(hide_threadname_flag=False, hide_filename_flag=False, hide_funcname_flag=False)TODO目前不會show實例化的class名稱otherpickle包裝logger會有問題 # 在calculator.py有解決範例https://stackoverflow.com/questions/2999638/how-to-stop-attributes-from-being-pickled-in-python多進程會有logging同時讀寫問題: # 理論上已經透過ConcurrentRotatingFileHandler解決https://www.qnjslm.com/ITHelp/996.htmlhttps://stackoverflow.com/questions/22459850/permissionerror-when-using-python-3-3-4-and-rotatingfilehandlerhttps://blog.gdyshi.top/2018/06/27/logging_multiprocess/https://www.programmersought.com/article/43941158027/