graphite-project / graphite-web

A highly scalable real-time graphing system
http://graphite.readthedocs.org/
Apache License 2.0
5.88k stars 1.26k forks source link

[BUG] `holtWintersConfidenceBands` throws for small enough season_length #2780

Closed npazosmendez closed 1 year ago

npazosmendez commented 1 year ago

Describe the bug

If season_length is < 2 after this calculation

https://github.com/graphite-project/graphite-web/blob/e7d08e6af65c47c5a5dd6421c5b352d7ac3d381c/webapp/graphite/render/functions.py#L4007

then one of these two lines will throw IndexError: list index out of range during the first iteration of the for loop:

https://github.com/graphite-project/graphite-web/blob/e7d08e6af65c47c5a5dd6421c5b352d7ac3d381c/webapp/graphite/render/functions.py#L4057-L4058

This can happen if the series.step is big enough or the seasonality small enough.

The problem comes from the fact that 2 values from the last season are needed on each iteration. So if season_length < 2, this is impossible.

To Reproduce

Run the docker image:

docker run -d  --name graphite  --restart=always  -p 80:80  -p 2003-2004:2003-2004  -p 2023-2024:2023-2024  -p 8125:8125/udp  -p 8126:8126  graphiteapp/graphite-statsd

Query with the following

curl  -G --data-urlencode "format=json" --data-urlencode "target=holtWintersConfidenceBands(summarize(randomWalk('foo'), '30d'), 3)" -H "Accept: application/json"  http://localhost:80/render

<body style="background-color: #666666; color: black;">
<center>
<h2 style='font-family: "Arial", sans-serif'>
<p>Graphite encountered an unexpected error while handling your request.</p>
<p>Please contact your site administrator if the problem persists.</p>
</h2>
<br/>
<div style="width: 50%; text-align: center; font-family: monospace; background-color: black; font-weight: bold; color: #ff4422;">

</div>

<div style="width: 70%; text-align: left; background-color: black; color: #44ff22; border: thin solid gray;">
<pre>
Traceback (most recent call last):
  File &quot;/opt/graphite/lib/python3.9/site-packages/django/core/handlers/exception.py&quot;, line 34, in inner
    response = get_response(request)
  File &quot;/opt/graphite/lib/python3.9/site-packages/django/core/handlers/base.py&quot;, line 115, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File &quot;/opt/graphite/lib/python3.9/site-packages/django/core/handlers/base.py&quot;, line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File &quot;/opt/graphite/webapp/graphite/errors.py&quot;, line 101, in new_f
    return f(*args, **kwargs)
  File &quot;/opt/graphite/webapp/graphite/render/views.py&quot;, line 130, in renderView
    data.extend(evaluateTarget(requestContext, targets))
  File &quot;/opt/graphite/webapp/graphite/render/evaluator.py&quot;, line 34, in evaluateTarget
    result = evaluateTokens(requestContext, target)
  File &quot;/opt/graphite/webapp/graphite/render/evaluator.py&quot;, line 67, in evaluateTokens
    return evaluateTokens(requestContext, tokens.expression, replacements)
  File &quot;/opt/graphite/webapp/graphite/render/evaluator.py&quot;, line 120, in evaluateTokens
    return func(requestContext, *args, **kwargs)
  File &quot;/opt/graphite/webapp/graphite/render/functions.py&quot;, line 4148, in holtWintersConfidenceBands
    analysis = holtWintersAnalysis(series, seasonality)
  File &quot;/opt/graphite/webapp/graphite/render/functions.py&quot;, line 4057, in holtWintersAnalysis
    last_seasonal = getLastSeasonal(i)
  File &quot;/opt/graphite/webapp/graphite/render/functions.py&quot;, line 4019, in getLastSeasonal
    return seasonals[j]
IndexError: list index out of range

</pre>
</div>

</center>

Note: the point of the summarize(..,'30d')` here is to make the step of the series big enough for the exception to happen.

Expected behavior

I am not familiar enough with the holtWinters method to propose an expected behavior. But clamping the season_length so it's not lower than 2 fixes the exception

Environment:

deniszh commented 1 year ago

Hi @npazosmendez

Looks legit, thanks!

deniszh commented 1 year ago

Sould be fixed in #2787