Wrap all newrelic dependencies in a check to see if the module is loaded
This commit is contained in:
@@ -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
|
||||
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
|
||||
|
||||
REQUEST_CACHE_KEY = 'newrelic_custom_metrics'
|
||||
@@ -40,6 +47,8 @@ class NewRelicCustomMetrics(object):
|
||||
"""
|
||||
Report the collected custom metrics to New Relic.
|
||||
"""
|
||||
if not newrelic:
|
||||
return
|
||||
metrics_cache = cls._get_metrics_cache()
|
||||
for metric_name, metric_value in metrics_cache.iteritems():
|
||||
newrelic.agent.add_custom_parameter(metric_name, metric_value)
|
||||
|
||||
@@ -14,7 +14,6 @@ from lxml import etree
|
||||
from xblock.core import XBlock
|
||||
from xblock.fields import Integer, Scope, Boolean, String
|
||||
from xblock.fragment import Fragment
|
||||
import newrelic.agent
|
||||
|
||||
from .exceptions import NotFoundError
|
||||
from .fields import Date
|
||||
@@ -25,6 +24,11 @@ from .xml_module import XmlDescriptor
|
||||
|
||||
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
|
||||
# OBSOLETE: This obsoletes 'type'
|
||||
class_priority = ['video', 'problem']
|
||||
@@ -385,6 +389,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
"""
|
||||
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.display_name', self.display_name or '')
|
||||
newrelic.agent.add_custom_parameter('seq.position', self.position)
|
||||
@@ -396,6 +402,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
the sequence as a whole. We send this information to New Relic so that
|
||||
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
|
||||
# this learning sequence
|
||||
newrelic.agent.add_custom_parameter('seq.num_units', len(display_items))
|
||||
@@ -414,6 +422,8 @@ class SequenceModule(SequenceFields, ProctoringFields, XModule):
|
||||
"""
|
||||
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
|
||||
# weird state where the saved position is out of bounds (e.g. the
|
||||
# content was changed), avoid going into any details about this unit.
|
||||
|
||||
@@ -8,7 +8,6 @@ import logging
|
||||
from collections import OrderedDict
|
||||
from functools import partial
|
||||
|
||||
import newrelic.agent
|
||||
from capa.xqueue_interface import XQueueInterface
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
@@ -82,6 +81,10 @@ from .field_overrides import OverrideFieldData
|
||||
|
||||
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:
|
||||
REQUESTS_AUTH = HTTPBasicAuth(*settings.XQUEUE_INTERFACE['basic_auth'])
|
||||
@@ -966,9 +969,10 @@ def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course
|
||||
except InvalidKeyError:
|
||||
raise Http404
|
||||
|
||||
# Gather metrics for New Relic so we can slice data in New Relic Insights
|
||||
newrelic.agent.add_custom_parameter('course_id', unicode(course_key))
|
||||
newrelic.agent.add_custom_parameter('org', unicode(course_key.org))
|
||||
if newrelic:
|
||||
# Gather metrics for New Relic so we can slice data in New Relic Insights
|
||||
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):
|
||||
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
|
||||
# "handler" in those cases is always just "xmodule_handler".
|
||||
nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler)
|
||||
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'
|
||||
req = django_to_webob_request(request)
|
||||
|
||||
@@ -19,7 +19,14 @@ from django.shortcuts import redirect
|
||||
from courseware.url_helpers import get_redirect_url_for_global_staff
|
||||
from edxmako.shortcuts import render_to_response, render_to_string
|
||||
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
|
||||
|
||||
from xblock.fragment import Fragment
|
||||
@@ -54,7 +61,6 @@ from ..module_render import toc_for_course, get_module_for_descriptor
|
||||
from .views import get_current_child, registered_for_course
|
||||
|
||||
|
||||
log = logging.getLogger("edx.courseware.views.index")
|
||||
TEMPLATE_IMPORTS = {'urllib': urllib}
|
||||
CONTENT_DEPTH = 2
|
||||
|
||||
@@ -174,6 +180,8 @@ class CoursewareIndex(View):
|
||||
"""
|
||||
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('org', unicode(self.course_key.org))
|
||||
|
||||
|
||||
@@ -17,7 +17,13 @@ from django.shortcuts import render_to_response
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.translation import get_language_bidi
|
||||
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 web_fragments.fragment import Fragment
|
||||
@@ -50,13 +56,27 @@ import lms.lib.comment_client as cc
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from contextlib import contextmanager
|
||||
|
||||
THREADS_PER_PAGE = 20
|
||||
INLINE_THREADS_PER_PAGE = 20
|
||||
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):
|
||||
"""
|
||||
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):
|
||||
}
|
||||
|
||||
|
||||
@newrelic.agent.function_trace()
|
||||
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
|
||||
@@ -184,7 +203,6 @@ def inline_discussion(request, course_key, discussion_id):
|
||||
"""
|
||||
Renders JSON for DiscussionModules
|
||||
"""
|
||||
nr_transaction = newrelic.agent.current_transaction()
|
||||
|
||||
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
|
||||
cc_user = cc.User.from_django_user(request.user)
|
||||
@@ -195,12 +213,14 @@ def inline_discussion(request, course_key, discussion_id):
|
||||
except ValueError:
|
||||
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)
|
||||
|
||||
is_staff = has_permission(request.user, 'openclose_thread', course.id)
|
||||
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)
|
||||
|
||||
return utils.JsonResponse({
|
||||
'is_commentable_cohorted': is_commentable_cohorted(course_key, discussion_id),
|
||||
'discussion_data': threads,
|
||||
@@ -219,8 +239,6 @@ def forum_form_discussion(request, course_key):
|
||||
"""
|
||||
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)
|
||||
if request.is_ajax():
|
||||
user = cc.User.from_django_user(request.user)
|
||||
@@ -235,10 +253,10 @@ def forum_form_discussion(request, course_key):
|
||||
except ValueError:
|
||||
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)
|
||||
|
||||
with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
|
||||
with newrelic_function_trace("add_courseware_context"):
|
||||
add_courseware_context(threads, course, request.user)
|
||||
|
||||
return utils.JsonResponse({
|
||||
@@ -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.
|
||||
"""
|
||||
nr_transaction = newrelic.agent.current_transaction()
|
||||
|
||||
course = get_course_with_access(request.user, 'load', course_key, check_if_enrolled=True)
|
||||
|
||||
if request.is_ajax():
|
||||
@@ -278,7 +294,7 @@ def single_thread(request, course_key, discussion_id, thread_id):
|
||||
if not thread:
|
||||
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(
|
||||
course_key,
|
||||
thread,
|
||||
@@ -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)
|
||||
with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
|
||||
with newrelic_function_trace("add_courseware_context"):
|
||||
add_courseware_context([content], course, request.user)
|
||||
|
||||
return utils.JsonResponse({
|
||||
@@ -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.
|
||||
"""
|
||||
nr_transaction = newrelic.agent.current_transaction()
|
||||
context = _create_base_discussion_view_context(request, course_key)
|
||||
course = context['course']
|
||||
course_settings = context['course_settings']
|
||||
@@ -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)
|
||||
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)
|
||||
|
||||
with newrelic.agent.FunctionTrace(nr_transaction, "add_courseware_context"):
|
||||
with newrelic_function_trace("add_courseware_context"):
|
||||
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)
|
||||
|
||||
context.update({
|
||||
@@ -435,9 +450,6 @@ def user_profile(request, course_key, user_id):
|
||||
Renders a response to display the user profile page (shown after clicking
|
||||
on a post author's username).
|
||||
"""
|
||||
|
||||
nr_transaction = newrelic.agent.current_transaction()
|
||||
|
||||
user = cc.User.from_django_user(request.user)
|
||||
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):
|
||||
query_params['page'] = page
|
||||
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()
|
||||
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)
|
||||
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)
|
||||
if request.is_ajax():
|
||||
return utils.JsonResponse({
|
||||
@@ -486,7 +498,7 @@ def user_profile(request, course_key, user_id):
|
||||
course_id=course.id
|
||||
).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)
|
||||
|
||||
context = _create_base_discussion_view_context(request, course_key)
|
||||
@@ -514,9 +526,6 @@ def followed_threads(request, course_key, user_id):
|
||||
"""
|
||||
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)
|
||||
try:
|
||||
profiled_user = cc.User(id=user_id, course_id=course_key)
|
||||
@@ -557,7 +566,7 @@ def followed_threads(request, course_key, user_id):
|
||||
query_params['num_pages'] = paginated_results.num_pages
|
||||
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(
|
||||
course_key,
|
||||
paginated_results.collection,
|
||||
|
||||
@@ -9,7 +9,12 @@ from django.contrib.auth.models import User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.db.utils import DatabaseError
|
||||
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.persist_on_failure import PersistOnFailureTask
|
||||
@@ -31,8 +36,6 @@ from .new.subsection_grade import SubsectionGradeFactory
|
||||
from .signals.signals import SUBSECTION_SCORE_CHANGED
|
||||
from .transformer import GradesTransformer
|
||||
|
||||
log = getLogger(__name__)
|
||||
|
||||
|
||||
class DatabaseNotReadyError(IOError):
|
||||
"""
|
||||
@@ -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)
|
||||
|
||||
newrelic.agent.add_custom_parameter('course_id', unicode(course_key))
|
||||
newrelic.agent.add_custom_parameter('usage_id', unicode(scored_block_usage_key))
|
||||
if newrelic:
|
||||
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,
|
||||
# where this code runs. So we take the values from the
|
||||
|
||||
@@ -4,7 +4,11 @@ Middleware to serve assets.
|
||||
|
||||
import logging
|
||||
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 (
|
||||
HttpResponse, HttpResponseNotModified, HttpResponseForbidden,
|
||||
HttpResponseBadRequest, HttpResponseNotFound, HttpResponsePermanentRedirect)
|
||||
@@ -25,7 +29,6 @@ from .models import CourseAssetCacheTtlConfig, CdnUserAgentsConfig
|
||||
# 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
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
HTTP_DATE_FORMAT = "%a, %d %b %Y %H:%M:%S GMT"
|
||||
|
||||
|
||||
@@ -86,17 +89,18 @@ class StaticContentServer(object):
|
||||
if safe_course_key.run is None:
|
||||
safe_course_key = safe_course_key.replace(run='only')
|
||||
|
||||
newrelic.agent.add_custom_parameter('course_id', safe_course_key)
|
||||
newrelic.agent.add_custom_parameter('org', loc.org)
|
||||
newrelic.agent.add_custom_parameter('contentserver.path', loc.path)
|
||||
if newrelic:
|
||||
newrelic.agent.add_custom_parameter('course_id', safe_course_key)
|
||||
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.
|
||||
is_from_cdn = StaticContentServer.is_cdn_request(request)
|
||||
newrelic.agent.add_custom_parameter('contentserver.from_cdn', is_from_cdn)
|
||||
# Figure out if this is a CDN using us as the origin.
|
||||
is_from_cdn = StaticContentServer.is_cdn_request(request)
|
||||
newrelic.agent.add_custom_parameter('contentserver.from_cdn', is_from_cdn)
|
||||
|
||||
# Check if this content is locked or not.
|
||||
locked = self.is_content_locked(content)
|
||||
newrelic.agent.add_custom_parameter('contentserver.locked', locked)
|
||||
# Check if this content is locked or not.
|
||||
locked = self.is_content_locked(content)
|
||||
newrelic.agent.add_custom_parameter('contentserver.locked', locked)
|
||||
|
||||
# Check that user has access to the content.
|
||||
if not self.is_user_authorized(request, content, loc):
|
||||
@@ -153,7 +157,8 @@ class StaticContentServer(object):
|
||||
response['Content-Length'] = str(last - first + 1)
|
||||
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:
|
||||
log.warning(
|
||||
u"Cannot satisfy ranges in Range header: %s for content: %s", header_value, unicode(loc)
|
||||
@@ -165,8 +170,9 @@ class StaticContentServer(object):
|
||||
response = HttpResponse(content.stream_data())
|
||||
response['Content-Length'] = content.length
|
||||
|
||||
newrelic.agent.add_custom_parameter('contentserver.content_len', content.length)
|
||||
newrelic.agent.add_custom_parameter('contentserver.content_type', content.content_type)
|
||||
if newrelic:
|
||||
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
|
||||
response['Accept-Ranges'] = 'bytes'
|
||||
@@ -194,12 +200,14 @@ class StaticContentServer(object):
|
||||
# indicate there should be no caching whatsoever.
|
||||
cache_ttl = CourseAssetCacheTtlConfig.get_cache_ttl()
|
||||
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['Cache-Control'] = "public, max-age={ttl}, s-maxage={ttl}".format(ttl=cache_ttl)
|
||||
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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user