Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
630985b3
Commit
630985b3
authored
Mar 06, 2017
by
Joel Barciauskas
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Wrap all newrelic dependencies in a check to see if the module is loaded
parent
369c13cd
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
112 additions
and
59 deletions
+112
-59
common/djangoapps/newrelic_custom_metrics/middleware.py
+10
-1
common/lib/xmodule/xmodule/seq_module.py
+11
-1
lms/djangoapps/courseware/module_render.py
+10
-5
lms/djangoapps/courseware/views/index.py
+10
-2
lms/djangoapps/discussion/views.py
+38
-29
lms/djangoapps/grades/tasks.py
+9
-5
openedx/core/djangoapps/contentserver/middleware.py
+24
-16
No files found.
common/djangoapps/newrelic_custom_metrics/middleware.py
View file @
630985b3
...
@@ -6,7 +6,14 @@ This middleware will only call on the newrelic agent if there are any metrics
...
@@ -6,7 +6,14 @@ This middleware will only call on the newrelic agent if there are any metrics
to report for this request, so it will not incur any processing overhead for
to report for this request, so it will not incur any processing overhead for
request handlers which do not record custom metrics.
request handlers which do not record custom metrics.
"""
"""
import
newrelic.agent
import
logging
log
=
logging
.
getLogger
(
__name__
)
try
:
import
newrelic.agent
except
ImportError
:
log
.
warning
(
"Unable to load NewRelic agent module"
)
newrelic
=
None
# pylint: disable=invalid-name
import
request_cache
import
request_cache
REQUEST_CACHE_KEY
=
'newrelic_custom_metrics'
REQUEST_CACHE_KEY
=
'newrelic_custom_metrics'
...
@@ -40,6 +47,8 @@ class NewRelicCustomMetrics(object):
...
@@ -40,6 +47,8 @@ class NewRelicCustomMetrics(object):
"""
"""
Report the collected custom metrics to New Relic.
Report the collected custom metrics to New Relic.
"""
"""
if
not
newrelic
:
return
metrics_cache
=
cls
.
_get_metrics_cache
()
metrics_cache
=
cls
.
_get_metrics_cache
()
for
metric_name
,
metric_value
in
metrics_cache
.
iteritems
():
for
metric_name
,
metric_value
in
metrics_cache
.
iteritems
():
newrelic
.
agent
.
add_custom_parameter
(
metric_name
,
metric_value
)
newrelic
.
agent
.
add_custom_parameter
(
metric_name
,
metric_value
)
...
...
common/lib/xmodule/xmodule/seq_module.py
View file @
630985b3
...
@@ -14,7 +14,6 @@ from lxml import etree
...
@@ -14,7 +14,6 @@ from lxml import etree
from
xblock.core
import
XBlock
from
xblock.core
import
XBlock
from
xblock.fields
import
Integer
,
Scope
,
Boolean
,
String
from
xblock.fields
import
Integer
,
Scope
,
Boolean
,
String
from
xblock.fragment
import
Fragment
from
xblock.fragment
import
Fragment
import
newrelic.agent
from
.exceptions
import
NotFoundError
from
.exceptions
import
NotFoundError
from
.fields
import
Date
from
.fields
import
Date
...
@@ -25,6 +24,11 @@ from .xml_module import XmlDescriptor
...
@@ -25,6 +24,11 @@ from .xml_module import XmlDescriptor
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
try
:
import
newrelic.agent
except
ImportError
:
newrelic
=
None
# pylint: disable=invalid-name
# HACK: This shouldn't be hard-coded to two types
# HACK: This shouldn't be hard-coded to two types
# OBSOLETE: This obsoletes 'type'
# OBSOLETE: This obsoletes 'type'
class_priority
=
[
'video'
,
'problem'
]
class_priority
=
[
'video'
,
'problem'
]
...
@@ -385,6 +389,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
...
@@ -385,6 +389,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
"""
"""
Capture basic information about this sequence in New Relic.
Capture basic information about this sequence in New Relic.
"""
"""
if
not
newrelic
:
return
newrelic
.
agent
.
add_custom_parameter
(
'seq.block_id'
,
unicode
(
self
.
location
))
newrelic
.
agent
.
add_custom_parameter
(
'seq.block_id'
,
unicode
(
self
.
location
))
newrelic
.
agent
.
add_custom_parameter
(
'seq.display_name'
,
self
.
display_name
or
''
)
newrelic
.
agent
.
add_custom_parameter
(
'seq.display_name'
,
self
.
display_name
or
''
)
newrelic
.
agent
.
add_custom_parameter
(
'seq.position'
,
self
.
position
)
newrelic
.
agent
.
add_custom_parameter
(
'seq.position'
,
self
.
position
)
...
@@ -396,6 +402,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
...
@@ -396,6 +402,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
the sequence as a whole. We send this information to New Relic so that
the sequence as a whole. We send this information to New Relic so that
we can do better performance analysis of courseware.
we can do better performance analysis of courseware.
"""
"""
if
not
newrelic
:
return
# Basic count of the number of Units (a.k.a. VerticalBlocks) we have in
# Basic count of the number of Units (a.k.a. VerticalBlocks) we have in
# this learning sequence
# this learning sequence
newrelic
.
agent
.
add_custom_parameter
(
'seq.num_units'
,
len
(
display_items
))
newrelic
.
agent
.
add_custom_parameter
(
'seq.num_units'
,
len
(
display_items
))
...
@@ -414,6 +422,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
...
@@ -414,6 +422,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
"""
"""
Capture information about the current selected Unit within the Sequence.
Capture information about the current selected Unit within the Sequence.
"""
"""
if
not
newrelic
:
return
# Positions are stored with indexing starting at 1. If we get into a
# Positions are stored with indexing starting at 1. If we get into a
# weird state where the saved position is out of bounds (e.g. the
# weird state where the saved position is out of bounds (e.g. the
# content was changed), avoid going into any details about this unit.
# content was changed), avoid going into any details about this unit.
...
...
lms/djangoapps/courseware/module_render.py
View file @
630985b3
...
@@ -8,7 +8,6 @@ import logging
...
@@ -8,7 +8,6 @@ import logging
from
collections
import
OrderedDict
from
collections
import
OrderedDict
from
functools
import
partial
from
functools
import
partial
import
newrelic.agent
from
capa.xqueue_interface
import
XQueueInterface
from
capa.xqueue_interface
import
XQueueInterface
from
django.conf
import
settings
from
django.conf
import
settings
from
django.contrib.auth.models
import
User
from
django.contrib.auth.models
import
User
...
@@ -82,6 +81,10 @@ from .field_overrides import OverrideFieldData
...
@@ -82,6 +81,10 @@ from .field_overrides import OverrideFieldData
log
=
logging
.
getLogger
(
__name__
)
log
=
logging
.
getLogger
(
__name__
)
try
:
import
newrelic.agent
except
ImportError
:
newrelic
=
None
# pylint: disable=invalid-name
if
settings
.
XQUEUE_INTERFACE
.
get
(
'basic_auth'
)
is
not
None
:
if
settings
.
XQUEUE_INTERFACE
.
get
(
'basic_auth'
)
is
not
None
:
REQUESTS_AUTH
=
HTTPBasicAuth
(
*
settings
.
XQUEUE_INTERFACE
[
'basic_auth'
])
REQUESTS_AUTH
=
HTTPBasicAuth
(
*
settings
.
XQUEUE_INTERFACE
[
'basic_auth'
])
...
@@ -966,9 +969,10 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
...
@@ -966,9 +969,10 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
except
InvalidKeyError
:
except
InvalidKeyError
:
raise
Http404
raise
Http404
# Gather metrics for New Relic so we can slice data in New Relic Insights
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
unicode
(
course_key
))
# Gather metrics for New Relic so we can slice data in New Relic Insights
newrelic
.
agent
.
add_custom_parameter
(
'org'
,
unicode
(
course_key
.
org
))
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
unicode
(
course_key
))
newrelic
.
agent
.
add_custom_parameter
(
'org'
,
unicode
(
course_key
.
org
))
with
modulestore
()
.
bulk_operations
(
course_key
):
with
modulestore
()
.
bulk_operations
(
course_key
):
instance
,
tracking_context
=
get_module_by_usage_id
(
request
,
course_id
,
usage_id
,
course
=
course
)
instance
,
tracking_context
=
get_module_by_usage_id
(
request
,
course_id
,
usage_id
,
course
=
course
)
...
@@ -978,7 +982,8 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
...
@@ -978,7 +982,8 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
# "handler" in those cases is always just "xmodule_handler".
# "handler" in those cases is always just "xmodule_handler".
nr_tx_name
=
"{}.{}"
.
format
(
instance
.
__class__
.
__name__
,
handler
)
nr_tx_name
=
"{}.{}"
.
format
(
instance
.
__class__
.
__name__
,
handler
)
nr_tx_name
+=
"/{}"
.
format
(
suffix
)
if
(
suffix
and
handler
==
"xmodule_handler"
)
else
""
nr_tx_name
+=
"/{}"
.
format
(
suffix
)
if
(
suffix
and
handler
==
"xmodule_handler"
)
else
""
newrelic
.
agent
.
set_transaction_name
(
nr_tx_name
,
group
=
"Python/XBlock/Handler"
)
if
newrelic
:
newrelic
.
agent
.
set_transaction_name
(
nr_tx_name
,
group
=
"Python/XBlock/Handler"
)
tracking_context_name
=
'module_callback_handler'
tracking_context_name
=
'module_callback_handler'
req
=
django_to_webob_request
(
request
)
req
=
django_to_webob_request
(
request
)
...
...
lms/djangoapps/courseware/views/index.py
View file @
630985b3
...
@@ -19,7 +19,14 @@ from django.shortcuts import redirect
...
@@ -19,7 +19,14 @@ from django.shortcuts import redirect
from
courseware.url_helpers
import
get_redirect_url_for_global_staff
from
courseware.url_helpers
import
get_redirect_url_for_global_staff
from
edxmako.shortcuts
import
render_to_response
,
render_to_string
from
edxmako.shortcuts
import
render_to_response
,
render_to_string
import
logging
import
logging
import
newrelic.agent
log
=
logging
.
getLogger
(
"edx.courseware.views.index"
)
try
:
import
newrelic.agent
except
ImportError
:
newrelic
=
None
# pylint: disable=invalid-name
import
urllib
import
urllib
from
xblock.fragment
import
Fragment
from
xblock.fragment
import
Fragment
...
@@ -54,7 +61,6 @@ from ..module_render import toc_for_course, get_module_for_descriptor
...
@@ -54,7 +61,6 @@ from ..module_render import toc_for_course, get_module_for_descriptor
from
.views
import
get_current_child
,
registered_for_course
from
.views
import
get_current_child
,
registered_for_course
log
=
logging
.
getLogger
(
"edx.courseware.views.index"
)
TEMPLATE_IMPORTS
=
{
'urllib'
:
urllib
}
TEMPLATE_IMPORTS
=
{
'urllib'
:
urllib
}
CONTENT_DEPTH
=
2
CONTENT_DEPTH
=
2
...
@@ -174,6 +180,8 @@ class CoursewareIndex(View):
...
@@ -174,6 +180,8 @@ class CoursewareIndex(View):
"""
"""
Initialize metrics for New Relic so we can slice data in New Relic Insights
Initialize metrics for New Relic so we can slice data in New Relic Insights
"""
"""
if
not
newrelic
:
return
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
unicode
(
self
.
course_key
))
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
unicode
(
self
.
course_key
))
newrelic
.
agent
.
add_custom_parameter
(
'org'
,
unicode
(
self
.
course_key
.
org
))
newrelic
.
agent
.
add_custom_parameter
(
'org'
,
unicode
(
self
.
course_key
.
org
))
...
...
lms/djangoapps/discussion/views.py
View file @
630985b3
...
@@ -17,7 +17,13 @@ from django.shortcuts import render_to_response
...
@@ -17,7 +17,13 @@ from django.shortcuts import render_to_response
from
django.template.loader
import
render_to_string
from
django.template.loader
import
render_to_string
from
django.utils.translation
import
get_language_bidi
from
django.utils.translation
import
get_language_bidi
from
django.views.decorators.http
import
require_GET
from
django.views.decorators.http
import
require_GET
import
newrelic.agent
log
=
logging
.
getLogger
(
"edx.discussions"
)
try
:
import
newrelic.agent
except
ImportError
:
newrelic
=
None
# pylint: disable=invalid-name
from
rest_framework
import
status
from
rest_framework
import
status
from
web_fragments.fragment
import
Fragment
from
web_fragments.fragment
import
Fragment
...
@@ -50,13 +56,27 @@ import lms.lib.comment_client as cc
...
@@ -50,13 +56,27 @@ import lms.lib.comment_client as cc
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.keys
import
CourseKey
from
contextlib
import
contextmanager
THREADS_PER_PAGE
=
20
THREADS_PER_PAGE
=
20
INLINE_THREADS_PER_PAGE
=
20
INLINE_THREADS_PER_PAGE
=
20
PAGES_NEARBY_DELTA
=
2
PAGES_NEARBY_DELTA
=
2
log
=
logging
.
getLogger
(
"edx.discussions"
)
@newrelic.agent.function_trace
()
@contextmanager
def
newrelic_function_trace
(
function_name
):
"""
A wrapper context manager newrelic.agent.FunctionTrace to no-op if the
newrelic package is not installed
"""
if
newrelic
:
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
function_name
):
yield
else
:
yield
def
make_course_settings
(
course
,
user
):
def
make_course_settings
(
course
,
user
):
"""
"""
Generate a JSON-serializable model for course settings, which will be used to initialize a
Generate a JSON-serializable model for course settings, which will be used to initialize a
...
@@ -71,7 +91,6 @@ def make_course_settings(course, user):
...
@@ -71,7 +91,6 @@ def make_course_settings(course, user):
}
}
@newrelic.agent.function_trace
()
def
get_threads
(
request
,
course
,
user_info
,
discussion_id
=
None
,
per_page
=
THREADS_PER_PAGE
):
def
get_threads
(
request
,
course
,
user_info
,
discussion_id
=
None
,
per_page
=
THREADS_PER_PAGE
):
"""
"""
This may raise an appropriate subclass of cc.utils.CommentClientError
This may raise an appropriate subclass of cc.utils.CommentClientError
...
@@ -184,7 +203,6 @@ def inline_discussion(request, course_key, discussion_id):
...
@@ -184,7 +203,6 @@ def inline_discussion(request, course_key, discussion_id):
"""
"""
Renders JSON for DiscussionModules
Renders JSON for DiscussionModules
"""
"""
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
cc_user
=
cc
.
User
.
from_django_user
(
request
.
user
)
cc_user
=
cc
.
User
.
from_django_user
(
request
.
user
)
...
@@ -195,12 +213,14 @@ def inline_discussion(request, course_key, discussion_id):
...
@@ -195,12 +213,14 @@ def inline_discussion(request, course_key, discussion_id):
except
ValueError
:
except
ValueError
:
return
HttpResponseServerError
(
"Invalid group_id"
)
return
HttpResponseServerError
(
"Invalid group_id"
)
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_metadata_for_threads"
):
with
newrelic
_function_trace
(
"get_metadata_for_threads"
):
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
request
.
user
,
user_info
)
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
request
.
user
,
user_info
)
is_staff
=
has_permission
(
request
.
user
,
'openclose_thread'
,
course
.
id
)
is_staff
=
has_permission
(
request
.
user
,
'openclose_thread'
,
course
.
id
)
threads
=
[
utils
.
prepare_content
(
thread
,
course_key
,
is_staff
)
for
thread
in
threads
]
threads
=
[
utils
.
prepare_content
(
thread
,
course_key
,
is_staff
)
for
thread
in
threads
]
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"add_courseware_context"
):
with
newrelic
_function_trace
(
"add_courseware_context"
):
add_courseware_context
(
threads
,
course
,
request
.
user
)
add_courseware_context
(
threads
,
course
,
request
.
user
)
return
utils
.
JsonResponse
({
return
utils
.
JsonResponse
({
'is_commentable_cohorted'
:
is_commentable_cohorted
(
course_key
,
discussion_id
),
'is_commentable_cohorted'
:
is_commentable_cohorted
(
course_key
,
discussion_id
),
'discussion_data'
:
threads
,
'discussion_data'
:
threads
,
...
@@ -219,8 +239,6 @@ def forum_form_discussion(request, course_key):
...
@@ -219,8 +239,6 @@ def forum_form_discussion(request, course_key):
"""
"""
Renders the main Discussion page, potentially filtered by a search query
Renders the main Discussion page, potentially filtered by a search query
"""
"""
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
if
request
.
is_ajax
():
if
request
.
is_ajax
():
user
=
cc
.
User
.
from_django_user
(
request
.
user
)
user
=
cc
.
User
.
from_django_user
(
request
.
user
)
...
@@ -235,10 +253,10 @@ def forum_form_discussion(request, course_key):
...
@@ -235,10 +253,10 @@ def forum_form_discussion(request, course_key):
except
ValueError
:
except
ValueError
:
return
HttpResponseServerError
(
"Invalid group_id"
)
return
HttpResponseServerError
(
"Invalid group_id"
)
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_metadata_for_threads"
):
with
newrelic
_function_trace
(
"get_metadata_for_threads"
):
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
request
.
user
,
user_info
)
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
request
.
user
,
user_info
)
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"add_courseware_context"
):
with
newrelic
_function_trace
(
"add_courseware_context"
):
add_courseware_context
(
threads
,
course
,
request
.
user
)
add_courseware_context
(
threads
,
course
,
request
.
user
)
return
utils
.
JsonResponse
({
return
utils
.
JsonResponse
({
...
@@ -265,8 +283,6 @@ def single_thread(request, course_key, discussion_id, thread_id):
...
@@ -265,8 +283,6 @@ def single_thread(request, course_key, discussion_id, thread_id):
Depending on the HTTP headers, we'll adjust our response accordingly.
Depending on the HTTP headers, we'll adjust our response accordingly.
"""
"""
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
if
request
.
is_ajax
():
if
request
.
is_ajax
():
...
@@ -278,7 +294,7 @@ def single_thread(request, course_key, discussion_id, thread_id):
...
@@ -278,7 +294,7 @@ def single_thread(request, course_key, discussion_id, thread_id):
if
not
thread
:
if
not
thread
:
raise
Http404
raise
Http404
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_annotated_content_infos"
):
with
newrelic
_function_trace
(
"get_annotated_content_infos"
):
annotated_content_info
=
utils
.
get_annotated_content_infos
(
annotated_content_info
=
utils
.
get_annotated_content_infos
(
course_key
,
course_key
,
thread
,
thread
,
...
@@ -287,7 +303,7 @@ def single_thread(request, course_key, discussion_id, thread_id):
...
@@ -287,7 +303,7 @@ def single_thread(request, course_key, discussion_id, thread_id):
)
)
content
=
utils
.
prepare_content
(
thread
.
to_dict
(),
course_key
,
is_staff
)
content
=
utils
.
prepare_content
(
thread
.
to_dict
(),
course_key
,
is_staff
)
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"add_courseware_context"
):
with
newrelic
_function_trace
(
"add_courseware_context"
):
add_courseware_context
([
content
],
course
,
request
.
user
)
add_courseware_context
([
content
],
course
,
request
.
user
)
return
utils
.
JsonResponse
({
return
utils
.
JsonResponse
({
...
@@ -372,7 +388,6 @@ def _create_discussion_board_context(request, course_key, discussion_id=None, th
...
@@ -372,7 +388,6 @@ def _create_discussion_board_context(request, course_key, discussion_id=None, th
"""
"""
Returns the template context for rendering the discussion board.
Returns the template context for rendering the discussion board.
"""
"""
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
context
=
_create_base_discussion_view_context
(
request
,
course_key
)
context
=
_create_base_discussion_view_context
(
request
,
course_key
)
course
=
context
[
'course'
]
course
=
context
[
'course'
]
course_settings
=
context
[
'course_settings'
]
course_settings
=
context
[
'course_settings'
]
...
@@ -401,13 +416,13 @@ def _create_discussion_board_context(request, course_key, discussion_id=None, th
...
@@ -401,13 +416,13 @@ def _create_discussion_board_context(request, course_key, discussion_id=None, th
is_staff
=
has_permission
(
user
,
'openclose_thread'
,
course
.
id
)
is_staff
=
has_permission
(
user
,
'openclose_thread'
,
course
.
id
)
threads
=
[
utils
.
prepare_content
(
thread
,
course_key
,
is_staff
)
for
thread
in
threads
]
threads
=
[
utils
.
prepare_content
(
thread
,
course_key
,
is_staff
)
for
thread
in
threads
]
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_metadata_for_threads"
):
with
newrelic
_function_trace
(
"get_metadata_for_threads"
):
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
user
,
user_info
)
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
user
,
user_info
)
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"add_courseware_context"
):
with
newrelic
_function_trace
(
"add_courseware_context"
):
add_courseware_context
(
threads
,
course
,
user
)
add_courseware_context
(
threads
,
course
,
user
)
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_cohort_info"
):
with
newrelic
_function_trace
(
"get_cohort_info"
):
user_cohort_id
=
get_cohort_id
(
user
,
course_key
)
user_cohort_id
=
get_cohort_id
(
user
,
course_key
)
context
.
update
({
context
.
update
({
...
@@ -435,9 +450,6 @@ def user_profile(request, course_key, user_id):
...
@@ -435,9 +450,6 @@ def user_profile(request, course_key, user_id):
Renders a response to display the user profile page (shown after clicking
Renders a response to display the user profile page (shown after clicking
on a post author's username).
on a post author's username).
"""
"""
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
user
=
cc
.
User
.
from_django_user
(
request
.
user
)
user
=
cc
.
User
.
from_django_user
(
request
.
user
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
...
@@ -466,13 +478,13 @@ def user_profile(request, course_key, user_id):
...
@@ -466,13 +478,13 @@ def user_profile(request, course_key, user_id):
query_params
[
'page'
]
=
page
query_params
[
'page'
]
=
page
query_params
[
'num_pages'
]
=
num_pages
query_params
[
'num_pages'
]
=
num_pages
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_metadata_for_threads"
):
with
newrelic
_function_trace
(
"get_metadata_for_threads"
):
user_info
=
cc
.
User
.
from_django_user
(
request
.
user
)
.
to_dict
()
user_info
=
cc
.
User
.
from_django_user
(
request
.
user
)
.
to_dict
()
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
request
.
user
,
user_info
)
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
threads
,
request
.
user
,
user_info
)
is_staff
=
has_permission
(
request
.
user
,
'openclose_thread'
,
course
.
id
)
is_staff
=
has_permission
(
request
.
user
,
'openclose_thread'
,
course
.
id
)
threads
=
[
utils
.
prepare_content
(
thread
,
course_key
,
is_staff
)
for
thread
in
threads
]
threads
=
[
utils
.
prepare_content
(
thread
,
course_key
,
is_staff
)
for
thread
in
threads
]
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"add_courseware_context"
):
with
newrelic
_function_trace
(
"add_courseware_context"
):
add_courseware_context
(
threads
,
course
,
request
.
user
)
add_courseware_context
(
threads
,
course
,
request
.
user
)
if
request
.
is_ajax
():
if
request
.
is_ajax
():
return
utils
.
JsonResponse
({
return
utils
.
JsonResponse
({
...
@@ -486,7 +498,7 @@ def user_profile(request, course_key, user_id):
...
@@ -486,7 +498,7 @@ def user_profile(request, course_key, user_id):
course_id
=
course
.
id
course_id
=
course
.
id
)
.
order_by
(
"name"
)
.
values_list
(
"name"
,
flat
=
True
)
.
distinct
()
)
.
order_by
(
"name"
)
.
values_list
(
"name"
,
flat
=
True
)
.
distinct
()
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_cohort_info"
):
with
newrelic
_function_trace
(
"get_cohort_info"
):
user_cohort_id
=
get_cohort_id
(
request
.
user
,
course_key
)
user_cohort_id
=
get_cohort_id
(
request
.
user
,
course_key
)
context
=
_create_base_discussion_view_context
(
request
,
course_key
)
context
=
_create_base_discussion_view_context
(
request
,
course_key
)
...
@@ -514,9 +526,6 @@ def followed_threads(request, course_key, user_id):
...
@@ -514,9 +526,6 @@ def followed_threads(request, course_key, user_id):
"""
"""
Ajax-only endpoint retrieving the threads followed by a specific user.
Ajax-only endpoint retrieving the threads followed by a specific user.
"""
"""
nr_transaction
=
newrelic
.
agent
.
current_transaction
()
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
course
=
get_course_with_access
(
request
.
user
,
'load'
,
course_key
,
check_if_enrolled
=
True
)
try
:
try
:
profiled_user
=
cc
.
User
(
id
=
user_id
,
course_id
=
course_key
)
profiled_user
=
cc
.
User
(
id
=
user_id
,
course_id
=
course_key
)
...
@@ -557,7 +566,7 @@ def followed_threads(request, course_key, user_id):
...
@@ -557,7 +566,7 @@ def followed_threads(request, course_key, user_id):
query_params
[
'num_pages'
]
=
paginated_results
.
num_pages
query_params
[
'num_pages'
]
=
paginated_results
.
num_pages
user_info
=
cc
.
User
.
from_django_user
(
request
.
user
)
.
to_dict
()
user_info
=
cc
.
User
.
from_django_user
(
request
.
user
)
.
to_dict
()
with
newrelic
.
agent
.
FunctionTrace
(
nr_transaction
,
"get_metadata_for_threads"
):
with
newrelic
_function_trace
(
"get_metadata_for_threads"
):
annotated_content_info
=
utils
.
get_metadata_for_threads
(
annotated_content_info
=
utils
.
get_metadata_for_threads
(
course_key
,
course_key
,
paginated_results
.
collection
,
paginated_results
.
collection
,
...
...
lms/djangoapps/grades/tasks.py
View file @
630985b3
...
@@ -9,7 +9,12 @@ from django.contrib.auth.models import User
...
@@ -9,7 +9,12 @@ from django.contrib.auth.models import User
from
django.core.exceptions
import
ValidationError
from
django.core.exceptions
import
ValidationError
from
django.db.utils
import
DatabaseError
from
django.db.utils
import
DatabaseError
from
logging
import
getLogger
from
logging
import
getLogger
import
newrelic.agent
log
=
getLogger
(
__name__
)
try
:
import
newrelic.agent
except
ImportError
:
newrelic
=
None
# pylint: disable=invalid-name
from
celery_utils.logged_task
import
LoggedTask
from
celery_utils.logged_task
import
LoggedTask
from
celery_utils.persist_on_failure
import
PersistOnFailureTask
from
celery_utils.persist_on_failure
import
PersistOnFailureTask
...
@@ -31,8 +36,6 @@ from .new.subsection_grade import SubsectionGradeFactory
...
@@ -31,8 +36,6 @@ from .new.subsection_grade import SubsectionGradeFactory
from
.signals.signals
import
SUBSECTION_SCORE_CHANGED
from
.signals.signals
import
SUBSECTION_SCORE_CHANGED
from
.transformer
import
GradesTransformer
from
.transformer
import
GradesTransformer
log
=
getLogger
(
__name__
)
class
DatabaseNotReadyError
(
IOError
):
class
DatabaseNotReadyError
(
IOError
):
"""
"""
...
@@ -96,8 +99,9 @@ def _recalculate_subsection_grade(self, **kwargs):
...
@@ -96,8 +99,9 @@ def _recalculate_subsection_grade(self, **kwargs):
scored_block_usage_key
=
UsageKey
.
from_string
(
kwargs
[
'usage_id'
])
.
replace
(
course_key
=
course_key
)
scored_block_usage_key
=
UsageKey
.
from_string
(
kwargs
[
'usage_id'
])
.
replace
(
course_key
=
course_key
)
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
unicode
(
course_key
))
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'usage_id'
,
unicode
(
scored_block_usage_key
))
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
unicode
(
course_key
))
newrelic
.
agent
.
add_custom_parameter
(
'usage_id'
,
unicode
(
scored_block_usage_key
))
# The request cache is not maintained on celery workers,
# The request cache is not maintained on celery workers,
# where this code runs. So we take the values from the
# where this code runs. So we take the values from the
...
...
openedx/core/djangoapps/contentserver/middleware.py
View file @
630985b3
...
@@ -4,7 +4,11 @@ Middleware to serve assets.
...
@@ -4,7 +4,11 @@ Middleware to serve assets.
import
logging
import
logging
import
datetime
import
datetime
import
newrelic.agent
log
=
logging
.
getLogger
(
__name__
)
try
:
import
newrelic.agent
except
ImportError
:
newrelic
=
None
# pylint: disable=invalid-name
from
django.http
import
(
from
django.http
import
(
HttpResponse
,
HttpResponseNotModified
,
HttpResponseForbidden
,
HttpResponse
,
HttpResponseNotModified
,
HttpResponseForbidden
,
HttpResponseBadRequest
,
HttpResponseNotFound
,
HttpResponsePermanentRedirect
)
HttpResponseBadRequest
,
HttpResponseNotFound
,
HttpResponsePermanentRedirect
)
...
@@ -25,7 +29,6 @@ from .models import CourseAssetCacheTtlConfig, CdnUserAgentsConfig
...
@@ -25,7 +29,6 @@ from .models import CourseAssetCacheTtlConfig, CdnUserAgentsConfig
# TODO: Soon as we have a reasonable way to serialize/deserialize AssetKeys, we need
# TODO: Soon as we have a reasonable way to serialize/deserialize AssetKeys, we need
# to change this file so instead of using course_id_partial, we're just using asset keys
# to change this file so instead of using course_id_partial, we're just using asset keys
log
=
logging
.
getLogger
(
__name__
)
HTTP_DATE_FORMAT
=
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
HTTP_DATE_FORMAT
=
"
%
a,
%
d
%
b
%
Y
%
H:
%
M:
%
S GMT"
...
@@ -86,17 +89,18 @@ class StaticContentServer(object):
...
@@ -86,17 +89,18 @@ class StaticContentServer(object):
if
safe_course_key
.
run
is
None
:
if
safe_course_key
.
run
is
None
:
safe_course_key
=
safe_course_key
.
replace
(
run
=
'only'
)
safe_course_key
=
safe_course_key
.
replace
(
run
=
'only'
)
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
safe_course_key
)
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'org'
,
loc
.
org
)
newrelic
.
agent
.
add_custom_parameter
(
'course_id'
,
safe_course_key
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.path'
,
loc
.
path
)
newrelic
.
agent
.
add_custom_parameter
(
'org'
,
loc
.
org
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.path'
,
loc
.
path
)
# Figure out if this is a CDN using us as the origin.
# Figure out if this is a CDN using us as the origin.
is_from_cdn
=
StaticContentServer
.
is_cdn_request
(
request
)
is_from_cdn
=
StaticContentServer
.
is_cdn_request
(
request
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.from_cdn'
,
is_from_cdn
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.from_cdn'
,
is_from_cdn
)
# Check if this content is locked or not.
# Check if this content is locked or not.
locked
=
self
.
is_content_locked
(
content
)
locked
=
self
.
is_content_locked
(
content
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.locked'
,
locked
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.locked'
,
locked
)
# Check that user has access to the content.
# Check that user has access to the content.
if
not
self
.
is_user_authorized
(
request
,
content
,
loc
):
if
not
self
.
is_user_authorized
(
request
,
content
,
loc
):
...
@@ -153,7 +157,8 @@ class StaticContentServer(object):
...
@@ -153,7 +157,8 @@ class StaticContentServer(object):
response
[
'Content-Length'
]
=
str
(
last
-
first
+
1
)
response
[
'Content-Length'
]
=
str
(
last
-
first
+
1
)
response
.
status_code
=
206
# Partial Content
response
.
status_code
=
206
# Partial Content
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.ranged'
,
True
)
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.ranged'
,
True
)
else
:
else
:
log
.
warning
(
log
.
warning
(
u"Cannot satisfy ranges in Range header:
%
s for content:
%
s"
,
header_value
,
unicode
(
loc
)
u"Cannot satisfy ranges in Range header:
%
s for content:
%
s"
,
header_value
,
unicode
(
loc
)
...
@@ -165,8 +170,9 @@ class StaticContentServer(object):
...
@@ -165,8 +170,9 @@ class StaticContentServer(object):
response
=
HttpResponse
(
content
.
stream_data
())
response
=
HttpResponse
(
content
.
stream_data
())
response
[
'Content-Length'
]
=
content
.
length
response
[
'Content-Length'
]
=
content
.
length
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.content_len'
,
content
.
length
)
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.content_type'
,
content
.
content_type
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.content_len'
,
content
.
length
)
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.content_type'
,
content
.
content_type
)
# "Accept-Ranges: bytes" tells the user that only "bytes" ranges are allowed
# "Accept-Ranges: bytes" tells the user that only "bytes" ranges are allowed
response
[
'Accept-Ranges'
]
=
'bytes'
response
[
'Accept-Ranges'
]
=
'bytes'
...
@@ -194,12 +200,14 @@ class StaticContentServer(object):
...
@@ -194,12 +200,14 @@ class StaticContentServer(object):
# indicate there should be no caching whatsoever.
# indicate there should be no caching whatsoever.
cache_ttl
=
CourseAssetCacheTtlConfig
.
get_cache_ttl
()
cache_ttl
=
CourseAssetCacheTtlConfig
.
get_cache_ttl
()
if
cache_ttl
>
0
and
not
is_locked
:
if
cache_ttl
>
0
and
not
is_locked
:
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.cacheable'
,
True
)
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.cacheable'
,
True
)
response
[
'Expires'
]
=
StaticContentServer
.
get_expiration_value
(
datetime
.
datetime
.
utcnow
(),
cache_ttl
)
response
[
'Expires'
]
=
StaticContentServer
.
get_expiration_value
(
datetime
.
datetime
.
utcnow
(),
cache_ttl
)
response
[
'Cache-Control'
]
=
"public, max-age={ttl}, s-maxage={ttl}"
.
format
(
ttl
=
cache_ttl
)
response
[
'Cache-Control'
]
=
"public, max-age={ttl}, s-maxage={ttl}"
.
format
(
ttl
=
cache_ttl
)
elif
is_locked
:
elif
is_locked
:
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.cacheable'
,
False
)
if
newrelic
:
newrelic
.
agent
.
add_custom_parameter
(
'contentserver.cacheable'
,
False
)
response
[
'Cache-Control'
]
=
"private, no-cache, no-store"
response
[
'Cache-Control'
]
=
"private, no-cache, no-store"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment