This file is indexed.

/usr/lib/python2.7/dist-packages/graphite/metrics/search.py is in graphite-web 0.9.12+debian-6.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
import time
import subprocess
import os.path
from django.conf import settings
from graphite.logger import log
from graphite.storage import is_pattern, match_entries


class IndexSearcher:
  def __init__(self, index_path):
    self.index_path = index_path
    if not os.path.exists(index_path):
      open(index_path, 'w').close()  # touch the file to prevent re-entry down this code path
      #XXX This is garbagy, should been handled natively, forking a shell to
      #build the index is less than ideal
      build_index_path = os.path.join(settings.GRAPHITE_ROOT, "bin/build-index.sh")
      retcode = subprocess.call(build_index_path)
      if retcode != 0:
        log.exception("Couldn't build index file %s" % index_path)
        raise RuntimeError("Couldn't build index file %s" % index_path)
    self.last_mtime = 0
    self._tree = (None, {})  # (data, children)
    log.info("[IndexSearcher] performing initial index load")
    self.reload()

  @property
  def tree(self):
    current_mtime = os.path.getmtime(self.index_path)
    if current_mtime > self.last_mtime:
      log.info("[IndexSearcher] reloading stale index, current_mtime=%s last_mtime=%s" %
               (current_mtime, self.last_mtime))
      self.reload()

    return self._tree

  def reload(self):
    log.info("[IndexSearcher] reading index data from %s" % self.index_path)
    t = time.time()
    total_entries = 0
    tree = (None, {})  # (data, children)
    for line in open(self.index_path):
      line = line.strip()
      if not line:
        continue

      branches = line.split('.')
      leaf = branches.pop()
      parent = None
      cursor = tree
      for branch in branches:
        if branch not in cursor[1]:
          cursor[1][branch] = (None, {})  # (data, children)
        parent = cursor
        cursor = cursor[1][branch]

      cursor[1][leaf] = (line, {})
      total_entries += 1

    self._tree = tree
    self.last_mtime = os.path.getmtime(self.index_path)
    log.info("[IndexSearcher] index reload took %.6f seconds (%d entries)" % (time.time() - t, total_entries))

  def search(self, query, max_results=None, keep_query_pattern=False):
    query_parts = query.split('.')
    metrics_found = set()
    for result in self.subtree_query(self.tree, query_parts):
      # Overlay the query pattern on the resulting paths
      if keep_query_pattern:
        path_parts = result['path'].split('.')
        result['path'] = '.'.join(query_parts) + result['path'][len(query_parts):]

      if result['path'] in metrics_found:
        continue
      yield result

      metrics_found.add(result['path'])
      if max_results is not None and len(metrics_found) >= max_results:
        return

  def subtree_query(self, root, query_parts):
    if query_parts:
      my_query = query_parts[0]
      if is_pattern(my_query):
        matches = [root[1][node] for node in match_entries(root[1], my_query)]
      elif my_query in root[1]:
        matches = [root[1][my_query]]
      else:
        matches = []

    else:
      matches = root[1].values()

    for child_node in matches:
      result = {
        'path': child_node[0],
        'is_leaf': bool(child_node[0]),
      }
      if result['path'] is not None and not result['is_leaf']:
        result['path'] += '.'
      yield result

      if query_parts:
        for result in self.subtree_query(child_node, query_parts[1:]):
          yield result


class SearchIndexCorrupt(StandardError):
  pass


searcher = IndexSearcher(settings.INDEX_FILE)