Commit 67783f8d by Calen Pennington

Sample more frequently, and always record unexpected cache misses

parent ec2e90f5
...@@ -41,9 +41,10 @@ class Tagger(object): ...@@ -41,9 +41,10 @@ class Tagger(object):
An object used by :class:`QueryTimer` to allow timed code blocks An object used by :class:`QueryTimer` to allow timed code blocks
to add measurements and tags to the timer. to add measurements and tags to the timer.
""" """
def __init__(self): def __init__(self, default_sample_rate):
self.added_tags = [] self.added_tags = []
self.measures = [] self.measures = []
self.sample_rate = default_sample_rate
def measure(self, name, size): def measure(self, name, size):
""" """
...@@ -108,7 +109,7 @@ class QueryTimer(object): ...@@ -108,7 +109,7 @@ class QueryTimer(object):
metric_name: The name used to aggregate all of these metrics. metric_name: The name used to aggregate all of these metrics.
course_context: The course which the query is being made for. course_context: The course which the query is being made for.
""" """
tagger = Tagger() tagger = Tagger(self._sample_rate)
metric_name = "{}.{}".format(self._metric_base, metric_name) metric_name = "{}.{}".format(self._metric_base, metric_name)
start = time() start = time()
...@@ -124,24 +125,24 @@ class QueryTimer(object): ...@@ -124,24 +125,24 @@ class QueryTimer(object):
size, size,
timestamp=end, timestamp=end,
tags=[tag for tag in tags if not tag.startswith('{}:'.format(metric_name))], tags=[tag for tag in tags if not tag.startswith('{}:'.format(metric_name))],
sample_rate=self._sample_rate, sample_rate=tagger.sample_rate,
) )
dog_stats_api.histogram( dog_stats_api.histogram(
'{}.duration'.format(metric_name), '{}.duration'.format(metric_name),
end - start, end - start,
timestamp=end, timestamp=end,
tags=tags, tags=tags,
sample_rate=self._sample_rate, sample_rate=tagger.sample_rate,
) )
dog_stats_api.increment( dog_stats_api.increment(
metric_name, metric_name,
timestamp=end, timestamp=end,
tags=tags, tags=tags,
sample_rate=self._sample_rate, sample_rate=tagger.sample_rate,
) )
TIMER = QueryTimer(__name__, 0.001) TIMER = QueryTimer(__name__, 0.01)
def structure_from_mongo(structure, course_context=None): def structure_from_mongo(structure, course_context=None):
...@@ -231,6 +232,8 @@ class CourseStructureCache(object): ...@@ -231,6 +232,8 @@ class CourseStructureCache(object):
tagger.tag(from_cache=str(compressed_pickled_data is not None).lower()) tagger.tag(from_cache=str(compressed_pickled_data is not None).lower())
if compressed_pickled_data is None: if compressed_pickled_data is None:
# Always log cache misses, because they are unexpected
tagger.sample_rate = 1
return None return None
tagger.measure('compressed_size', len(compressed_pickled_data)) tagger.measure('compressed_size', len(compressed_pickled_data))
...@@ -320,10 +323,15 @@ class MongoConnection(object): ...@@ -320,10 +323,15 @@ class MongoConnection(object):
structure = cache.get(key, course_context) structure = cache.get(key, course_context)
tagger_get_structure.tag(from_cache=str(bool(structure)).lower()) tagger_get_structure.tag(from_cache=str(bool(structure)).lower())
if not structure: if not structure:
# Always log cache misses, because they are unexpected
tagger_get_structure.sample_rate = 1
with TIMER.timer("get_structure.find_one", course_context) as tagger_find_one: with TIMER.timer("get_structure.find_one", course_context) as tagger_find_one:
doc = self.structures.find_one({'_id': key}) doc = self.structures.find_one({'_id': key})
tagger_find_one.measure("blocks", len(doc['blocks'])) tagger_find_one.measure("blocks", len(doc['blocks']))
structure = structure_from_mongo(doc, course_context) structure = structure_from_mongo(doc, course_context)
tagger_find_one.sample_rate = 1
cache.set(key, structure, course_context) cache.set(key, structure, course_context)
return structure return structure
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment