La configuration globale des logs se fera via des variables d'environnement positionnée au niveau de la configuration de systemd dans /etc/systemd/system.conf
via la directive DefaultEnvironment
. Sur un système en marche on fera ensuite systemctl daemon-reexec
pour s'assurer du rechargement de la configuration, aussi on relancera les démons concernés.
Le niveau NOTICE n'existe pas en Python, on l'ajoutera et on lui donnera comme valeur 25.
DefaultEnvironment="SENTRY_DSN=https://a2009....ouvert.org/1" "GRAYLOG_URL=ufo.entrouvert.org:12203"
mettre aussi dans /etc/environment
pour que l'environnement utilisateur et système soit équivalent:
SENTRY_DSN=https://a20092f7b3da484abf8fc0a4ee2f7202:c9fab41dcde24b04a30ac01ffd3c2457@sentry.entrouvert.org/1
INSTALLED_APPS += ('raven.contrib.django.raven_compat', ) RAVEN_CONFIG = { 'dsn': 'https://a20092f7b3da484abf8fc0a4ee2f7202:c9fab41dcde24b04a30ac01ffd3c2457@sentry.entrouvert.org/1', }
?verify_ssl=0
sys.stderr
:import logging logging.basicConfig(format='%(asctime)-15s $(levelname)s %(message)s', level=logging.INFO/WARNING/ERROR) # définir le niveau en fonction d'une option --verbose par exemple logger = logging.getLogger('monscript') logger.info('python was here')
project_name
et django
au niveau INFO
.debian_settings.py
du packaging idem mais vers syslogdisable_existing_logger
à True
sinon on se retrouve avec les logs gunicorn dans /var/log/syslog
ou la consolelogging.getLogger()
dans un contexte global (ex.: logger = logging.getLogger(__name__)
si le module s'exécute avant le chargement des settings; le logger sera désactivé avant même d'avoir pu servir. On demande un logger quand on en a besoin pas avant.DEBUG
lorsque DEBUG
est à True
? C'est pratique mais c'est un retour en arrière parce que cela demande de faire des trucs après le chargement du fichier de settings local. Sinon on peut aussi faire des macros i.e. par exemple juste avant le execfile()
du fichier PROJECT_SETTINGS_FILE
on définit: def debug(): global DEBUG, LOGGING DEBUG = True for logger in LOGGING["loggers"]: logger["level"] = "DEBUG"Comme cela on définit un comportement par défaut utilisable facilement mais on laisse aussi la possibilité de faire autrement.
python-entrouvert
nommé entrouvert.logging.handlers.SyslogHandler
qui découpe les message de plus de 120 caractères en plusieurs pour que tout passe. Généralise-t-on son utilisation ou peut-on envisager une autre solution ?Formatter
qui ferait un get_connection()
et aui ajouterait le nom du tenant au logrecord avant de formater le message.>>> from logging_tree import printout >>> printout() "" Level DEBUG Propagate OFF Handler Stream <open file '<stderr>', mode 'w' at 0x7fd2285a2270> Level DEBUG Formatter fmt='[%(asctime)s] %(levelname)s %(name)s.%(funcName)s: %(message)s' datefmt='%Y-%m-%d %a %H:%M:%S' Handler <authentic2.middleware.ThreadTrackingHandler object at 0x3430b10> | o<--"attribute_aggregator" | Level NOTSET so inherits level DEBUG | o<--[authentic2] | | | o<--[authentic2.attribute_aggregator] | | | | | o<--"authentic2.attribute_aggregator.attributes" | | | Level NOTSET so inherits level DEBUG | | | | | o<--"authentic2.attribute_aggregator.models" | | | Level NOTSET so inherits level DEBUG | | | | | o<--"authentic2.attribute_aggregator.user_profile" | | Level NOTSET so inherits level DEBUG | | | o<--"authentic2.managers" | | Level NOTSET so inherits level DEBUG | | | o<--"authentic2.plugins" | | Level NOTSET so inherits level DEBUG | | Disabled | | | o<--[authentic2.saml] | | | o<--"authentic2.saml.admin" | Level NOTSET so inherits level DEBUG | o<--[django] | | | o "django.db" | | Level INFO | | Propagate OFF | | Handler Stream <open file '<stderr>', mode 'w' at 0x7fd2285a2270> | | Level DEBUG | | Formatter fmt='[%(asctime)s] %(levelname)s %(name)s.%(funcName)s: %(message)s' datefmt='%Y-%m-%d %a %H:%M:%S' | | | | | o<--"django.db.backends" | | Level NOTSET so inherits level INFO | | | | | o<--"django.db.backends.schema" | | Level NOTSET so inherits level INFO | | | o<--"django.request" | Level NOTSET so inherits level DEBUG | Disabled | o<--"django_select2" | Level NOTSET so inherits level DEBUG | | | o<--"django_select2.fields" | | Level NOTSET so inherits level DEBUG | | | o<--"django_select2.util" | | Level NOTSET so inherits level DEBUG | | | o<--"django_select2.widgets" | Level NOTSET so inherits level DEBUG | o<--[py] | | | o<--"py.warnings" | Level NOTSET so inherits level DEBUG | Handler <logging.NullHandler object at 0x20ed250> | o<--"requests" Level NOTSET so inherits level DEBUG Handler <logging.NullHandler object at 0x2f4a3d0> | o<--[requests.packages] | o<--"requests.packages.urllib3" Level NOTSET so inherits level DEBUG Handler <logging.NullHandler object at 0x2f4a350> | o<--"requests.packages.urllib3.connectionpool" | Level NOTSET so inherits level DEBUG | o<--"requests.packages.urllib3.poolmanager" | Level NOTSET so inherits level DEBUG | o<--[requests.packages.urllib3.util] | o<--"requests.packages.urllib3.util.retry" Level NOTSET so inherits level DEBUGtesté sur authentic avec la configuration suggérée par les gens de Caktus group