~graphite-dev/graphite/graphite-0.9.8

« back to all changes in this revision

Viewing changes to webapp/graphite/render/functions.py

  • Committer: Chris Davis
  • Date: 2011-04-02 21:07:25 UTC
  • Revision ID: chrismd@gmail.com-20110402210725-f5g0y0wo79ihcyzb
added hitcount() function

Show diffs side-by-side

added added

removed removed

Lines of Context:
631
631
    newSeries.pathExpression = newName
632
632
    results.append(newSeries)
633
633
 
 
634
  return results
 
635
 
 
636
 
 
637
def hitcount(requestContext, seriesList, intervalString):
 
638
  """Estimate hit counts from a list of time series.
 
639
 
 
640
  This function assumes the values in each time series represent
 
641
  hits per second.  It calculates hits per some larger interval
 
642
  such as per day or per hour.  This function is like summarize(),
 
643
  except that it compensates automatically for different time scales
 
644
  (so that a similar graph results from using either fine-grained
 
645
  or coarse-grained records) and handles rarely-occurring events
 
646
  gracefully.
 
647
  """
 
648
  results = []
 
649
  delta = parseTimeOffset(intervalString)
 
650
  interval = int(delta.seconds + (delta.days * 86400))
 
651
 
 
652
  for series in seriesList:
 
653
    length = len(series)
 
654
    step = int(series.step)
 
655
    bucket_count = int(math.ceil(float(series.end - series.start) / interval))
 
656
    buckets = [[] for _ in range(bucket_count)]
 
657
    newStart = int(series.end - bucket_count * interval)
 
658
 
 
659
    for i, value in enumerate(series):
 
660
      if value is None:
 
661
        continue
 
662
 
 
663
      start_time = int(series.start + i * step)
 
664
      start_bucket, start_mod = divmod(start_time - newStart, interval)
 
665
      end_time = start_time + step
 
666
      end_bucket, end_mod = divmod(end_time - newStart, interval)
 
667
 
 
668
      if end_bucket >= bucket_count:
 
669
        end_bucket = bucket_count - 1
 
670
        end_mod = interval
 
671
 
 
672
      if start_bucket == end_bucket:
 
673
        # All of the hits go to a single bucket.
 
674
        if start_bucket >= 0:
 
675
          buckets[start_bucket].append(value * (end_mod - start_mod))
 
676
 
 
677
      else:
 
678
        # Spread the hits among 2 or more buckets.
 
679
        if start_bucket >= 0:
 
680
          buckets[start_bucket].append(value * (interval - start_mod))
 
681
        hits_per_bucket = value * interval
 
682
        for j in range(start_bucket + 1, end_bucket):
 
683
          buckets[j].append(hits_per_bucket)
 
684
        if end_mod > 0:
 
685
          buckets[end_bucket].append(value * end_mod)
 
686
 
 
687
    newValues = [(sum(bucket) if bucket else None) for bucket in buckets]
 
688
    newName = 'hitcount(%s, "%s")' % (series.name, intervalString)
 
689
    newSeries = TimeSeries(newName, newStart, series.end, interval, newValues)
 
690
    newSeries.pathExpression = newName
 
691
    results.append(newSeries)
634
692
 
635
693
  return results
636
694
 
672
730
  'log' : log,
673
731
  'timeShift': timeShift,
674
732
  'summarize' : summarize,
 
733
  'hitcount'  : hitcount,
675
734
 
676
735
  # Calculate functions
677
736
  'movingAverage' : movingAverage,