cevi/automatic_walk-time_tables

Tool is currently broken

Closed this issue · 7 comments

When I upload the any GPX track, the final button "Generieren lassen" currently does nothing. The POST request never gets a response. Is your backend service down? This has been the case since at least last Saturday.

An example GPX track (though I tried with several different ones, none worked):
oproute.zip

Thanks @carlobeltrame for pointing it out. I restarted the backed service, the tool should work again.

Nevertheless, we should investigate root of the crash. In the following the last log of the backed container:

[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Der Export wurde gestartet.
[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Benötigte Zeit zum Berechnen der Marschzeittabelle: 0.33s
[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Route wurde berechnet.
[INFO] way_points = 14875.869369292206 | distances = 14875.869369292206
Process Process-12:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/multiprocessing/process.py", line 315, in _bootstrap
    self.run()
  File "/usr/local/lib/python3.9/multiprocessing/process.py", line 108, in run
    self._target(*self._args, **self._kwargs)
  File "/app/automatic_walk_time_tables/walk_time_table/walk_table.py", line 70, in _plot_elevation_profile
    plt.savefig(file_name + '_elevation_profile.png', dpi=750)
  File "/usr/local/lib/python3.9/site-packages/matplotlib/pyplot.py", line 979, in savefig
    res = fig.savefig(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/matplotlib/figure.py", line 3046, in savefig
    self.canvas.print_figure(fname, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/matplotlib/backend_bases.py", line 2319, in print_figure
    result = print_method(
  File "/usr/local/lib/python3.9/site-packages/matplotlib/backend_bases.py", line 1648, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/matplotlib/_api/deprecation.py", line 415, in wrapper
    return func(*inner_args, **inner_kwargs)
  File "/usr/local/lib/python3.9/site-packages/matplotlib/backends/backend_agg.py", line 541, in print_png
    mpl.image.imsave(
  File "/usr/local/lib/python3.9/site-packages/matplotlib/image.py", line 1675, in imsave
    image.save(fname, **pil_kwargs)
  File "/usr/local/lib/python3.9/site-packages/PIL/Image.py", line 2317, in save
    fp = builtins.open(filename, "w+b")
FileNotFoundError: [Errno 2] No such file or directory: 'output/16b0a847617742828c50f2ca8074f824/MF Berg 22 / Gruppe Hide_elevation_profile.png'
[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Benötigte Zeit zum Zeichnen des Höhenprofils: 0.35s
[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Höhenprofil wurde erstellt.
[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Benötigte Zeit um die Karten-Nummern zu berechnen: 0.01s
[Level 200] [uuid=16b0a847617742828c50f2ca8074f824] Der Export ist fehlgeschlagen. Ein unbekannter Fehler ist aufgetreten!
Exception in thread Thread-15:
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/threading.py", line 980, in _bootstrap_inner
    self.run()
  File "/usr/local/lib/python3.9/threading.py", line 917, in run
    self._target(*self._args, **self._kwargs)
  File "/app/app.py", line 44, in create_export
    generator.run()
  File "/app/automatic_walk_time_tables/generator.py", line 37, in run
    self.__log_runtime(self.__create_files, "Benötigte Zeit für Export")
  File "/app/automatic_walk_time_tables/generator.py", line 118, in __log_runtime
    results = function(*args, **kwargs)
  File "/app/automatic_walk_time_tables/generator.py", line 90, in __create_files
    self.__log_runtime(create_walk_table, "Benötigte Zeit zum Erstellen der Excel-Tabelle",
  File "/app/automatic_walk_time_tables/generator.py", line 118, in __log_runtime
    results = function(*args, **kwargs)
  File "/app/automatic_walk_time_tables/walk_time_table/walk_table.py", line 148, in create_walk_table
    xfile.save(file_name + '_Marschzeittabelle.xlsx')
  File "/usr/local/lib/python3.9/site-packages/openpyxl/workbook/workbook.py", line 407, in save
    save_workbook(self, filename)
  File "/usr/local/lib/python3.9/site-packages/openpyxl/writer/excel.py", line 291, in save_workbook
    archive = ZipFile(filename, 'w', ZIP_DEFLATED, allowZip64=True)
  File "/usr/local/lib/python3.9/zipfile.py", line 1248, in __init__
    self.fp = io.open(file, filemode)
FileNotFoundError: [Errno 2] No such file or directory: 'output/16b0a847617742828c50f2ca8074f824/MF Berg 22 / Gruppe Hide_Marschzeittabelle.xlsx'
[Level 200] [uuid=a6db06cfd9fb4bee9d57a968ca80efd9] Export wird vorbereitet.
usage: gunicorn [-h] -fn <file_path> [-v <speed>] [-s <scale>] [-t <time>]
                [-n <name>] [--output_directory OUTPUT_DIRECTORY]
                [--log-level <log-level>]
                [--print-api-base-url PRINT_API_BASE_URL]
                [--create-map-pdfs CREATE_MAP_PDFS]
                [--create-excel CREATE_EXCEL]
                [--create-elevation-profile CREATE_ELEVATION_PROFILE]
                [--open-figure OPEN_FIGURE]
                [--legend-position LEGEND_POSITION] [--map-layers MAP_LAYERS]
                [--list-of-pois LIST_OF_POIS]
gunicorn: error: unrecognized arguments: 608574,184588 610057,185183 612012,185733 613360,184247
Exception in worker
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 83, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 60, in run
    self.future.set_exception(exc)
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 555, in set_exception
    self._invoke_callbacks()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 330, in _invoke_callbacks
    callback(self)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 238, in finish_request
    (keepalive, conn) = fs.result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 439, in result
    return self.__get_result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 391, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle
    keepalive = self.handle_request(req, conn)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1517, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1503, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/app/app.py", line 113, in create_map
    args = parser.parse_args(['-fn', file_name, '--output_directory', output_directory, '--print-api-base-url',
  File "/usr/local/lib/python3.9/argparse.py", line 1828, in parse_args
    self.error(msg % ' '.join(argv))
  File "/usr/local/lib/python3.9/argparse.py", line 2582, in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
  File "/usr/local/lib/python3.9/argparse.py", line 2569, in exit
    _sys.exit(status)
SystemExit: 2
[Level 200] [uuid=ca6669bf202241dfb35282593a2a5eb1] Export wird vorbereitet.
usage: gunicorn [-h] -fn <file_path> [-v <speed>] [-s <scale>] [-t <time>]
                [-n <name>] [--output_directory OUTPUT_DIRECTORY]
                [--log-level <log-level>]
                [--print-api-base-url PRINT_API_BASE_URL]
                [--create-map-pdfs CREATE_MAP_PDFS]
                [--create-excel CREATE_EXCEL]
                [--create-elevation-profile CREATE_ELEVATION_PROFILE]
                [--open-figure OPEN_FIGURE]
                [--legend-position LEGEND_POSITION] [--map-layers MAP_LAYERS]
                [--list-of-pois LIST_OF_POIS]
gunicorn: error: unrecognized arguments: 608574,184588 610057,185183 612012,185733 613360,184247
Exception in worker
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 83, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 60, in run
    self.future.set_exception(exc)
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 555, in set_exception
    self._invoke_callbacks()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 330, in _invoke_callbacks
    callback(self)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 238, in finish_request
    (keepalive, conn) = fs.result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 439, in result
    return self.__get_result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 391, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle
    keepalive = self.handle_request(req, conn)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1517, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1503, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/app/app.py", line 113, in create_map
    args = parser.parse_args(['-fn', file_name, '--output_directory', output_directory, '--print-api-base-url',
  File "/usr/local/lib/python3.9/argparse.py", line 1828, in parse_args
    self.error(msg % ' '.join(argv))
  File "/usr/local/lib/python3.9/argparse.py", line 2582, in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
  File "/usr/local/lib/python3.9/argparse.py", line 2569, in exit
    _sys.exit(status)
SystemExit: 2

Could be because of the slash in the filename..? output/16b0a847617742828c50f2ca8074f824/MF Berg 22 / Gruppe Hide_elevation_profile.png

I agree, this would make sense.
Potential fixes:

  • Use a UUID as name?
  • Encode special characters ( search-replace /, ", '. ?, (, ), etc. by a dash?

Also, you could consider adding monitoring / alerting to your deployment so that you'd be notified when the app is down. Or use something like sentry.io to gather all frontend and backend errors your tool produces in a single place. Sentry has excellent integrations for lots of programming languages and frameworks, including python and Angular.

I agree, this would make sense. Potential fixes:

  • Use a UUID as name?
  • Encode special characters ( search-replace /, ", '. ?, (, ), etc. by a dash?

This is indeed a bug. You can reproduce it by choosing the route's name (a tag inside the GPX file and not the filename itself) such that it contains a slash or any other special character. As @maede97 has proposed this could be fixed by replacing special characters with a dash. A fix is implemented in 1b53c0e.

There must be a second bug

However, this crashed only the current execution (resulting in Der Export ist fehlgeschlagen. Ein unbekannter Fehler ist aufgetreten! (Fehler)) and not the entire backend server.

We must have a look at:

[Level 200] [uuid=ca6669bf202241dfb35282593a2a5eb1] Export wird vorbereitet.
usage: gunicorn [-h] -fn <file_path> [-v <speed>] [-s <scale>] [-t <time>]
                [-n <name>] [--output_directory OUTPUT_DIRECTORY]
                [--log-level <log-level>]
                [--print-api-base-url PRINT_API_BASE_URL]
                [--create-map-pdfs CREATE_MAP_PDFS]
                [--create-excel CREATE_EXCEL]
                [--create-elevation-profile CREATE_ELEVATION_PROFILE]
                [--open-figure OPEN_FIGURE]
                [--legend-position LEGEND_POSITION] [--map-layers MAP_LAYERS]
                [--list-of-pois LIST_OF_POIS]
gunicorn: error: unrecognized arguments: 608574,184588 610057,185183 612012,185733 613360,184247
Exception in worker
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 83, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 60, in run
    self.future.set_exception(exc)
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 555, in set_exception
    self._invoke_callbacks()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 330, in _invoke_callbacks
    callback(self)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 238, in finish_request
    (keepalive, conn) = fs.result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 439, in result
    return self.__get_result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 391, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle
    keepalive = self.handle_request(req, conn)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1517, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1503, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/app/app.py", line 113, in create_map
    args = parser.parse_args(['-fn', file_name, '--output_directory', output_directory, '--print-api-base-url',
  File "/usr/local/lib/python3.9/argparse.py", line 1828, in parse_args
    self.error(msg % ' '.join(argv))
  File "/usr/local/lib/python3.9/argparse.py", line 2582, in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
  File "/usr/local/lib/python3.9/argparse.py", line 2569, in exit
    _sys.exit(status)
SystemExit: 2

Also, you could consider adding monitoring / alerting to your deployment so that you'd be notified when the app is down. Or use something like sentry.io to gather all frontend and backend errors your tool produces in a single place. Sentry has excellent integrations for lots of programming languages and frameworks, including python and Angular.

Our tool is running on a docker cluster, we are building up this infrastructure for cevi.tools. In the long term, there are plans to include monitoring, logging and alerting for all containers running on the cluster.

Today morning it crashed again:

[Level 200] [uuid=f8ea6bfd1fd3481d9714573cb4c6f542] Export wird vorbereitet.
Level 200:app:Export wird vorbereitet.
usage: gunicorn [-h] -fn <file_path> [-v <speed>] [-s <scale>] [-t <time>]
                [-n <name>] [--output_directory OUTPUT_DIRECTORY]
                [--log-level <log-level>]
                [--print-api-base-url PRINT_API_BASE_URL]
                [--create-map-pdfs CREATE_MAP_PDFS]
                [--create-excel CREATE_EXCEL]
                [--create-elevation-profile CREATE_ELEVATION_PROFILE]
                [--open-figure OPEN_FIGURE]
                [--legend-position LEGEND_POSITION] [--map-layers MAP_LAYERS]
                [--list-of-pois LIST_OF_POIS]
gunicorn: error: unrecognized arguments: 612008,185749
CRITICAL:concurrent.futures:Exception in worker
Traceback (most recent call last):
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 83, in _worker
    work_item.run()
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 60, in run
    self.future.set_exception(exc)
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 555, in set_exception
    self._invoke_callbacks()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 330, in _invoke_callbacks
    callback(self)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 238, in finish_request
    (keepalive, conn) = fs.result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 439, in result
    return self.__get_result()
  File "/usr/local/lib/python3.9/concurrent/futures/_base.py", line 391, in __get_result
    raise self._exception
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 271, in handle
    keepalive = self.handle_request(req, conn)
  File "/usr/local/lib/python3.9/site-packages/gunicorn/workers/gthread.py", line 323, in handle_request
    respiter = self.wsgi(environ, resp.start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2091, in __call__
    return self.wsgi_app(environ, start_response)
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 2073, in wsgi_app
    response = self.full_dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1517, in full_dispatch_request
    rv = self.dispatch_request()
  File "/usr/local/lib/python3.9/site-packages/flask/app.py", line 1503, in dispatch_request
    return self.ensure_sync(self.view_functions[rule.endpoint])(**req.view_args)
  File "/app/app.py", line 113, in create_map
    args = parser.parse_args(['-fn', file_name, '--output_directory', output_directory, '--print-api-base-url',
  File "/usr/local/lib/python3.9/argparse.py", line 1828, in parse_args
    self.error(msg % ' '.join(argv))
  File "/usr/local/lib/python3.9/argparse.py", line 2582, in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
  File "/usr/local/lib/python3.9/argparse.py", line 2569, in exit
    _sys.exit(status)
SystemExit: 2