{"action":"created","comment":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/comments/172263020","pull_request_review_id":99156060,"id":172263020,"diff_hunk":"@@ -0,0 +1,479 @@\n+\"\"\"\n+Monitoring utilities which aren't used by the application by default, but can\n+be used as needed to troubleshoot problems.\n+\"\"\"\n+from __future__ import absolute_import, print_function\n+\n+import gc\n+import itertools\n+import logging\n+import operator\n+import os\n+import socket\n+import sys\n+from StringIO import StringIO\n+from collections import defaultdict\n+\n+from django.conf import settings\n+from django.core.servers.basehttp import WSGIServer as DjangoWSGIServer\n+\n+import gunicorn.util\n+from objgraph import (\n+    _long_typename,\n+    _short_typename,\n+    at_addrs,\n+    show_backrefs,\n+    show_refs,\n+)\n+\n+from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace\n+\n+indices = defaultdict(itertools.count)\n+\n+# The directory in which graph files will be created.\n+GRAPH_DIRECTORY_PATH = settings.MEMORY_GRAPH_DIRECTORY\n+\n+# The max number of object types for which to show data on the console\n+MAX_CONSOLE_ROWS = 30\n+\n+# The max number of object types for which to generate reference graphs\n+MAX_GRAPHED_OBJECT_TYPES = 5\n+\n+# Maximum depth of forward reference graphs\n+REFS_DEPTH = 3\n+\n+# Maximum depth of backward reference graphs\n+BACK_REFS_DEPTH = 8\n+\n+# Max number of objects per type to use as starting points in the reference graphs\n+MAX_OBJECTS_PER_TYPE = 10\n+\n+# Object type names for which table rows and graphs should not be generated if\n+# the new object count is below the given threshold.  \"set\" is ignored by\n+# default because many sets are created in the course of tracking the number\n+# of new objects of each type.  \"ApdexStats\", \"SplitResult\", and \"TimeStats\"\n+# are New Relic data which sometimes outlives the duration of the request but\n+# usually doesn't stick around long-term.\n+IGNORE_THRESHOLDS = {\n+    'ApdexStats': 10,\n+    'SplitResult': 50,\n+    'TimeStats': 500,\n+    'set': 10000,\n+}\n+\n+WAFFLE_NAMESPACE = 'monitoring_utils'\n+\n+log = logging.getLogger(__name__)\n+\n+\n+def show_memory_leaks(\n+        label=u'memory_leaks',\n+        max_console_rows=MAX_CONSOLE_ROWS,\n+        max_graphed_object_types=MAX_GRAPHED_OBJECT_TYPES,\n+        refs_depth=REFS_DEPTH,\n+        back_refs_depth=BACK_REFS_DEPTH,\n+        max_objects_per_type=MAX_OBJECTS_PER_TYPE,\n+        ignore_thresholds=None,\n+        graph_directory_path=GRAPH_DIRECTORY_PATH,\n+        memory_table_buffer=None,\n+        skip_first_graphs=True):\n+    \"\"\"\n+    Call this function to get data about memory leaks; what objects are being\n+    leaked, where did they come from, and what do they contain?  The leaks\n+    are measured from the last call to ``get_new_ids()`` (which is called\n+    within this function).  Some data is printed to stdout, and more details\n+    are available in graphs stored at the paths printed to stdout.  Subsequent\n+    calls with the same label are indicated by an increasing index in the\n+    filename.\n+\n+    Args:\n+        label (unicode): The start of the filename for each graph\n+        max_console_rows (int): The max number of object types for which to\n+            show data on the console\n+        max_graphed_object_types (int): The max number of object types for\n+            which to generate reference graphs\n+        refs_depth (int): Maximum depth of forward reference graphs\n+        back_refs_depth (int): Maximum depth of backward reference graphs\n+        max_objects_per_type (int): Max number of objects per type to use as\n+            starting points in the reference graphs\n+        ignore_thresholds (dict): Object type names for which table rows and\n+            graphs should not be generated if the new object count is below\n+            the corresponding number.\n+        graph_directory_path (unicode): The directory in which graph files\n+            will be created.  It will be created if it doesn't already exist.\n+        memory_table_buffer (StringIO): Storage for the generated table of\n+            memory statistics.  Ideally, create this before starting to\n+            count newly allocated objects.\n+        skip_first_graphs (bool): True if the first call to this function for\n+            a given label should not produce graphs (the default behavior).\n+            The first call to a given block of code often initializes an\n+            assortment of objects which aren't really leaked memory.\n+    \"\"\"\n+    if ignore_thresholds is None:\n+        ignore_thresholds = IGNORE_THRESHOLDS\n+    if memory_table_buffer is None:\n+        memory_table_buffer = StringIO()\n+    new_ids = get_new_ids(limit=max_console_rows, ignore_thresholds=ignore_thresholds,\n+                          output=memory_table_buffer)\n+    memory_table_text = memory_table_buffer.getvalue()\n+    log.info('\\n' + memory_table_text)","path":"openedx/core/djangoapps/monitoring_utils/utils.py","position":119,"original_position":119,"commit_id":"65f58df0af4dc4c67963255c769ab9fab2a68bbb","original_commit_id":"65f58df0af4dc4c67963255c769ab9fab2a68bbb","user":{"login":"ormsbee","id":41625,"avatar_url":"https://avatars1.githubusercontent.com/u/41625?v=4","gravatar_id":"","url":"https://api.github.com/users/ormsbee","html_url":"https://github.com/ormsbee","followers_url":"https://api.github.com/users/ormsbee/followers","following_url":"https://api.github.com/users/ormsbee/following{/other_user}","gists_url":"https://api.github.com/users/ormsbee/gists{/gist_id}","starred_url":"https://api.github.com/users/ormsbee/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ormsbee/subscriptions","organizations_url":"https://api.github.com/users/ormsbee/orgs","repos_url":"https://api.github.com/users/ormsbee/repos","events_url":"https://api.github.com/users/ormsbee/events{/privacy}","received_events_url":"https://api.github.com/users/ormsbee/received_events","type":"User","site_admin":false},"body":"Silly nit/question: Why the pre-pended `\\n`?","created_at":"2018-03-05T17:19:51Z","updated_at":"2018-03-05T17:42:37Z","html_url":"https://github.com/edx/edx-platform/pull/17486#discussion_r172263020","pull_request_url":"https://api.github.com/repos/edx/edx-platform/pulls/17486","author_association":"OWNER","_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments/172263020"},"html":{"href":"https://github.com/edx/edx-platform/pull/17486#discussion_r172263020"},"pull_request":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17486"}}},"pull_request":{"url":"https://api.github.com/repos/edx/edx-platform/pulls/17486","id":169246112,"html_url":"https://github.com/edx/edx-platform/pull/17486","diff_url":"https://github.com/edx/edx-platform/pull/17486.diff","patch_url":"https://github.com/edx/edx-platform/pull/17486.patch","issue_url":"https://api.github.com/repos/edx/edx-platform/issues/17486","number":17486,"state":"open","locked":false,"title":"PLAT-1957 Better memory leak diagnostic tooling","user":{"login":"jmbowman","id":1005375,"avatar_url":"https://avatars2.githubusercontent.com/u/1005375?v=4","gravatar_id":"","url":"https://api.github.com/users/jmbowman","html_url":"https://github.com/jmbowman","followers_url":"https://api.github.com/users/jmbowman/followers","following_url":"https://api.github.com/users/jmbowman/following{/other_user}","gists_url":"https://api.github.com/users/jmbowman/gists{/gist_id}","starred_url":"https://api.github.com/users/jmbowman/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jmbowman/subscriptions","organizations_url":"https://api.github.com/users/jmbowman/orgs","repos_url":"https://api.github.com/users/jmbowman/repos","events_url":"https://api.github.com/users/jmbowman/events{/privacy}","received_events_url":"https://api.github.com/users/jmbowman/received_events","type":"User","site_admin":false},"body":"Add an additional memory monitoring utility with the ability to show more detailed data on new objects in memory and their reference graphs.  Key points:\r\n\r\n* This utility is available to LMS devstack and load tests (and all Studio instances) by default, but unless the corresponding waffle switch is enabled it does nothing beyond confirming that the switch is off.\r\n* Moved the original memory monitoring middleware such that it processes memory data *after* the request cache has been cleared.\r\n* To show leaked object stats on the console, call `MemoryUsageData.analyze(request)` within one or more views; the detailed memory usage info will only be processed for those views.  This keeps the performance impact and volume of generated data manageable.\r\n* The main configuration options for graph generation use defaults in module constants, but can be overridden for individual views.  We can look into overriding the defaults via Django settings or a configuration model later.","created_at":"2018-02-14T23:01:33Z","updated_at":"2018-03-05T17:42:37Z","closed_at":null,"merged_at":null,"merge_commit_sha":"115f8316afe3c09cb847fbf8814bc795a097af64","assignee":null,"assignees":[],"requested_reviewers":[{"login":"cpennington","id":30236,"avatar_url":"https://avatars0.githubusercontent.com/u/30236?v=4","gravatar_id":"","url":"https://api.github.com/users/cpennington","html_url":"https://github.com/cpennington","followers_url":"https://api.github.com/users/cpennington/followers","following_url":"https://api.github.com/users/cpennington/following{/other_user}","gists_url":"https://api.github.com/users/cpennington/gists{/gist_id}","starred_url":"https://api.github.com/users/cpennington/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cpennington/subscriptions","organizations_url":"https://api.github.com/users/cpennington/orgs","repos_url":"https://api.github.com/users/cpennington/repos","events_url":"https://api.github.com/users/cpennington/events{/privacy}","received_events_url":"https://api.github.com/users/cpennington/received_events","type":"User","site_admin":false},{"login":"bmedx","id":24231382,"avatar_url":"https://avatars3.githubusercontent.com/u/24231382?v=4","gravatar_id":"","url":"https://api.github.com/users/bmedx","html_url":"https://github.com/bmedx","followers_url":"https://api.github.com/users/bmedx/followers","following_url":"https://api.github.com/users/bmedx/following{/other_user}","gists_url":"https://api.github.com/users/bmedx/gists{/gist_id}","starred_url":"https://api.github.com/users/bmedx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bmedx/subscriptions","organizations_url":"https://api.github.com/users/bmedx/orgs","repos_url":"https://api.github.com/users/bmedx/repos","events_url":"https://api.github.com/users/bmedx/events{/privacy}","received_events_url":"https://api.github.com/users/bmedx/received_events","type":"User","site_admin":false}],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/edx/edx-platform/pulls/17486/commits","review_comments_url":"https://api.github.com/repos/edx/edx-platform/pulls/17486/comments","review_comment_url":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}","comments_url":"https://api.github.com/repos/edx/edx-platform/issues/17486/comments","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/65f58df0af4dc4c67963255c769ab9fab2a68bbb","head":{"label":"edx:jmbowman/PLAT-1957","ref":"jmbowman/PLAT-1957","sha":"65f58df0af4dc4c67963255c769ab9fab2a68bbb","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars3.githubusercontent.com/u/3179841?v=4","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars3.githubusercontent.com/u/3179841?v=4","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"The Open edX platform, the software that powers edX!","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-platform/deployments","created_at":"2013-05-30T20:20:38Z","updated_at":"2018-03-05T16:10:07Z","pushed_at":"2018-03-05T17:38:00Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://open.edx.org/","size":893023,"stargazers_count":3561,"watchers_count":3561,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2006,"mirror_url":null,"archived":false,"open_issues_count":225,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0"},"forks":2006,"open_issues":225,"watchers":3561,"default_branch":"master"}},"base":{"label":"edx:master","ref":"master","sha":"312a9ec16036a68d3b394f342daf3a89bcf6335f","user":{"login":"edx","id":3179841,"avatar_url":"https://avatars3.githubusercontent.com/u/3179841?v=4","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"repo":{"id":10391073,"name":"edx-platform","full_name":"edx/edx-platform","owner":{"login":"edx","id":3179841,"avatar_url":"https://avatars3.githubusercontent.com/u/3179841?v=4","gravatar_id":"","url":"https://api.github.com/users/edx","html_url":"https://github.com/edx","followers_url":"https://api.github.com/users/edx/followers","following_url":"https://api.github.com/users/edx/following{/other_user}","gists_url":"https://api.github.com/users/edx/gists{/gist_id}","starred_url":"https://api.github.com/users/edx/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/edx/subscriptions","organizations_url":"https://api.github.com/users/edx/orgs","repos_url":"https://api.github.com/users/edx/repos","events_url":"https://api.github.com/users/edx/events{/privacy}","received_events_url":"https://api.github.com/users/edx/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/edx/edx-platform","description":"The Open edX platform, the software that powers edX!","fork":false,"url":"https://api.github.com/repos/edx/edx-platform","forks_url":"https://api.github.com/repos/edx/edx-platform/forks","keys_url":"https://api.github.com/repos/edx/edx-platform/keys{/key_id}","collaborators_url":"https://api.github.com/repos/edx/edx-platform/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/edx/edx-platform/teams","hooks_url":"https://api.github.com/repos/edx/edx-platform/hooks","issue_events_url":"https://api.github.com/repos/edx/edx-platform/issues/events{/number}","events_url":"https://api.github.com/repos/edx/edx-platform/events","assignees_url":"https://api.github.com/repos/edx/edx-platform/assignees{/user}","branches_url":"https://api.github.com/repos/edx/edx-platform/branches{/branch}","tags_url":"https://api.github.com/repos/edx/edx-platform/tags","blobs_url":"https://api.github.com/repos/edx/edx-platform/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/edx/edx-platform/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/edx/edx-platform/git/refs{/sha}","trees_url":"https://api.github.com/repos/edx/edx-platform/git/trees{/sha}","statuses_url":"https://api.github.com/repos/edx/edx-platform/statuses/{sha}","languages_url":"https://api.github.com/repos/edx/edx-platform/languages","stargazers_url":"https://api.github.com/repos/edx/edx-platform/stargazers","contributors_url":"https://api.github.com/repos/edx/edx-platform/contributors","subscribers_url":"https://api.github.com/repos/edx/edx-platform/subscribers","subscription_url":"https://api.github.com/repos/edx/edx-platform/subscription","commits_url":"https://api.github.com/repos/edx/edx-platform/commits{/sha}","git_commits_url":"https://api.github.com/repos/edx/edx-platform/git/commits{/sha}","comments_url":"https://api.github.com/repos/edx/edx-platform/comments{/number}","issue_comment_url":"https://api.github.com/repos/edx/edx-platform/issues/comments{/number}","contents_url":"https://api.github.com/repos/edx/edx-platform/contents/{+path}","compare_url":"https://api.github.com/repos/edx/edx-platform/compare/{base}...{head}","merges_url":"https://api.github.com/repos/edx/edx-platform/merges","archive_url":"https://api.github.com/repos/edx/edx-platform/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/edx/edx-platform/downloads","issues_url":"https://api.github.com/repos/edx/edx-platform/issues{/number}","pulls_url":"https://api.github.com/repos/edx/edx-platform/pulls{/number}","milestones_url":"https://api.github.com/repos/edx/edx-platform/milestones{/number}","notifications_url":"https://api.github.com/repos/edx/edx-platform/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/edx/edx-platform/labels{/name}","releases_url":"https://api.github.com/repos/edx/edx-platform/releases{/id}","deployments_url":"https://api.github.com/repos/edx/edx-platform/deployments","created_at":"2013-05-30T20:20:38Z","updated_at":"2018-03-05T16:10:07Z","pushed_at":"2018-03-05T17:38:00Z","git_url":"git://github.com/edx/edx-platform.git","ssh_url":"git@github.com:edx/edx-platform.git","clone_url":"https://github.com/edx/edx-platform.git","svn_url":"https://github.com/edx/edx-platform","homepage":"http://open.edx.org/","size":893023,"stargazers_count":3561,"watchers_count":3561,"language":"Python","has_issues":false,"has_projects":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":2006,"mirror_url":null,"archived":false,"open_issues_count":225,"license":{"key":"agpl-3.0","name":"GNU Affero General Public License v3.0","spdx_id":"AGPL-3.0","url":"https://api.github.com/licenses/agpl-3.0"},"forks":2006,"open_issues":225,"watchers":3561,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17486"},"html":{"href":"https://github.com/edx/edx-platform/pull/17486"},"issue":{"href":"https://api.github.com/repos/edx/edx-platform/issues/17486"},"comments":{"href":"https://api.github.com/repos/edx/edx-platform/issues/17486/comments"},"review_comments":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17486/comments"},"review_comment":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/edx/edx-platform/pulls/17486/commits"},"statuses":{"href":"https://api.github.com/repos/edx/edx-platform/statuses/65f58df0af4dc4c67963255c769ab9fab2a68bbb"}},"author_association":"MEMBER"}}
{"actor":{"display_login":"ormsbee"}}