2013-11-04 16 views
7

Voglio accedere alcune informazioni di ogni singola richiesta di inviare a un server http impegnato in una forma formattata, modulo L'inizio creerebbe qualche cosa che non voglio:qual è il modo corretto di fare il log in file csv?

[I 131104 15:31:29 Sys:34] 

penso formato csv, ma non so come personalizzarlo, e pitone ottenuto modulo csv, ma letto il manuale

import csv 
with open('some.csv', 'w', newline='') as f: 
    writer = csv.writer(f) 
    writer.writerows(someiterable) 

poiché sarebbe aprire e chiudere un file ogni volta, ho paura in questo modo sarebbe rallentare l'intero server prestazioni, cosa potrei fare?

+1

È necessario utilizzare un'istanza di logging.Formatter con un formato che emetta righe csv. –

risposta

6

Basta usare il modulo logging di python.

È possibile regolare l'uscita nel modo desiderato; dare un'occhiata a Changing the format of displayed messages:

Per cambiare il formato che viene utilizzato per visualizzare i messaggi, è necessario specificare il formato che si desidera utilizzare:

import logging
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
logging.debug('This message should appear on the console')
logging.info('So should this')
logging.warning('And this, too')

e Formatters:

oggetti Formatter configurare le finali di ordine, la struttura, e il contenuto del messaggio di log.

Si può facilmente sostituire il : con un , per creare un file di output CSV-like.

Troverete un elenco degli attributi che è possibile utilizzare qui: LogRecord attributes.

0

Non penso che sia l'idea migliore, ma è fattibile e abbastanza semplice. Memorizza manualmente il registro. Memorizza le voci del registro in qualche posto e scriverle di volta in volta. Se si sa che il server sarà costantemente occupato, svuotare il buffer quando raggiunge alcune dimensioni. Se ci potrebbero essere grosse lacune nell'uso, direi che il nuovo thread (o processo migliore, controlla te stesso perché i thread fanno schifo e rallenti app) con il ciclo infinito (teoricamente ovviamente) di sleep/flush sarebbe una chiamata migliore. Inoltre, ricorda di creare una sorta di hook che svuota il buffer quando il server viene interrotto o fallisce (forse segnali? O semplicemente prova/eccetto la funzione principale - ci sono ancora più modi per farlo), così da non perdere un flush buffer dati all'uscita inattesa.

Ripeto: questa non è la migliore idea, è la prima cosa che mi è venuta in mente. Si consiglia di consultare le implementazioni di registrazione da Flask o da qualche altro framework webapp (anche AFAIR Flask ha una registrazione CSV).

1

Come suggerisce la pigrizia, è possibile modificare facilmente il delimitatore del registro in una virgola, producendo così un file CSV.

esempio di lavoro:

import logging 

# create logger 
lgr = logging.getLogger('logger name') 
lgr.setLevel(logging.DEBUG) # log all escalated at and above DEBUG 
# add a file handler 
fh = logging.FileHandler('path_of_your_log.csv') 
fh.setLevel(logging.DEBUG) # ensure all messages are logged to file 

# create a formatter and set the formatter for the handler. 
frmt = logging.Formatter('%(asctime)s,%(name)s,%(levelname)s,%(message)s') 
fh.setFormatter(frmt) 

# add the Handler to the logger 
lgr.addHandler(fh) 

# You can now start issuing logging statements in your code 
lgr.debug('a debug message') 
lgr.info('an info message') 
lgr.warn('A Checkout this warning.') 
lgr.error('An error writen here.') 
lgr.critical('Something very critical happened.') 
+2

c'è un modo per aggiungere una riga di intestazione CSV? (cioè una prima riga nel file di testo CSV contenente i nomi delle colonne?) – ycomp

+0

Sì, questo potrebbe essere quello che stai cercando: http://stackoverflow.com/questions/27840094/write-a-header-at -Ogni-logfile-che-è-creato-con-un-tempo-rotante-logger – ecoe

2

Sono d'accordo che è necessario utilizzare il modulo di registrazione, ma non si può davvero farlo correttamente con solo una stringa di formato come alcune delle altre risposte mostrano, come fanno non affrontare la situazione in cui si registra un messaggio che contiene una virgola.

Se è necessaria una soluzione che eviti correttamente caratteri speciali nel messaggio (o altri campi, suppongo), è necessario scrivere un formattatore personalizzato e impostarlo.

logger = logging.getLogger() 

formatter = MyCsvFormatter() 

handler = logging.FileHandler(filename, "w") 
handler.setFormatter(formatter) 
logger.addHandler(handler) 
logger.setLevel(level) 

Avrete ovviamente bisogno di implementare la classe MyCsvFormatter, che dovrebbe ereditare da logging.Formatter e sovrascrivere il metodo format()

class MyCsvFormatter(logging.Formatter): 
    def __init__(self): 
     fmt = "%(levelname)s,%(message)s" # Set a format that uses commas, like the other answers 
     super(MyCsvFormatter, self).__init__(fmt=fmt) 

    def format(self, record): 
     msg = record.getMessage() 
     # convert msg to a csv compatible string using your method of choice 
     record.msg = msg 
     return super(MyCsvFormatter, self).format(self, record) 

Nota: ho fatto qualcosa di simile prima, ma non hanno testato questo particolare esempio di codice

Per quanto riguarda facendo la fuga effettivo del messaggio, ecco un possibile approccio: Python - write data into csv format as string (not file)

Problemi correlati