瀏覽代碼

HUE-8118 [core] Fine grain tracking of the memory usage

Roohi 7 年之前
父節點
當前提交
7590c0b

+ 3 - 0
desktop/conf.dist/hue.ini

@@ -65,6 +65,9 @@
   # Enable or disable memory profiling.
   ## memory_profiler=false
 
+  # Enable or disable instrumentation. If django_debug_mode is True, this is automatically enabled
+  ## instrumentation=false
+
   # Server email for internal error messages
   ## django_server_email='hue@localhost.localdomain'
 

+ 3 - 0
desktop/conf/pseudo-distributed.ini.tmpl

@@ -69,6 +69,9 @@
   # Enable or disable memory profiling.
   ## memory_profiler=false
 
+  # Enable or disable instrumentation. If django_debug_mode is True, this is automatically enabled
+  ## instrumentation=false
+
   # Server email for internal error messages
   ## django_server_email='hue@localhost.localdomain'
 

+ 10 - 0
desktop/core/src/desktop/conf.py

@@ -1337,6 +1337,16 @@ MEMORY_PROFILER = Config(
   type=coerce_bool,
   default=False)
 
+def get_instrumentation_default():
+  """If django_debug_mode is True, this is automatically enabled"""
+  return DJANGO_DEBUG_MODE.get()
+
+INSTRUMENTATION = Config(
+  key='instrumentation',
+  help=_('Enable or disable instrumentation. If django_debug_mode is True, this is automatically enabled.'),
+  type=coerce_bool,
+  dynamic_default=get_instrumentation_default)
+
 
 AUDIT_EVENT_LOG_DIR = Config(
   key="audit_event_log_dir",

+ 19 - 3
desktop/core/src/desktop/log/access.py

@@ -22,6 +22,8 @@ This assumes a single-threaded server.
 
 import logging
 import re
+import resource
+import sys
 import threading
 import time
 
@@ -81,15 +83,29 @@ class AccessInfo(dict):
     self['agent'] = request.META.get('HTTP_USER_AGENT', '-')
     self['time'] = time.time()
     self['duration'] = None
+    self['memory'] = None
+
+  def memory_usage_resource(self):
+    """
+      This is a lightweight way to get the total peak memory as
+       doing the diffing before/after request with guppy was too inconsistent and memory intensive.
+      """
+    rusage_denom = 1024
+    if sys.platform == 'darwin':
+      rusage_denom = rusage_denom * 1024
+    # get peak memory usage, bytes on OSX, Kilobytes on Linux
+    return resource.getrusage(resource.RUSAGE_SELF).ru_maxrss / rusage_denom
 
   def log(self, level, msg=None, start_time=None):
-    self['duration'] = ' returned in %dms' % ((time.time() - start_time) * 1000) if start_time is not None else ''
+    is_instrumentation = desktop.conf.INSTRUMENTATION.get()
+    self['duration'] = ' returned in %dms' % ((time.time() - start_time) * 1000) if start_time is not None and is_instrumentation else ''
+    self['memory'] = ' (mem: %dmb)' % self.memory_usage_resource() if is_instrumentation else ''
 
     if msg is not None:
       self['msg'] = msg
-      ACCESS_LOG.log(level, '%(remote_ip)s %(username)s - "%(method)s %(path)s %(proto)s"%(duration)s -- %(msg)s' % self)
+      ACCESS_LOG.log(level, '%(remote_ip)s %(username)s - "%(method)s %(path)s %(proto)s"%(duration)s%(memory)s-- %(msg)s' % self)
     else:
-      ACCESS_LOG.log(level, '%(remote_ip)s %(username)s - "%(method)s %(path)s %(proto)s"%(duration)s' % self)
+      ACCESS_LOG.log(level, '%(remote_ip)s %(username)s - "%(method)s %(path)s %(proto)s"%(duration)s%(memory)s' % self)
 
   def add_to_access_history(self, app):
     """Record this user access to the recent access map"""

+ 4 - 0
desktop/core/src/desktop/settings.py

@@ -20,6 +20,7 @@
 # Local customizations are done by symlinking a file
 # as local_settings.py.
 
+import gc
 import logging
 import os
 import pkg_resources
@@ -509,6 +510,9 @@ if desktop.conf.MEMORY_PROFILER.get():
   MEMORY_PROFILER = hpy()
   MEMORY_PROFILER.setrelheap()
 
+# Instrumentation
+if desktop.conf.INSTRUMENTATION.get():
+  gc.set_debug(gc.DEBUG_UNCOLLECTABLE | gc.DEBUG_OBJECTS)
 
 if not desktop.conf.DATABASE_LOGGING.get():
   def disable_database_logging():