← Back to team overview

graphite-dev team mailing list archive

[Question #176228]: Rolling Standard Deviation for N samples triggers UnboundLocalError in specific cases

 

New question #176228 on Graphite:
https://answers.launchpad.net/graphite/+question/176228

I've discovered that the `stdev` function in graphite.render.functions will cause an UnboundLocalError to be triggered in some instances. 

Basically, it boils down to a local named sumOfSquares not being initialized on the first N items, because the average is None (the sum is None; there is no data in the first N samples). And later in the series, a non-None average appears, and uninitialized sumOfSquares is passed in doStdDev, causing the error.

How can this be triggered? Well, as a simple replication case, if on the Graphite Composer you want to plot the last 24 hours, and you take the standard deviation of some metric that only has data starting 3 hours ago (ie. the data for the first 21 hours is None), then it'll blow up.

-- Andrew Crowell

Also, for some more diagnostics, here is a real, more complicated example, and the traceback demonstrating the problem:

Environment:

Request Method: GET
Request URL: http://graphite2011:8888/render/?width=586&height=308&_salt=1319579730.737&from=-1days&target=movingAverage(diffSeries(load.1min.web.%5Eroll-up%2Cscale(stdev(load.1min.web.%5Eroll-up%2C50)%2C2))%2C100)&target=movingAverage(sum(load.1min.web.%5Eroll-up%2Cscale(stdev(load.1min.web.%5Eroll-up%2C50)%2C2))%2C100)&target=stdev(load.1min.web.%5Eroll-up%2C50)&target=stdev(load.1min.web.%5Eroll-up%2C50)&target=load.1min.web.%5Eroll-up&target=sumSeries(load.1min.web.%5Eroll-up%2Cscale(stdev(load.1min.web.%5Eroll-up%2C50)%2C2))
Django Version: 1.1.1
Python Version: 2.6.5
Installed Applications:
['graphite.metrics',
 'graphite.render',
 'graphite.cli',
 'graphite.browser',
 'graphite.composer',
 'graphite.account',
 'graphite.dashboard',
 'graphite.whitelist',
 'graphite.events',
 'django.contrib.auth',
 'django.contrib.sessions',
 'django.contrib.admin',
 'django.contrib.contenttypes',
 'tagging']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
 'django.middleware.gzip.GZipMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware')


Traceback:
File "/usr/lib/pymodules/python2.6/django/core/handlers/base.py" in get_response
  92.                 response = callback(request, *callback_args, **callback_kwargs)
File "/opt/graphite/webapp/graphite/render/views.py" in renderView
  105.         seriesList = evaluateTarget(requestContext, target)
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTarget
  10.   result = evaluateTokens(requestContext, tokens)
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  21.     return evaluateTokens(requestContext, tokens.expression)
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  28.     args = [evaluateTokens(requestContext, arg) for arg in tokens.call.args]
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  21.     return evaluateTokens(requestContext, tokens.expression)
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  28.     args = [evaluateTokens(requestContext, arg) for arg in tokens.call.args]
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  21.     return evaluateTokens(requestContext, tokens.expression)
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  28.     args = [evaluateTokens(requestContext, arg) for arg in tokens.call.args]
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  21.     return evaluateTokens(requestContext, tokens.expression)
File "/opt/graphite/webapp/graphite/render/evaluator.py" in evaluateTokens
  29.     return func(requestContext, *args)
File "/opt/graphite/webapp/graphite/render/functions.py" in stdev
  1071.         (sd, sumOfSquares) = doStdDev(sumOfSquares, toDrop, series[index+time], time, avg)

Exception Type: UnboundLocalError at /render/
Exception Value: local variable 'sumOfSquares' referenced before assignment


You received this question notification because you are a member of
graphite-dev, which is an answer contact for Graphite.