2
votes

comment définir le niveau de journalisation à partir de la ligne de commande

J'utilise argparse pour obtenir le niveau de journalisation à partir de la ligne de commande, puis je le passe comme entrée pour logging.basicConfig. Cependant, la façon dont j'essaie de mettre en œuvre cela ne fonctionne pas. Une suggestion?

Comportement souhaité, depuis la ligne de commande:

import logging
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("-log", "--log", nargs='+', help="Provide logging level. Example --log debug'")

log_level = parser.parse_args().log
log_level = 'logging.'+log_level[0]
print(log_level)
logging.basicConfig(level=log_level)
logger = logging.getLogger(__name__) 
logger.debug(' Debug is working')

Sortie souhaitée

DEBUG:__main__: Debug is working

Code

python main.py -log=DEBUG


4 commentaires

Pourquoi mettez-vous nargs = '+' , l'utilisateur doit choisir un seul niveau, la notation par défaut est que votre paramètre est facultatif ( documentation python )?


@ndclt vous avez raison, nargs = '+' n'est pas obligatoire et c'était la raison principale pour laquelle j'obtenais une liste en entrée.


Je recommande souvent args = parser.parse_args () suivi de print (args) . Le vous donne une (plus) idée claire de ce que l'analyseur a fait pour vous.


Voir également stackoverflow.com/questions/14097061


4 Réponses :


2
votes

Le niveau doit être une variable de logging et non une chaîne, logging.DEBUG par exemple. Je pense que vous devez créer un dict correspondant à l'argument donné et à la variable de journalisation:

level_config = {'debug': logging.DEBUG, 'info': logging.INFO} # etc.
log_level = level_config[parser.parse_args().log[0].lower()]

Vous pouvez également ajouter choice = ['debug', 'info', 'warning'] dans votre appel add_argument .


4 commentaires

Salut, j'ai essayé votre suggestion et j'ai obtenu l'erreur suivante: AttributeError: l'objet 'list' n'a pas d'attribut 'lower'


J'ai oublié un [0] après le journal (je modifie mon message). Mais je pense que la solution blues est plus élégante que la mienne.


Bien fait. Celui-ci devrait être sélectionné comme réponse!


Depuis Python 3.2, vous pouvez spécifier le niveau sous forme de chaîne



1
votes

log_level = 'logging.' + log_level [0] cela rend juste la chaîne 'logging.DEBUG' qui n'est pas quelque chose que basicConfig comprend. ce qu'il veut, c'est la constante logging.DEBUG que vous pouvez obtenir par getattr (logging, log_level [0]) . Les nouvelles versions de python acceptent également la représentation textuelle et vous pouvez simplement passer 'DEBUG' comme niveau.


2 commentaires

Salut @blues, après avoir essayé log_level = getattr (journalisation, log_level [0]), logging.basicConfig (level = log_level), j'ai eu l'erreur suivante rise TypeError ("Level not an integer or a valid string:% r"% level) TypeError: Level n'est pas un entier ou une chaîne valide:


Je suppose que vous n'avez pas capitalisé l'argument. Assurez-vous de fournir l'argument sous la forme -log = DEBUG et non -log = debug . Ou appelez .upper () dessus.



5
votes

Mettre ces combinaisons ensemble, permettant à l'utilisateur de nommer le niveau avec des majuscules ou des minuscules, permettant de spécifier un seul niveau, et de choisir le niveau explicite dans un dictionnaire avec une valeur par défaut au niveau WARNING:

import argparse
import logging
parser = argparse.ArgumentParser()
parser.add_argument(
    "-log", 
    "--log", 
    default="warning",
    help=(
        "Provide logging level. "
        "Example --log debug', default='warning'"),
    ),
)

options = parser.parse_args()
levels = {
    'critical': logging.CRITICAL,
    'error': logging.ERROR,
    'warn': logging.WARNING,
    'warning': logging.WARNING,
    'info': logging.INFO,
    'debug': logging.DEBUG
}
level = levels.get(options.log.lower())
if level is None:
    raise ValueError(
        f"log level given: {options.log}"
        f" -- must be one of: {' | '.join(levels.keys())}")
logging.basicConfig(level=level)
logger = logging.getLogger(__name__)


0 commentaires

0
votes

La fonction basicConfig peut prendre un argument de chaîne pour level , et elle vérifiera sa validité pour vous, de sorte que le code peut être beaucoup plus simple que la réponse de BarryPye.

import argparse
import logging

parser = argparse.ArgumentParser()
parser.add_argument( '-log',
                     '--loglevel',
                     default='warning',
                     help='Provide logging level. Example --loglevel debug, default=warning' )

args = parser.parse_args()

logging.basicConfig( level=args.loglevel.upper() )
logging.info( 'Logging now setup.' )


0 commentaires