Dateien herunterladen und in einem Verzeichnis ablegen
Ich bin immer noch beim Logging. Leider verstehe ich die Details nicht, obwohl ich schon Stunden lese und google bemühe. Bitte erklärt doch einem Erstklässler wie ich das Logging in meinen Programm richtig zum Laufen bringe. Ich bekomme immer nur die Meldungen aus den Zeilen unterhalb von # application code und nicht die Meldung aus der Funktion fetch_whole_year. In dem Logfile sollen auch die Informationen über den erfolgreichen Download der anderen Dateien. Nicht nur die defekten, oder nicht vorhandenen Dateien.
Code: Alles auswählen
def initialize_logger():
logfile_name = generate_logfile()
print(logfile_name)
ensure_logdir_exists(logfile_name)
logger = logging.getLogger('Data download')
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(logfile_name)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
# application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
Code: Alles auswählen
def fetch_whole_year(symbol, year):
for symbol in symbol:
last_week = datetime.date(year, 12, 31).isocalendar()[1]
for week in range(1, last_week + 1):
try:
if not exists_file(symbol, year, week):
data = pull_file(symbol, year, week)
print_data_length(data)
save_file(symbol, year, week, data)
except Exception as e:
logging.exception(e)
else:
print("File for {}/{}/{} already fetched.".format(
symbol, year, week)
)
Code: Alles auswählen
Traceback (most recent call last):
File "TickDataCsv.py", line 103, in fetch_whole_year
data = pull_file(symbol, year, week)
File "TickDataCsv.py", line 55, in pull_file
response = urllib2.urlopen(url)
File "/usr/lib64/python2.7/urllib2.py", line 154, in urlopen
return opener.open(url, data, timeout)
File "/usr/lib64/python2.7/urllib2.py", line 437, in open
response = meth(req, response)
File "/usr/lib64/python2.7/urllib2.py", line 550, in http_response
'http', request, response, code, msg, hdrs)
File "/usr/lib64/python2.7/urllib2.py", line 475, in error
return self._call_chain(*args)
File "/usr/lib64/python2.7/urllib2.py", line 409, in _call_chain
result = func(*args)
File "/usr/lib64/python2.7/urllib2.py", line 558, in http_error_default
raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
HTTPError: HTTP Error 404: Not Found
ERROR:root:HTTP Error 404: Not Found
Danke für die Antwort. Das habe ich mittlerweile auch herausgefunden. Ich brauche ein Beispielprogramm bei dem ich einmal sehe, wie das Logging richtig eingesetzt wird. Das heißt ich erstelle die Lognachrichten selbst?
Sicherlich hast du dir schon die offizielle Dokumentation zu Logging samt Beispielen angeschaut, bevor du hier Grundsätzliches erfragst?aaron hat geschrieben:Ich brauche ein Beispielprogramm bei dem ich einmal sehe, wie das Logging richtig eingesetzt wird.
https://docs.python.org/3.6/howto/logging.html
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
Ich beschäftige mich immer noch mit dem Logging in meinem Programm. Ich möchte euch bitten mir die fehlenden Zeilen Code einmal zu schreiben. Ich verbringe mit diesem Teil des Programmes schon viele Tage. Ich finde kein Beispiel. Auch die Dokumentation hilft mir nicht, weil ich nicht weiß, wie das Logging richtig eingebaut wird.
Aufgerufen wird das Logging in der Funktion main()
Code: Alles auswählen
def initialize_logger():
logfile_name = generate_logfile()
print(logfile_name)
ensure_logdir_exists(logfile_name)
logger = logging.getLogger('Data download')
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(logfile_name)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
# application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
Code: Alles auswählen
def fetch_whole_year(symbol, year):
for symbol in symbol:
last_week = datetime.date(year, 12, 31).isocalendar()[1]
for week in range(1, last_week + 1):
try:
if not exists_file(symbol, year, week):
data = pull_file(symbol, year, week)
print_data_length(data)
save_file(symbol, year, week, data)
except Exception as e:
logging.exception(e)
else:
print("File for {}/{}/{} already fetched.".format(
symbol, year, week)
)
Code: Alles auswählen
def main():
initialize_logger()
Was funktioniert denn nicht? Fuer mich geht dein code (nachdem ich etwas drumrum gebaut habe was du nicht zeigst)
Bekomme ich eine Datei mit Eintraegen, so wie erwartet.
In deiner fetch_whole_year Funktion rufst du kein logging auf, nur so am Rande. Insofern kann da dann auch nichts geloggt werden.
Code: Alles auswählen
import os
import logging
def generate_logfile():
return "/tmp/test-foo/logfile.log"
def ensure_logdir_exists(logfile_name):
dir = os.path.dirname(logfile_name)
if not os.path.exists(dir):
os.makedirs(dir)
def initialize_logger():
logfile_name = generate_logfile()
print(logfile_name)
ensure_logdir_exists(logfile_name)
logger = logging.getLogger('Data download')
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(logfile_name)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
# application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message')
def main():
initialize_logger()
if __name__ == '__main__':
main()
In deiner fetch_whole_year Funktion rufst du kein logging auf, nur so am Rande. Insofern kann da dann auch nichts geloggt werden.
Danke für die Antworten. Das ist ja genau meine Frage, wie rufe ich das Logging in der Funktion fetch_whole-year auf? Hier noch einmal die Funktionen, die genau das machen was sie sollen. Das Ergebnis ist ein Logfile mit folgendem Inhalt. Ich möchte, dass die Fehlermeldungen, wie die Datei ist auf dem Server nicht vorhanden, oder die Datei ist beschädigt.
Code: Alles auswählen
2017-04-26 15:39:35,141 - Data download - DEBUG - debug message
2017-04-26 15:39:35,141 - Data download - INFO - info message
2017-04-26 15:39:35,141 - Data download - WARNING - warn message
2017-04-26 15:39:35,141 - Data download - ERROR - error message
2017-04-26 15:39:35,141 - Data download - CRITICAL - critical message
Code: Alles auswählen
def generate_logfile():
return os.path.join("log", str(datetime.date.today())+'.log')
def ensure_logdir_exists(logfilename):
if not os.path.exists(os.path.dirname(logfilename)):
os.makedirs(os.path.dirname(logfilename))
def initialize_logger():
logfile_name = generate_logfile()
print(logfile_name)
ensure_logdir_exists(logfile_name)
logger = logging.getLogger('Data download')
logger.setLevel(logging.DEBUG)
handler = logging.FileHandler(logfile_name)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(message)s'
)
handler.setFormatter(formatter)
logger.addHandler(handler)
# application' code
logger.debug('debug message')
logger.info('info message')
logger.warn('warn message')
logger.error('error message')
logger.critical('critical message'
Der Trick ist das getLogger mit dem gleichen Namen immer den gleichen Logger zurueckgibt. Der ist an anderer Stelle (also initialize_logger) konfiguriert worden, aber benutzen kannst du ihn ueberall mit
Ueblicherweise verwendet man stattdessen das hier https://docs.python.org/2/howto/logging ... g-tutorial beschriebene
Und statt in initialise_logger einen Namen anzugeben, machst du nur "logger = logging.getLogger()", womit du den root-logger bekommst. Alle anderen Logger mit Namen wie "mein.package.submodul" delegieren immer weiter nach oben, bis zur Wurzel.
Code: Alles auswählen
logging.getLogger("Data download").info("text")
Code: Alles auswählen
# modul-global!
logger = logging.getLogger(__name__)
Der Trick ist das getLogger mit dem gleichen Namen immer den gleichen Logger zurueckgibt. Der ist an anderer Stelle (also initialize_logger) konfiguriert worden, aber benutzen kannst du ihn ueberall mit
Ueblicherweise verwendet man stattdessen das hier https://docs.python.org/2/howto/logging ... g-tutorial beschriebene
Und statt in initialise_logger einen Namen anzugeben, machst du nur "logger = logging.getLogger()", womit du den root-logger bekommst. Alle anderen Logger mit Namen wie "mein.package.submodul" delegieren immer weiter nach oben, bis zur Wurzel.
Code: Alles auswählen
logging.getLogger("Data download").info("text")
Code: Alles auswählen
# modul-global!
logger = logging.getLogger(__name__)
Als Ergebnis möchte ich eine Ausgabe wie folgt haben:
File for AUDJPY/2017/1 already fetched.
File for AUDJPY/2017/2 already fetched.
File for AUDJPY/2017/3 already fetched.
File for AUDJPY/2017/4 already fetched.
File for AUDJPY/2017/5 already fetched.
Das Logging muß ja in der Schleife aufgerufen werden.
1. wenn die Datei nicht vorhanden, oder beschädigt ist.
2. wenn die Datei schon heruntergeladen wurde.
Der Inhalt des Logfiles sieht so aus:
2017-04-26 17:45:21,064 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,140 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,215 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,300 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,381 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,470 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,559 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,636 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,736 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,823 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,921 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,006 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,086 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,179 - Data download - ERROR - HTTP Error 404: Not Found
ERROR - HTTP Error 404: Not Found ist ja richtig. Nur möchte ich wissen welche Datei nicht vorhanden, oder beschädigt ist.
Hier noch einmal die Funktion. So schwer kann das doch nicht sein. Das HOWTO bringt mich nicht weiter, weil ich nicht erkennen kann, wie ich was in der Schleife aufrufe.
File for AUDJPY/2017/1 already fetched.
File for AUDJPY/2017/2 already fetched.
File for AUDJPY/2017/3 already fetched.
File for AUDJPY/2017/4 already fetched.
File for AUDJPY/2017/5 already fetched.
Das Logging muß ja in der Schleife aufgerufen werden.
1. wenn die Datei nicht vorhanden, oder beschädigt ist.
2. wenn die Datei schon heruntergeladen wurde.
Der Inhalt des Logfiles sieht so aus:
2017-04-26 17:45:21,064 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,140 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,215 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,300 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,381 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,470 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,559 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,636 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,736 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,823 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:21,921 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,006 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,086 - Data download - ERROR - HTTP Error 404: Not Found
2017-04-26 17:45:22,179 - Data download - ERROR - HTTP Error 404: Not Found
ERROR - HTTP Error 404: Not Found ist ja richtig. Nur möchte ich wissen welche Datei nicht vorhanden, oder beschädigt ist.
Hier noch einmal die Funktion. So schwer kann das doch nicht sein. Das HOWTO bringt mich nicht weiter, weil ich nicht erkennen kann, wie ich was in der Schleife aufrufe.
Code: Alles auswählen
def fetch_whole_year(symbol, year):
for symbol in symbol:
last_week = datetime.date(year, 12, 31).isocalendar()[1]
for week in range(1, last_week + 1):
try:
if not exists_file(symbol, year, week):
data = pull_file(symbol, year, week)
print_data_length(data)
save_file(symbol, year, week, data)
except Exception as e:
logging.getLogger("Data download").error(e)
else:
print("File for {}/{}/{} already fetched.".format(
symbol, year, week)
)
@aaron: so
Code: Alles auswählen
import logging
logger = logging.getLogger('Data download')
def fetch_whole_year(symbol, year):
for symbol in symbol:
last_week = datetime.date(year, 12, 31).isocalendar()[1]
for week in range(1, last_week + 1):
try:
if not exists_file(symbol, year, week):
data = pull_file(symbol, year, week)
print_data_length(data)
save_file(symbol, year, week, data)
except Exception:
logger.exception("while downloading {}/{}/{}".format(symbol, year, week))
else:
logger.info("File for {}/{}/{} already fetched.".format(symbol, year, week))
def initialize_logger():
logfile_name = generate_logfile()
ensure_logdir_exists(logfile_name)
logging.basicConfig(filename=logfile_name, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', level=logging.DEBUG)
@aaron: wenn Du am aktuellen Datum aufhören willst, dann prüf einfach auf das aktuelle Datum:
Code: Alles auswählen
last_day = min(datetime.date(year, 12, 31), datetime.date.today())
new_year, last_week, _ = day.isocalendar()
if new_year > year:
last_week = 52
elif new_year < year:
return
Ich möchte den Codeschnipsel als Funktion einbauen.
Ich bekomme folgende Fehlermeldung:
Ich wollte die Funktion dann in der Funktion fetch_whole-year aufrufen.
Code: Alles auswählen
def check_date():
last_day = min(datetime.date(year, 12, 31), datetime.date.today())
new_year, last_week, _ = day.isocalendar()
if new_year > year:
last_week = 52
elif new_year < year:
return
Code: Alles auswählen
TickDataCsv.py|91 col 1 error| E0602 undefined name 'year' [pyflakes]
TickDataCsv.py|91 col 1 error| W0612 local variable 'last_day' is assigned to but never used [pyflakes]
TickDataCsv.py|92 col 1 error| E0602 undefined name 'day' [pyflakes]
TickDataCsv.py|93 col 1 error| E0602 undefined name 'year' [pyflakes]
TickDataCsv.py|94 col 1 error| W0612 local variable 'last_week' is assigned to but never used [pyflakes]
TickDataCsv.py|95 col 1 error| E0602 undefined name 'year' [pyflakes]
Code: Alles auswählen
def fetch_whole_year(symbol, year):
for symbol in symbol:
check_date()
last_week = datetime.date(year, 12, 31).isocalendar()[1]
for week in range(1, last_week + 1):
try:
if not exists_file(symbol, year, week):
data = pull_file(symbol, year, week)
print_data_length(data)
save_file(symbol, year, week, data)
except Exception:
logger.exception("while downloading {}/{}/{}".format(
symbol, year, week)
)
else:
logger.info("File for {}/{}/{} already fetched.".format(
symbol, year, week)
)
Ich versuche schon lange die Funktionen zu begreifen. Hier meine erste Frage. Als Parameter übergebe ich year und day, weil ich aktuelle Datum prüfen möchte. Ist 2017 > 2016, dann ist die letzte Woche die 52. Kalenderwoche. Was ist bei einem Jahr mit 53 Kalenderwochen? Ist das neue Jahr < Jahr dann return. Kann mir bitte jemand erklären wie diese Funktion richtig funktioniert, woher die Parameter kommen und wie diese richtig an die nächste Funktion übergeben werden.
Als Fehlermeldung bekomme ich
Code: Alles auswählen
def check_date(year, day):
last_day = min(datetime.date(year, 12, 31), datetime.date.today())
new_year, last_week, _ = day.isocalendar()
if new_year > year:
last_week = 52
elif new_year < year:
return
Code: Alles auswählen
TickDataCsv.py|91 col 1 error| W0612 local variable 'last_day' is assigned to but never used [pyflakes]
TickDataCsv.py|94 col 1 error| W0612 local variable 'last_week' is assigned to but never used
Ich habe die Diskussion nicht verfolgt. Möglicherweise macht es Sinn die Diskussionen (z. B. Logging-Problem) jeweils in neue Threads zu packen, so dass kleinere Einheiten (Diskussionnen) entstehen und man das später mittels Foren-Suche noch mal nutzen kann.
Zu den einzelnen Zeilen:
1. Du definierst eine Funktion check_date, die die beiden Parameter year und day erwartet.
2. Du ermittelst den last_day als Minimum zweier Daten, arbeitest in der Funktion aber nicht mehr (!) mit dieser Variable, was die Fehlermeldung 1 moniert.
3. Du bestimmst die Variablen new_year und last_week, nutzt aber die Variable last_week nicht mehr in der Funktion. Fehlermeldung 2. Ein echter Fehler, der zu einem Programmabbruch führen sollte, ist das beides nicht.
4. Du prüfst, ob das new_year größer als der Wert der Variable year ist und (5.) weist der Variablen last_week in diesem Fall den Wert 52 zu. Du verwendest diesen Wert in der Funktion sonst nicht mehr.
6. Ist new_year kleiner als year, dann machst du einen Rückgabewert ohne etwas zurückzugeben. Der Rückgabewert ist deshalb None.
Bei den Funktionen musst du verstehen, dass alles, was in der Funktion definiert und berechnet wird, dort bleibt (!), wenn es nicht zurückgegeben wird. Die Zuweisung in Zeile 5 z. B. ist wirkungslos, weil du damit weder weiterrechnest, noch etwas irgendwo veränderst (z. B. Prozedur), noch etwas zurückgibst.
Ich sehe nicht, dass die Funktion etwas leistet.
Code: Alles auswählen
def check_date(year, day):
last_day = min(datetime.date(year, 12, 31), datetime.date.today())
new_year, last_week, _ = day.isocalendar()
if new_year > year:
last_week = 52
elif new_year < year:
return
1. Du definierst eine Funktion check_date, die die beiden Parameter year und day erwartet.
2. Du ermittelst den last_day als Minimum zweier Daten, arbeitest in der Funktion aber nicht mehr (!) mit dieser Variable, was die Fehlermeldung 1 moniert.
3. Du bestimmst die Variablen new_year und last_week, nutzt aber die Variable last_week nicht mehr in der Funktion. Fehlermeldung 2. Ein echter Fehler, der zu einem Programmabbruch führen sollte, ist das beides nicht.
4. Du prüfst, ob das new_year größer als der Wert der Variable year ist und (5.) weist der Variablen last_week in diesem Fall den Wert 52 zu. Du verwendest diesen Wert in der Funktion sonst nicht mehr.
6. Ist new_year kleiner als year, dann machst du einen Rückgabewert ohne etwas zurückzugeben. Der Rückgabewert ist deshalb None.
Bei den Funktionen musst du verstehen, dass alles, was in der Funktion definiert und berechnet wird, dort bleibt (!), wenn es nicht zurückgegeben wird. Die Zuweisung in Zeile 5 z. B. ist wirkungslos, weil du damit weder weiterrechnest, noch etwas irgendwo veränderst (z. B. Prozedur), noch etwas zurückgibst.
Ich sehe nicht, dass die Funktion etwas leistet.