Utiliser la journalisation imprimer la sortie de pprint

101

Je veux utiliser la sortie de pprint pour afficher une structure de données complexe, mais je voudrais la sortir en utilisant le module de journalisation plutôt que stdout.

ds = [{'hello': 'there'}]
logging.debug( pprint.pprint(ds) ) # outputs as STDOUT
yee379
la source
J'ai parcouru les documents et j'ai trouvé pprint( {}, stream ), mais j'ai trouvé cela plutôt gênant. J'aurais pensé que quelque chose comme ça spprintaurait pu être plus agréable que pformat(comme dans c).
yee379
6
pprint.pformat()était sur cette page.
Gareth Latty
27
@Lattywayre - Tout le monde qui pose une question comme celle-ci n'a pas sauté la documentation. J'ai lu les mêmes documents et j'ai également manqué pformat. Sur stackoverflow, vous obtenez également parfois des gemmes de l'expérience d'autres personnes qui n'étaient pas du tout dans la documentation. Merci yee379 pour cette question.
Mnebuerquo

Réponses:

212

Utilisez pprint.pformatpour obtenir une chaîne, puis envoyez-la à votre infrastructure de journalisation.

from pprint import pformat
ds = [{'hello': 'there'}]
logging.debug(pformat(ds))
Robert
la source
11
Si vous ne supprimez pas ce code une fois le débogage terminé, vous devriez probablement le protéger avec "if Logger.isEnabledFor (logging.DEBUG):" pour éviter d'exécuter pformat lorsque vous n'utiliserez pas sa sortie: docs.python. org / 2 / library /…
Ed Brannin
1
@EdBrannin Est-ce que pformat ajoute autant de frais généraux qu'il vaut la peine d'ajouter les conditions à toutes les instructions du journal DEBUG?
undefinedvariable
2
@undefinedvariable Bonne question. Me-today veut me dire il y a 2 ans de générer des mesures de performance A / B.
Ed Brannin le
1
J'ai AttributeError: 'function' object has no attribute 'pformat'une idée pourquoi?
JinSnow
3
solution: j'avais besoin from pprint import pprint,pformat alorslogging.debug((pformat(stuff))
JinSnow
20

La solution ci-dessus ne m'a pas tout à fait permis car j'utilise également un formateur pour ajouter un nom et un nom de niveau lors de la journalisation. Cela a l'air un peu désordonné:

__main__    : DEBUG   : ['aaaaaaaaaaaaaaaaaaaa',
'bbbbbbbbbbbbbbbbbbbb',
'cccccccccccccccccccc',
'dddddddddddddddddddd']
__main__    : DEBUG   : Some other logging text

Il existe peut-être une solution plus élégante, mais celle-ci:

for line in pprint.pformat(ds).split('\n'):
    logging.debug(line)

produit quelque chose d'un peu plus agréable:

__main__    : DEBUG   : ['aaaaaaaaaaaaaaaaaaaa',
__main__    : DEBUG   :  'bbbbbbbbbbbbbbbbbbbb',
__main__    : DEBUG   :  'cccccccccccccccccccc',
__main__    : DEBUG   :  'dddddddddddddddddddd']
__main__    : DEBUG   : Some other logging text
Hywel Thomas
la source
14
Plus agréable pour la consommation humaine. Pas si génial si vous expédiez des journaux à logstash ou à des outils similaires et que vous souhaitez qu'un seul message multiligne soit envoyé sous forme d'un seul message.
Charles Duffy
5
y a-t-il un moyen d'imprimer assez au niveau du gestionnaire / formateur de la configuration de l'enregistreur? Cela semble être un cas d'utilisation valide pour imprimer sur la console, mais ne pas être formaté dans un fichier
jon_darkstar
@CharlesDuffy Existe-t-il un moyen simple de gérer les deux cas?
jtlz2
1
Ma solution a été de simplement ajouter un \ncaractère supplémentaire dans le pformat. Au moins de cette façon, le bloc est ensemble.
Ricekab