Supposons que vous souhaitiez développer un outil de script automatisé. La structure du projet est la suivante Common
Ceci package
est l'implémentation de la fonction framework Le répertoire Scripts
est le script de cas de test que nous avons écrit (veuillez ignorer). autres répertoires non pertinents).
Nos exigences pour la fonction de journalisation sont les suivantes :
1 Afin de faciliter la visualisation des journaux, chaque script correspond à un fichier journal, et le fichier journal est nommé d'après le nom du script
2 Le chemin du journal et la capacité du journal enregistré par chaque script peuvent être définis. Par exemple, s'il est défini sur 5 Mo, le journal le plus ancien sera automatiquement écrasé
3 Le. La fonction log doit être facile à utiliser et réduire le couplage avec les fonctions métier du framework
Analysons maintenant les exigences ci-dessus une par une.
1 Pour implémenter un fichier journal pour chaque script , vous devez générer un fichier journal en fonction du nom du script de cas d'utilisation dans le module de journalisation. Le problème clé ici est de savoir comment obtenir le nom du script de cas d'utilisation dans le module de journalisation.
Les méthodes courantes pour obtenir les noms de fichiers sont : os.getcwd()
, sys.argv[0], __file__,
Jetons un coup d'œil aux différentes fonctions :
Écrivez d'abord le code suivant dans un fichier (supposé être test.py
) :
Puis script1.py
dans un autre fichier (supposé être import test
), puis appeler la méthode func
:
En cours d'exécution script1.py
, le résultat est :
On voit que os.getcwd()
obtient le répertoire d'exécution du script, et sys.argv[0]
est le répertoire absolu pour exécuter le script. Nom du chemin, __file__
est le nom du chemin absolu du fichier où se trouve le code exécuté.
Il est maintenant clair que nous devons utiliser sys.argv[0]
pour obtenir le nom du script d'exécution Puisque le chemin absolu est obtenu, certains traitements doivent être effectués : sys.argv[0].split('/')[-1].split('.')[0]
<.>2 Problème de capacité du journal Pour écraser automatiquement le journal le plus ancien une fois la capacité dépassée, utilisez la classe dans logging
. nombre de sauvegardes. RotatingFileHandler
. Il est préférable de ne pas laisser les utilisateurs modifier le fichier framework. Les utilisateurs n'ont qu'à appeler l'interface et écrire leurs propres scripts. RotatingFileHandler
et nommez-le Common
Le contenu est : config.xml
<?xml version="1.0" encoding="utf-8"?> <config> <!-- 日志保存路径 --> <logpath>E:\PythonLog</logpath> <!-- 每个脚本对应的日志文件大小,单位MB --> <logsize>8</logsize> <!-- 每个脚本保存的日志文件个数 --> <lognum>3</lognum> </config>
pour récupérer le contenu du fichier XML. Le code sera donné plus tard. lxml
3 La fonction de journalisation doit être simple à utiliser et réduire le couplage avec les fonctions métiers du framework. Il est préférable d'encapsuler. la fonction de journalisation et fournit uniquement l'interface pour l'enregistrement des journaux est suffisante.
L'interface de journalisation adopte la forme d'une méthode de classe pour répondre aux exigences ci-dessus. Les utilisateurs n'ont qu'à appeler l'interface de journalisation via la classe, qui peut être appelée n'importe où. définir des instances de classe et n'est pas couplé au framework business. Avec l'analyse ci-dessus, implémentons le module de journalisation. Puisque la fonction de journalisation fait également partie de la base du framework, nous plaçons également le module de journalisation dans ce Common
, et créons un nouveau fichier package
sous Common
. est la suivante : log.py
# coding: utf-8 from lxml import etree import logging.handlers import logging import os import sys # 提供日志功能 class logger: # 先读取XML文件中的配置数据 # 由于config.xml放置在与当前文件相同的目录下,因此通过 __file__ 来获取XML文件的目录,然后再拼接成绝对路径 # 这里利用了lxml库来解析XML root = etree.parse(os.path.join(os.path.dirname(__file__), 'config.xml')).getroot() # 读取日志文件保存路径 logpath = root.find('logpath').text # 读取日志文件容量,转换为字节 logsize = 1024*1024*int(root.find('logsize').text) # 读取日志文件保存个数 lognum = int(root.find('lognum').text) # 日志文件名:由用例脚本的名称,结合日志保存路径,得到日志文件的绝对路径 logname = os.path.join(logpath, sys.argv[0].split('/')[-1].split('.')[0]) # 初始化logger log = logging.getLogger() # 日志格式,可以根据需要设置 fmt = logging.Formatter('[%(asctime)s][%(filename)s][line:%(lineno)d][%(levelname)s] %(message)s', '%Y-%m-%d %H:%M:%S') # 日志输出到文件,这里用到了上面获取的日志名称,大小,保存个数 handle1 = logging.handlers.RotatingFileHandler(logname, maxBytes=logsize, backupCount=lognum) handle1.setFormatter(fmt) # 同时输出到屏幕,便于实施观察 handle2 = logging.StreamHandler(stream=sys.stdout) handle2.setFormatter(fmt) log.addHandler(handle1) log.addHandler(handle2) # 设置日志基本,这里设置为INFO,表示只有INFO级别及以上的会打印 log.setLevel(logging.INFO) # 日志接口,用户只需调用这里的接口即可,这里只定位了INFO, WARNING, ERROR三个级别的日志,可根据需要定义更多接口 @classmethod def info(cls, msg): cls.log.info(msg) return @classmethod def warning(cls, msg): cls.log.warning(msg) return @classmethod def error(cls, msg): cls.log.error(msg) return
et script1
respectivement : script2
from Common.log import * logger.info('This is info') logger.warning('This is warning') logger.error('This is error')
Fichier journal généré :
Contenu du fichier :
Pour plus d'articles liés à l'utilisation de la fonction de journal de script Python, veuillez faire attention au site Web PHP chinois !