Je suis nouveau sur Python et je commence juste un projet. J'ai l'habitude d'utiliser log4j
in Java et je voudrais enregistrer tous les modules et classes dans Python comme je le fais en Java.
Dans Java J'ai un fichier de configuration de journal dans le dossier src nommé log4j.properties
comme ci-dessous:
log4j.rootLogger=DEBUG, Console, fileout
log4j.appender.Console=org.Apache.log4j.ConsoleAppender
log4j.appender.Console.layout=org.Apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} %5p [%t] (%F:%L) - %m%n
log4j.appender.fileout=org.Apache.log4j.RollingFileAppender
log4j.appender.fileout.File=servidor.log
log4j.appender.fileout.layout=org.Apache.log4j.PatternLayout
log4j.appender.fileout.layout.ConversionPattern=%d{dd/MM/yyyy HH:mm:ss} (%F:%L) %p %t %c - %m%n
Il se connecte à la console et à un fichier.
Dans mes cours, je n'ai qu'à importer log4j
et ajoutez un attribut statique pour récupérer le log4j
logger avec config chargé alors toutes les classes se connecteront dans la console et le fichier. Le fichier de configuration est chargé automatiquement par le nom. Par exemple:
import org.Apache.log4j.Logger;
public class Main {
public static Logger logger = Logger.getLogger(Main.class);
public static void main(String[] args) {
logger.info("Hello");
}
}
Maintenant, j'ai du mal à configurer la journalisation en Python, j'ai lu la documentation mais je n'ai pas trouvé de moyen de l'utiliser dans de nombreux modules/classes. Comment pourrais-je configurer Python se connecter de manière simple pour enregistrer mes modules et classes sans code beaucoup dans chaque module/classe? Est-il possible de reproduire le même code que j'ai écrit en Python?
En fait, en Python cela ressemble à peu près. Il existe différentes façons de le faire. Je crée généralement une classe de journalisation qui est très simple:
import os
import logging
import settings # alternativly from whereever import settings
class Logger(object):
def __init__(self, name):
name = name.replace('.log','')
logger = logging.getLogger('log_namespace.%s' % name) # log_namespace can be replaced with your namespace
logger.setLevel(logging.DEBUG)
if not logger.handlers:
file_name = os.path.join(settings.LOGGING_DIR, '%s.log' % name) # usually I keep the LOGGING_DIR defined in some global settings file
handler = logging.FileHandler(file_name)
formatter = logging.Formatter('%(asctime)s %(levelname)s:%(name)s %(message)s')
handler.setFormatter(formatter)
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
self._logger = logger
def get(self):
return self._logger
Ensuite, si je veux enregistrer quelque chose dans une classe ou un module, j'importe simplement l'enregistreur et crée une instance. La transmission du nom de classe créera un fichier pour chaque classe. L'enregistreur peut ensuite enregistrer des messages dans son fichier via le débogage, les informations, les erreurs, etc.:
from module_where_logger_is_defined import Logger
class MyCustomClass(object):
def __init__(self):
self.logger = Logger(self.__class__.__name__).get() # accessing the "private" variables for each class
def do_something():
...
self.logger.info('Hello')
def raise_error():
...
self.logger.error('some error message')
Au fil des ans, j'ai changé la façon dont j'utilise Python journalisation un peu. Sur la base des bonnes pratiques, je configure la journalisation de l'ensemble de l'application une fois dans le module chargé en premier lors du démarrage de l'application et puis utilisez des enregistreurs individuels dans chaque fichier. Exemple:
# app.py (runs when application starts)
import logging
import os.path
def main():
logging_config = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s [%(levelname)s] %(name)s: %(message)s'
},
},
'handlers': {
'default_handler': {
'class': 'logging.handlers.FileHandler',
'level': 'DEBUG',
'formatter': 'standard',
'filename': os.path.join('logs', 'application.log'),
'encoding': 'utf8'
},
},
'loggers': {
'': {
'handlers': ['default_handler'],
'level': 'DEBUG',
'propagate': False
}
}
}
logging.config.dictConfig(logging_config)
# start application ...
if __name__ == '__main__':
main()
# submodule.py (any application module used later in the application)
import logging
# define top level module logger
logger = logging.getLogger(__name__)
def do_something():
# application code ...
logger.info('Something happended')
# more code ...
try:
# something which might break
except SomeError:
logger.exception('Something broke')
# handle exception
# more code ...
Ce qui précède est la méthode recommandée pour ce faire. Chaque module définit son propre enregistreur et peut facilement s'identifier en fonction du __name__
attribut quel message a été connecté dans quel module lorsque vous inspectez les journaux. Cela supprime le passe-partout de ma réponse d'origine et utilise à la place le logging.config
module de la bibliothèque standard Python.
Les documents fournissent un assez bon exemple d'utilisation de votre enregistreur dans plusieurs modules . Fondamentalement, vous configurez la journalisation une fois au début de votre programme. Ensuite, vous importez le module de journalisation où vous voulez avoir la journalisation et l'utilisez.
import logging
import mylib
def main():
logging.basicConfig(filename='myapp.log', level=logging.INFO)
logging.info('Started')
mylib.do_something()
logging.info('Finished')
if __name__ == '__main__':
main()
import logging
def do_something():
logging.info('Doing something')
Cet exemple montre une configuration d'enregistreur très simpliste, mais vous pouvez très facilement utiliser différentes façons de configurer la journalisation pour configurer des scénarios plus avancés.