Added route to download logfile
This commit is contained in:
parent
d54a35e197
commit
63c0492022
2 changed files with 33 additions and 35 deletions
|
|
@ -1,10 +1,11 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
|
|
||||||
from flask import (
|
from flask import (
|
||||||
Flask, render_template, jsonify)
|
Flask, render_template, jsonify, send_file)
|
||||||
|
|
||||||
from flask.logging import default_handler
|
from flask.logging import default_handler
|
||||||
from serial import SerialException
|
from serial import SerialException
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
from flask_cors import CORS
|
from flask_cors import CORS
|
||||||
|
|
||||||
|
|
@ -16,6 +17,8 @@ from openflexure_microscope.camera.pi import StreamingCamera
|
||||||
from openflexure_microscope.stage.sanga import SangaStage
|
from openflexure_microscope.stage.sanga import SangaStage
|
||||||
from openflexure_microscope.stage.mock import MockStage
|
from openflexure_microscope.stage.mock import MockStage
|
||||||
|
|
||||||
|
from openflexure_microscope.config import USER_CONFIG_DIR
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import logging
|
import logging
|
||||||
import sys, os
|
import sys, os
|
||||||
|
|
@ -23,20 +26,34 @@ import sys, os
|
||||||
# Handle logging
|
# Handle logging
|
||||||
is_gunicorn = "gunicorn" in os.environ.get("SERVER_SOFTWARE", "")
|
is_gunicorn = "gunicorn" in os.environ.get("SERVER_SOFTWARE", "")
|
||||||
|
|
||||||
|
DEFAULT_LOGFILE = os.path.join(USER_CONFIG_DIR, 'openflexure_microscope.log')
|
||||||
|
print(DEFAULT_LOGFILE)
|
||||||
|
|
||||||
if (__name__ == "__main__") or (not is_gunicorn):
|
if (__name__ == "__main__") or (not is_gunicorn):
|
||||||
# If imported, but not by gunicorn
|
# If imported, but not by gunicorn
|
||||||
print("Letting sys handle logs")
|
print("Letting sys handle logs")
|
||||||
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
logging.basicConfig(stream=sys.stderr, level=logging.DEBUG)
|
||||||
else:
|
else:
|
||||||
print("Letting gunicorn handle logs")
|
# Direct standard Python logging to file and console
|
||||||
# If running in gunicorn, let gunicorn handle logging
|
|
||||||
root = logging.getLogger()
|
root = logging.getLogger()
|
||||||
|
error_formatter = logging.Formatter("[%(asctime)s] [%(threadName)s] [%(levelname)s] %(message)s")
|
||||||
gunicorn_logger = logging.getLogger('gunicorn.error')
|
|
||||||
for handler in gunicorn_logger.handlers:
|
rotating_logfile = logging.handlers.RotatingFileHandler(
|
||||||
|
DEFAULT_LOGFILE,
|
||||||
|
maxBytes=1000000,
|
||||||
|
backupCount=7
|
||||||
|
)
|
||||||
|
|
||||||
|
error_handlers = [
|
||||||
|
rotating_logfile,
|
||||||
|
logging.StreamHandler()
|
||||||
|
]
|
||||||
|
|
||||||
|
for handler in error_handlers:
|
||||||
|
handler.setFormatter(error_formatter)
|
||||||
root.addHandler(handler)
|
root.addHandler(handler)
|
||||||
|
|
||||||
root.setLevel(gunicorn_logger.level)
|
root.setLevel(logging.getLogger("gunicorn.error").level)
|
||||||
|
|
||||||
# Create a dummy microscope object, with no hardware attachments
|
# Create a dummy microscope object, with no hardware attachments
|
||||||
api_microscope = Microscope(None, None)
|
api_microscope = Microscope(None, None)
|
||||||
|
|
@ -119,6 +136,14 @@ def routes():
|
||||||
"""
|
"""
|
||||||
return jsonify(list_routes(app))
|
return jsonify(list_routes(app))
|
||||||
|
|
||||||
|
@app.route('/log')
|
||||||
|
def err_log():
|
||||||
|
"""
|
||||||
|
Most recent 1mb of log output
|
||||||
|
"""
|
||||||
|
timestamp = datetime.now().strftime("%Y-%m-%d_%H-%M-%S")
|
||||||
|
return send_file(DEFAULT_LOGFILE, as_attachment=True, attachment_filename='openflexure_microscope_{}.log'.format(timestamp))
|
||||||
|
|
||||||
# Automatically clean up microscope at exit
|
# Automatically clean up microscope at exit
|
||||||
def cleanup():
|
def cleanup():
|
||||||
global api_microscope
|
global api_microscope
|
||||||
|
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
from openflexure_stage import OpenFlexureStage
|
|
||||||
|
|
||||||
from openflexure_microscope.lock import StrictLock
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
|
|
||||||
class Stage(OpenFlexureStage):
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Subclass of :py:class:`openflexure_stage.stage.OpenFlexureStage`,
|
|
||||||
adding an instance of :py:class:`openflexure_microscope.lock.StrictLock` to regulate access.
|
|
||||||
"""
|
|
||||||
self.lock = StrictLock(timeout=2) #: :py:class:`openflexure_microscope.lock.StrictLock`: Strict lock controlling thread access to camera hardware
|
|
||||||
|
|
||||||
OpenFlexureStage.__init__(self, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def _move_rel_nobacklash(self, *args, **kwargs):
|
|
||||||
"""
|
|
||||||
Overrides :py:function:`openflexure_stage.stage.OpenFlexureStage._move_rel_nobacklash` to acquire lock first.
|
|
||||||
"""
|
|
||||||
if self._ser:
|
|
||||||
with self.lock:
|
|
||||||
OpenFlexureStage._move_rel_nobacklash(self, *args, **kwargs)
|
|
||||||
else:
|
|
||||||
logging.warning("Unable to move stage. Serial communication unavailable.")
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue