pythonはlogingモジュールを単独モジュールにパッケージし、動的な切り替えを実現するLevel方式
たくさんの資料を探しましたが、ネットで提供された教程は全部大同小異です。コードをもっと簡潔にして、結合したいです。次の二つの目標を実現したいです。
1.logingモジュールの初期化、構成、設定などのコードを一つのモジュールにパッケージ化する。
2.構成によってloging.levelを切り替えることができます。ネットで提供された教程は全部書き終わりました。もし私がオンラインで上の前でloging.infoを使ったら、今loging.debug(msg)に切り替えたいですが、どうすればいいですか?設定ファイルの設定に応じて、loging.levelを設定する必要があります。
二つのファイル:
ロゴギングクラス:logingモジュールの初期化、配置、設定などのコードをこのモジュールに入れて、プロファイルのlogレベルの設定項目を読み込みます。ロゴ機能を使うモジュールimportというモジュールが必要です。
applogconfig.ini:プロファイル
ロゴギングクラス:
loggingのパッケージをデバッグすると、既にlogingパッケージの関数が呼び出されています。他の関数に再起動されると、重複したloggingが表示されます。原因は違うところでハンドルが作成されていますので、繰り返します。暴力的な方法で解決できます。
暴力は新しいオブジェクトを作成するたびに、ロゴを空にする方法です。
私がよく使うパッケージは以下の通りです。
1.logingモジュールの初期化、構成、設定などのコードを一つのモジュールにパッケージ化する。
2.構成によってloging.levelを切り替えることができます。ネットで提供された教程は全部書き終わりました。もし私がオンラインで上の前でloging.infoを使ったら、今loging.debug(msg)に切り替えたいですが、どうすればいいですか?設定ファイルの設定に応じて、loging.levelを設定する必要があります。
二つのファイル:
ロゴギングクラス:logingモジュールの初期化、配置、設定などのコードをこのモジュールに入れて、プロファイルのlogレベルの設定項目を読み込みます。ロゴ機能を使うモジュールimportというモジュールが必要です。
applogconfig.ini:プロファイル
ロゴギングクラス:
import logging
import sys
import ConfigParser
def log_building(log_file):
try:
#set format
format_str=logging.Formatter("%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s")
#create stander output handler
crit_hand=logging.StreamHandler(sys.stderr)
crit_hand.setFormatter(format_str)
#create file handler
file_hand=logging.FileHandler(log_file,'a')
file_hand.setFormatter(format_str)
app_log=logging.getLogger(__name__)
app_log.addHandler(crit_hand)
app_log.addHandler(file_hand)
# ,
app_log.setLevel(logging.NOTSET)
return app_log
except Exception as e:
logging.shutdown()
raise e
def config_file_get(fpath):
try:
cnf_dict={}
cfg=ConfigParser.SafeConfigParser()
cfg.read(fpath)
for section in cfg.sections():
# ini item ,key=section+_option
for item in cfg.items(section):
key= section+'_'+item[0]
value=item[1]
if cnf_dict.get(key,None)==None:
cnf_dict[key]=value
return cnf_dict
except Exception as e:
raise e
def log_level_get(level):
DEBUG_LEVEL={'CRITICAL':logging.CRITICAL,'ERROR':logging.ERROR,'WARNING':logging.WARNING,
'INFO':logging.INFO,'DEBUG':logging.DEBUG
}
try:
return DEBUG_LEVEL.get(level.upper())
except Exception as e:
raise e
applogconfig.iniの内容:
[log]
log_level=ERROR
dir=log
以下はunittestの内容です。
import unittest
import logging_class
import os
import logging
class Test(unittest.TestCase):
cfg={}
def setUp(self):
print 'test begin'
self.cfg={}
def tearDown(self):
print 'test end'
def testlog_level_get(self):
currentWorkingPath = r'E:\Myworkspace\python\logging_module\logging_module'
ini_file=os.path.normpath(os.path.abspath(os.path.join(currentWorkingPath,'applogconfig.ini')))
self.cfg=logging_class.config_file_get(ini_file)
self.assertEqual(self.cfg['log_log_level'].upper(), 'ERROR', 'OK')
def testlog_level_set(self):
currentWorkingPath = r'E:\Myworkspace\python\logging_module\logging_module'
ini_file=os.path.normpath(os.path.abspath(os.path.join(currentWorkingPath,'applogconfig.ini')))
self.cfg=logging_class.config_file_get(ini_file)
#print self.cfg['log_log_level']
self.assertEqual(logging_class.log_level_get(self.cfg['log_log_level']), logging.ERROR, 'OK')
def testlog_building(self):
currentWorkingPath = r'E:\Myworkspace\python\logging_module\logging_module'
ini_file=os.path.normpath(os.path.abspath(os.path.join(currentWorkingPath,'applogconfig.ini')))
log_file=os.path.normpath(os.path.abspath(os.path.join(currentWorkingPath,'b.log')))
self.cfg=logging_class.config_file_get(ini_file)
#print self.cfg['log_log_level']
level=logging_class.log_level_get(self.cfg['log_log_level'])
log=logging_class.log_building(log_file)
log.log(level, 'dddds')
log.debug('msg')
if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
unittest.main()
出力:
Finding files... done.
Importing test modules ... done.
test begin
test end
test begin
test end
test begin
2016-12-15 17:59:04,059 logging_module_test.py[line:48] ERROR dddds
test end
----------------------------------------------------------------------
Ran 3 tests in 0.004s
知識を補充します:1種のlogingのカプセル化の方法、重複のloggを生むことはできませんloggingのパッケージをデバッグすると、既にlogingパッケージの関数が呼び出されています。他の関数に再起動されると、重複したloggingが表示されます。原因は違うところでハンドルが作成されていますので、繰り返します。暴力的な方法で解決できます。
暴力は新しいオブジェクトを作成するたびに、ロゴを空にする方法です。
私がよく使うパッケージは以下の通りです。
import logging
import time,os
'''
:
import mylog
log = mylog.Log().getlog()
log.debug("###")
'''
class Log():
def __init__(self,logger="mylog"):
self.logger = logging.getLogger(logger)
self.logger.setLevel(logging.DEBUG)
self.log_time = "\\"+time.strftime("%Y-%m-%d_%H_%M", time.localtime())+".log"
# log
# self.log_path = os.path.join(os.getcwd() + "\\log")
# mylog
self.log_path = os.path.join(os.path.dirname(os.path.dirname(__file__)) + "\\log")
if os.path.exists(self.log_path) and os.path.isdir(self.log_path):
pass
else:
os.makedirs(self.log_path)
self.log_name = os.path.join(self.log_path + self.log_time)
# logger handlers, handler
self.logger.handlers = []
fh = logging.FileHandler(self.log_name, 'a', encoding='utf-8')
formatter = logging.Formatter('[%(levelname)s][%(asctime)s] [%(filename)s]->[%(funcName)s] line:%(lineno)d ---> %(message)s')
fh.setLevel(logging.DEBUG)
fh.setFormatter(formatter)
self.logger.addHandler(fh)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
self.logger.addHandler(ch)
fh.close()
def getlog(self):
return self.logger
if __name__ == "__main__":
log = Log().getlog()
log.debug("hello")
以上のpythonはloggingモジュールを単独のモジュールにパッケージして、動的な切り替えを実現するLevel方式は小編集で皆さんに共有した内容です。参考にしていただきたいです。どうぞよろしくお願いします。