|
|
@@ -62,7 +62,8 @@ from desktop.lib.paths import get_desktop_root
|
|
|
from desktop.lib.thread_util import dump_traceback
|
|
|
from desktop.lib.view_util import is_ajax
|
|
|
from desktop.log.access import access_log_level, access_warn, AccessInfo
|
|
|
-from desktop.log import set_all_debug as _set_all_debug, reset_all_debug as _reset_all_debug, get_all_debug as _get_all_debug
|
|
|
+from desktop.log import set_all_debug as _set_all_debug, reset_all_debug as _reset_all_debug, \
|
|
|
+ get_all_debug as _get_all_debug, DEFAULT_LOG_DIR
|
|
|
from desktop.models import Settings, hue_version, _get_apps, UserPreferences
|
|
|
from libsaml.conf import REQUIRED_GROUPS, REQUIRED_GROUPS_ATTRIBUTE
|
|
|
from useradmin.models import get_profile
|
|
|
@@ -238,18 +239,38 @@ def log_view(request):
|
|
|
otherwise it will report that it can't be found.
|
|
|
"""
|
|
|
hostname = socket.gethostname()
|
|
|
- l = logging.getLogger()
|
|
|
-
|
|
|
- for h in l.handlers:
|
|
|
- if isinstance(h, desktop.log.log_buffer.FixedBufferHandler):
|
|
|
- return render('logs.mako', request,
|
|
|
- dict(
|
|
|
- log=[l for l in h.buf],
|
|
|
- query=request.GET.get("q", ""),
|
|
|
- hostname=hostname, is_embeddable=request.GET.get('is_embeddable', False)
|
|
|
- )
|
|
|
+ BUF_SIZE = 32 * 1024
|
|
|
+
|
|
|
+ buffer = []
|
|
|
+ log_dir = os.getenv("DESKTOP_LOG_DIR", DEFAULT_LOG_DIR)
|
|
|
+ log_file = "%s/rungunicornserver.log" % (log_dir)
|
|
|
+ prev_log_file = "%s/rungunicornserver.log.1" % (log_dir)
|
|
|
+
|
|
|
+ if log_dir and os.path.exists(log_file):
|
|
|
+ log_file_size = os.path.getsize(log_file)
|
|
|
+
|
|
|
+ # log file might get rotated or fresh start of server
|
|
|
+ if log_file_size < BUF_SIZE:
|
|
|
+ # search the previous file
|
|
|
+ if os.path.exists(prev_log_file):
|
|
|
+ prev_log_file_size = os.path.getsize(prev_log_file)
|
|
|
+ with open(prev_log_file, 'rb') as fh1:
|
|
|
+ fh1.seek(prev_log_file_size - BUF_SIZE - log_file_size)
|
|
|
+ for l in fh1.readlines(): buffer.append(l)
|
|
|
+ # read the current log file
|
|
|
+ with open(log_file, 'rb') as fh:
|
|
|
+ fh.seek(0)
|
|
|
+ for l in fh.readlines(): buffer.append(l)
|
|
|
+ else:
|
|
|
+ with open(log_file, 'rb') as fh:
|
|
|
+ fh.seek(log_file_size - BUF_SIZE)
|
|
|
+ for l in fh.readlines(): buffer.append(l)
|
|
|
+ return render('logs.mako', request, dict(
|
|
|
+ log=buffer,
|
|
|
+ query=request.GET.get("q", ""),
|
|
|
+ hostname=hostname, is_embeddable=request.GET.get('is_embeddable', False)
|
|
|
)
|
|
|
-
|
|
|
+ )
|
|
|
return render('logs.mako', request, dict(
|
|
|
log=[_("No logs found!")], query='', hostname=hostname, is_embeddable=request.GET.get('is_embeddable', False)
|
|
|
)
|
|
|
@@ -262,36 +283,60 @@ def download_log_view(request):
|
|
|
"""
|
|
|
Zip up the log buffer and then return as a file attachment.
|
|
|
"""
|
|
|
- l = logging.getLogger()
|
|
|
- for h in l.handlers:
|
|
|
- if isinstance(h, desktop.log.log_buffer.FixedBufferHandler):
|
|
|
- try:
|
|
|
- # We want to avoid doing a '\n'.join of the entire log in memory
|
|
|
- # in case it is rather big. So we write it to a file line by line
|
|
|
- # and pass that file to zipfile, which might follow a more efficient path.
|
|
|
- tmp = tempfile.NamedTemporaryFile()
|
|
|
- log_tmp = tempfile.NamedTemporaryFile("w+t") if sys.version_info[0] == 2 else tempfile.NamedTemporaryFile("w+t", encoding='utf-8')
|
|
|
- for l in h.buf:
|
|
|
- log_tmp.write(smart_str(l, errors='replace') + '\n')
|
|
|
- # This is not just for show - w/out flush, we often get truncated logs
|
|
|
- log_tmp.flush()
|
|
|
- t = time.time()
|
|
|
-
|
|
|
- zip = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED)
|
|
|
- zip.write(log_tmp.name, "hue-logs/hue-%s.log" % t)
|
|
|
- zip.close()
|
|
|
- length = tmp.tell()
|
|
|
-
|
|
|
- # if we don't seek to start of file, no bytes will be written
|
|
|
- tmp.seek(0)
|
|
|
- wrapper = FileWrapper(tmp)
|
|
|
- response = HttpResponse(wrapper, content_type="application/zip")
|
|
|
- response['Content-Disposition'] = 'attachment; filename=hue-logs-%s.zip' % t
|
|
|
- response['Content-Length'] = length
|
|
|
- return response
|
|
|
- except Exception as e:
|
|
|
- LOG.exception("Couldn't construct zip file to write logs")
|
|
|
- return log_view(request)
|
|
|
+ # Download 1MB log
|
|
|
+ BUF_SIZE = 1024 * 1024
|
|
|
+
|
|
|
+ buffer = []
|
|
|
+ log_dir = os.getenv("DESKTOP_LOG_DIR", DEFAULT_LOG_DIR)
|
|
|
+ log_file = "%s/rungunicornserver.log" % (log_dir)
|
|
|
+ prev_log_file = "%s/rungunicornserver.log.1" % (log_dir)
|
|
|
+
|
|
|
+ if log_dir and os.path.exists(log_file):
|
|
|
+ log_file_size = os.path.getsize(log_file)
|
|
|
+
|
|
|
+ # log file might get rotated or fresh start of server
|
|
|
+ if log_file_size < BUF_SIZE:
|
|
|
+ # search the previous file
|
|
|
+ if os.path.exists(prev_log_file):
|
|
|
+ prev_log_file_size = os.path.getsize(prev_log_file)
|
|
|
+ with open(prev_log_file, 'rb') as fh1:
|
|
|
+ fh1.seek(prev_log_file_size - BUF_SIZE - log_file_size)
|
|
|
+ for l in fh1.readlines(): buffer.append(l)
|
|
|
+ # read the current log file
|
|
|
+ with open(log_file, 'rb') as fh:
|
|
|
+ fh.seek(0)
|
|
|
+ for l in fh.readlines(): buffer.append(l)
|
|
|
+ else:
|
|
|
+ with open(log_file, 'rb') as fh:
|
|
|
+ fh.seek(log_file_size - BUF_SIZE)
|
|
|
+ for l in fh.readlines(): buffer.append(l)
|
|
|
+ try:
|
|
|
+ # We want to avoid doing a '\n'.join of the entire log in memory
|
|
|
+ # in case it is rather big. So we write it to a file line by line
|
|
|
+ # and pass that file to zipfile, which might follow a more efficient path.
|
|
|
+ tmp = tempfile.NamedTemporaryFile()
|
|
|
+ log_tmp = tempfile.NamedTemporaryFile("w+t") if sys.version_info[0] == 2 else tempfile.NamedTemporaryFile("w+t", encoding='utf-8')
|
|
|
+ for l in buffer:
|
|
|
+ log_tmp.write(smart_str(l, errors='replace'))
|
|
|
+ # This is not just for show - w/out flush, we often get truncated logs
|
|
|
+ log_tmp.flush()
|
|
|
+ t = time.time()
|
|
|
+
|
|
|
+ zip = zipfile.ZipFile(tmp, "w", zipfile.ZIP_DEFLATED)
|
|
|
+ zip.write(log_tmp.name, "hue-logs/hue-%s.log" % t)
|
|
|
+ zip.close()
|
|
|
+ length = tmp.tell()
|
|
|
+
|
|
|
+ # if we don't seek to start of file, no bytes will be written
|
|
|
+ tmp.seek(0)
|
|
|
+ wrapper = FileWrapper(tmp)
|
|
|
+ response = HttpResponse(wrapper, content_type="application/zip")
|
|
|
+ response['Content-Disposition'] = 'attachment; filename=hue-logs-%s.zip' % t
|
|
|
+ response['Content-Length'] = length
|
|
|
+ return response
|
|
|
+ except Exception as e:
|
|
|
+ LOG.exception("Couldn't construct zip file to write logs")
|
|
|
+ return log_view(request)
|
|
|
|
|
|
return django_render(request, "logs.mako", dict(log=[_("No logs found.")], is_embeddable=request.GET.get('is_embeddable', False)))
|
|
|
|