2013-11-04 22 views
7

mag ich einige Informationen von jeder einzelnen Anforderung an einen langen HTTP-Server in einer formatierten Form senden loggen sein, ich will Verwendung Logmodul würde ein Ding nicht schaffen:Was ist der richtige Weg, um die CSV-Datei einzuloggen?

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

i von CSV-Format denken, aber ich weiß nicht, wie es zu gestalten, und python bekam csv-Modul, lesen, aber das Handbuch

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

da es würde öffnen und eine Datei jedes Mal schließen, ich auf diese Weise Angst habe, würde den ganzen Server verlangsamen Leistung, was könnte ich tun?

+1

Sie sollten eine logging.Formatter-Instanz mit einem Format verwenden, das CSV-Zeilen ausgibt. –

Antwort

6

Verwenden Sie einfach Pythons logging Modul.

Sie können die Ausgabe so anpassen, wie Sie möchten; einen Blick auf Changing the format of displayed messages:

Um das Format zu ändern, die Nachrichten anzuzeigen verwendet wird, müssen Sie das Format, das Sie verwenden möchten, angeben:

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')

und Formatters:

Formatter Objekte konfigurieren, dass die endgültige Ordnung, Struktur und Inhalt der Log-Nachricht.

können Sie bequem die : mit einem , ersetzen, um eine CSV-ähnliche Ausgabedatei zu erstellen.

Hier finden Sie eine Liste der Attribute, die Sie hier verwenden können: LogRecord attributes.

0

Ich denke nicht, dass das die beste Idee ist, aber es ist machbar und ziemlich einfach. Puffern Sie Ihr Protokoll manuell. Speichern Sie Protokolleinträge an einem bestimmten Ort und schreiben Sie sie von Zeit zu Zeit in die Datei. Wenn Sie wissen, dass Ihr Server ständig beschäftigt ist, leeren Sie den Puffer, wenn er eine gewisse Größe erreicht. Wenn es große Lücken in der Nutzung gibt, würde ich sagen, dass neue Thread (oder besser, überprüfen Sie selbst, warum Threads saugen und Apps verlangsamen) mit endlosen (theoretisch natürlich) Schleife von Schlaf/Flush wäre besser Anruf. Denken Sie auch daran, eine Art von Hook zu erstellen, der den Puffer löscht, wenn der Server unterbrochen wird oder ausfällt (vielleicht Signale? Oder einfach versuchen/außer Hauptfunktion - es gibt noch mehr Möglichkeiten), damit Sie nicht unplugged verlieren Pufferdaten bei unerwartetem Beenden.

Ich wiederhole - das ist nicht die beste Idee, es ist das erste, was mir in den Sinn kam. Vielleicht möchten Sie Logging-Implementierungen von Flask oder einem anderen Webapp-Framework konsultieren (AFAIR Flask hat auch CSV-Protokollierung).

1

Wie Faultier vorschlägt, können Sie das Trennzeichen des Protokolls leicht zu einem Komma bearbeiten und so eine CSV-Datei erzeugen.

Arbeitsbeispiel:

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

gibt es eine Möglichkeit, eine CSV-Kopfzeile hinzuzufügen? (zB eine erste Zeile in der CSV-Textdatei, die die Namen der Spalten enthält?) – ycomp

+0

Ja, das könnte das sein, wonach Sie suchen: http://stackoverflow.com/questions/27840094/write-a-header-at -jede-Logfile-das-erstellt-mit-einer-Zeit-rotierende-Logger – ecoe

2

Ich würde zustimmen, dass Sie das Protokollierungsmodul verwenden sollte, aber man kann nicht wirklich tun es richtig mit nur einem Formatstring wie einige der anderen Antworten zeigen, wie sie es tun Adressieren Sie nicht die Situation, in der Sie eine Nachricht protokollieren, die ein Komma enthält.

Wenn Sie eine Lösung benötigen, die ordnungsgemäß alle Sonderzeichen in der Nachricht (oder andere Felder, ich nehme an) entkommen, müssten Sie einen benutzerdefinierten Formatierer schreiben und festlegen.

logger = logging.getLogger() 

formatter = MyCsvFormatter() 

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

Sie werden offensichtlich die MyCsvFormatter Klasse implementieren müssen, die von logging.Formatter und außer Kraft setzt das Format() -Methode

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) 

Hinweis erben sollte: wie diese, bevor ich habe etwas getan, aber nicht dieses besondere Codebeispiel getestet

Soweit die tatsächliche Entkommen der Nachricht tun, hier ist ein möglicher Ansatz: Python - write data into csv format as string (not file)

Verwandte Themen