Skip to content

Commit

Permalink
cherrypicking trunk revs 514-516
Browse files Browse the repository at this point in the history
  • Loading branch information
cdavis committed Aug 11, 2011
2 parents 825d199 + 2e80669 commit fbe737e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/config-carbon.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ Here's a more complicated example with multiple retention rates:
[apache_busyWorkers]
pattern = servers\.www.*\.workers\.busyWorkers$
retentions = 15s:7d,1min:21d,15min:5y
retentions = 15s:7d,1m:21d,15m:5y
The pattern matches server names that start with 'www', followed by anything, that end in '.workers.busyWorkers'. This way not all metrics associated with your webservers need this type of retention.

Expand Down
2 changes: 2 additions & 0 deletions docs/tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ mechanisms to store the values in a variety of ways, including RRD. To send coll
- Jordan Sissel's node collectd-to-graphite_ proxy
- Joe Miller's perl collectd-graphite_ plugin
- Gregory Szorc's python collectd-carbon_ plugin
- Scott Sanders's C collectd-write_graphite_ plugin

Graphite can also read directly from `collectd`_'s RRD files. RRD files can
simply be added to ``STORAGE_DIR/rrd`` (as long as directory names and files do not
Expand Down Expand Up @@ -69,6 +70,7 @@ Learn more here, http://code.google.com/p/rocksteady/
.. _collectd-to-graphite: https://github.com/loggly/collectd-to-graphite
.. _collectd-carbon: https://github.com/indygreg/collectd-carbon
.. _collectd-graphite: https://github.com/joemiller/collectd-graphite
.. _collectd-write_graphite: https://github.com/jssjr/collectd-write_graphite
.. _Logster: https://github.com/etsy/logster
.. _RabbitMQ: http://www.rabbitmq.com/
.. _Esper: http://esper.codehaus.org/
40 changes: 32 additions & 8 deletions webapp/graphite/render/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -1201,7 +1201,7 @@ def exclude(requestContext, seriesList, pattern):
return [s for s in seriesList if not regex.search(s.name)]


def summarize(requestContext, seriesList, intervalString, func='sum'):
def summarize(requestContext, seriesList, intervalString, func='sum', alignToFrom=False):
"""
Summarize the data into interval buckets of a certain size.
Expand All @@ -1214,6 +1214,14 @@ def summarize(requestContext, seriesList, intervalString, func='sum'):
'max', 'min' or 'last' can also be specified.
By default, buckets are caculated by rounding to the nearest interval. This
works well for intervals smaller than a day. For example, 22:32 will end up
in the bucket 22:00-23:00 when the interval=1hour.
Passing alignToFrom=true will instead create buckets starting at the from
time. In this case, the bucket for 22:32 depends on the from time. If
from=6:30 then the 1hour bucket for 22:32 is 22:30-23:30.
Example:
.. code-block:: none
Expand All @@ -1222,6 +1230,7 @@ def summarize(requestContext, seriesList, intervalString, func='sum'):
&target=summarize(nonNegativeDerivative(gauge.num_users), "1week") # new users per week
&target=summarize(queue.size, "1hour", "avg") # average queue size per hour
&target=summarize(queue.size, "1hour", "max") # maximum queue size during each hour
&target=summarize(metric, "13week", "avg", true)&from=midnight+20100101 # 2010 Q1-4
"""
results = []
delta = parseTimeOffset(intervalString)
Expand All @@ -1234,20 +1243,32 @@ def summarize(requestContext, seriesList, intervalString, func='sum'):
datapoints = zip(timestamps, series)

for (timestamp, value) in datapoints:
bucketInterval = int((timestamp - series.start) / interval)
if alignToFrom:
bucketInterval = int((timestamp - series.start) / interval)
else:
bucketInterval = timestamp - (timestamp % interval)

if bucketInterval not in buckets:
buckets[bucketInterval] = []

if value is not None:
buckets[bucketInterval].append(value)

newStart = series.start
newEnd = series.end
if alignToFrom:
newStart = series.start
newEnd = series.end
else:
newStart = series.start - (series.start % interval)
newEnd = series.end - (series.end % interval) + interval

newValues = []
for timestamp in range( int(series.start), int(series.end), interval ):
newEnd = timestamp
bucketInterval = int((timestamp - series.start) / interval)
for timestamp in range(newStart, newEnd, interval):
if alignToFrom:
newEnd = timestamp
bucketInterval = int((timestamp - series.start) / interval)
else:
bucketInterval = timestamp - (timestamp % interval)

bucket = buckets.get(bucketInterval, [])

if bucket:
Expand All @@ -1264,8 +1285,11 @@ def summarize(requestContext, seriesList, intervalString, func='sum'):
else:
newValues.append( None )

if alignToFrom:
newEnd += interval

newName = "summarize(%s, \"%s\")" % (series.name, intervalString)
newSeries = TimeSeries(newName, newStart, newEnd + interval, interval, newValues)
newSeries = TimeSeries(newName, newStart, newEnd, interval, newValues)
newSeries.pathExpression = newName
results.append(newSeries)

Expand Down

0 comments on commit fbe737e

Please sign in to comment.