Example #1
0
def evaluateTokens(requestContext, tokens, replacements=None, pipedArg=None):
  if tokens.template:
    arglist = dict()
    if tokens.template.kwargs:
      arglist.update(dict([(kwarg.argname, evaluateScalarTokens(kwarg.args[0])) for kwarg in tokens.template.kwargs]))
    if tokens.template.args:
      arglist.update(dict([(str(i+1), evaluateScalarTokens(arg)) for i, arg in enumerate(tokens.template.args)]))
    if 'template' in requestContext:
      arglist.update(requestContext['template'])
    return evaluateTokens(requestContext, tokens.template, arglist)

  if tokens.expression:
    if tokens.expression.pipedCalls:
      # when the expression has piped calls, we pop the right-most call and pass the remaining
      # expression into it via pipedArg, to get the same result as a nested call
      rightMost = tokens.expression.pipedCalls.pop()
      return evaluateTokens(requestContext, rightMost, replacements, tokens)

    return evaluateTokens(requestContext, tokens.expression, replacements)

  if tokens.pathExpression:
    expression = tokens.pathExpression
    if replacements:
      for name in replacements:
        if expression == '$'+name:
          val = replacements[name]
          if not isinstance(val, six.string_types):
            return val
          elif re.match('^-?[\d.]+$', val):
            return float(val)
          else:
            return val
        else:
          expression = expression.replace('$'+name, str(replacements[name]))
    return fetchData(requestContext, expression)

  if tokens.call:
    if tokens.call.funcname == 'template':
      # if template propagates down here, it means the grammar didn't match the invocation
      # as tokens.template. this generally happens if you try to pass non-numeric/string args
      raise ValueError("invalid template() syntax, only string/numeric arguments are allowed")

    if tokens.call.funcname == 'seriesByTag':
      return fetchData(requestContext, tokens.call.raw)

    func = SeriesFunction(tokens.call.funcname)
    rawArgs = tokens.call.args or []
    if pipedArg is not None:
      rawArgs.insert(0, pipedArg)
    args = [evaluateTokens(requestContext, arg, replacements) for arg in rawArgs]
    requestContext['args'] = rawArgs
    kwargs = dict([(kwarg.argname, evaluateTokens(requestContext, kwarg.args[0], replacements))
                   for kwarg in tokens.call.kwargs])
    try:
      return func(requestContext, *args, **kwargs)
    except NormalizeEmptyResultError:
      return []

  return evaluateScalarTokens(tokens)
Example #2
0
def evaluateTokens(requestContext, tokens):
  if tokens.expression:
    return evaluateTokens(requestContext, tokens.expression)

  elif tokens.pathExpression:
    return fetchData(requestContext, tokens.pathExpression)

  elif tokens.call:
    func = SeriesFunctions[tokens.call.func]
    args = [evaluateTokens(requestContext, arg) for arg in tokens.call.args]
    return func(requestContext, *args)

  elif tokens.number:
    if tokens.number.integer:
      return int(tokens.number.integer)
    elif tokens.number.float:
      return float(tokens.number.float)
    elif tokens.number.scientific:
      return float(tokens.number.scientific[0])

  elif tokens.string:
    return str(tokens.string)[1:-1]

  elif tokens.boolean:
    return tokens.boolean[0] == 'true'
Example #3
0
def evaluateTokens(requestContext, tokens):
  if tokens.expression:
    return evaluateTokens(requestContext, tokens.expression)

  elif tokens.pathExpression:
    return fetchData(requestContext, tokens.pathExpression)

  elif tokens.call:
    func = SeriesFunctions[tokens.call.funcname]
    args = [evaluateTokens(requestContext, arg) for arg in tokens.call.args]
    kwargs = dict([(kwarg.argname, evaluateTokens(requestContext, kwarg.args[0]))
                   for kwarg in tokens.call.kwargs])
    try:
      return func(requestContext, *args, **kwargs)
    except NormalizeEmptyResultError:
      return []

  elif tokens.number:
    if tokens.number.integer:
      return int(tokens.number.integer)
    elif tokens.number.float:
      return float(tokens.number.float)
    elif tokens.number.scientific:
      return float(tokens.number.scientific[0])

  elif tokens.string:
    return tokens.string[1:-1]

  elif tokens.boolean:
    return tokens.boolean[0] == 'true'
Example #4
0
def evaluateTokens(requestContext, tokens):
    if tokens.expression:
        return evaluateTokens(requestContext, tokens.expression)

    elif tokens.pathExpression:
        return fetchData(requestContext, tokens.pathExpression)

    elif tokens.call:
        try:
            func = SeriesFunctions[tokens.call.func]
            args = [
                evaluateTokens(requestContext, arg) for arg in tokens.call.args
            ]
            return func(requestContext, *args)
        except ValueError:
            log.exception('value error when render')
            return []

    elif tokens.number:
        if tokens.number.integer:
            return int(tokens.number.integer)
        elif tokens.number.float:
            return float(tokens.number.float)
        elif tokens.number.scientific:
            return float(tokens.number.scientific[0])

    elif tokens.string:
        return tokens.string[1:-1]

    elif tokens.boolean:
        return tokens.boolean[0] == 'true'
Example #5
0
def evaluateTokens(requestContext, tokens):
    if tokens.expression:
        return evaluateTokens(requestContext, tokens.expression)

    elif tokens.pathExpression:
        return fetchData(requestContext, tokens.pathExpression)

    elif tokens.call:
        func = SeriesFunctions[tokens.call.func]
        args = [
            evaluateTokens(requestContext, arg) for arg in tokens.call.args
        ]
        return func(requestContext, *args)

    elif tokens.number:
        if tokens.number.integer:
            return int(tokens.number.integer)

        elif tokens.number.float:
            return float(tokens.number.float)

    elif tokens.string:
        return str(tokens.string)[1:-1]

    elif tokens.boolean:
        return tokens.boolean[0] == 'true'
Example #6
0
def evaluateTokens(requestContext, tokens):
    if tokens.expression:
        return evaluateTokens(requestContext, tokens.expression)

    elif tokens.pathExpression:
        return fetchData(requestContext, tokens.pathExpression)

    elif tokens.call:
        func = SeriesFunctions[tokens.call.func]
        args = [
            evaluateTokens(requestContext, arg) for arg in tokens.call.args
        ]
        try:
            return func(requestContext, *args)
        except NormalizeEmptyResultError:
            return []

    elif tokens.number:
        if tokens.number.integer:
            return int(tokens.number.integer)
        elif tokens.number.float:
            return float(tokens.number.float)
        elif tokens.number.scientific:
            return float(tokens.number.scientific[0])

    elif tokens.string:
        return str(tokens.string)[1:-1]

    elif tokens.boolean:
        return tokens.boolean[0] == 'true'
Example #7
0
def evaluateTokens(requestContext, tokens):
    if tokens.expression:
        return evaluateTokens(requestContext, tokens.expression)

    elif tokens.pathExpression:
        return fetchData(requestContext, tokens.pathExpression)

    elif tokens.call:
        func = SeriesFunctions[tokens.call.funcname]
        args = [
            evaluateTokens(requestContext, arg) for arg in tokens.call.args
        ]
        kwargs = dict([(kwarg.argname,
                        evaluateTokens(requestContext, kwarg.args[0]))
                       for kwarg in tokens.call.kwargs])
        return func(requestContext, *args, **kwargs)

    elif tokens.number:
        if tokens.number.integer:
            return int(tokens.number.integer)
        elif tokens.number.float:
            return float(tokens.number.float)
        elif tokens.number.scientific:
            return float(tokens.number.scientific[0])

    elif tokens.string:
        return tokens.string[1:-1]

    elif tokens.boolean:
        return tokens.boolean[0] == 'true'
Example #8
0
def evaluateTokens(requestContext, tokens):
  if tokens.expression:
    return evaluateTokens(requestContext, tokens.expression)

  elif tokens.pathExpression:
    return fetchData(requestContext, tokens.pathExpression)

  elif tokens.call:
    try:
      func = SeriesFunctions[tokens.call.func]
      args = [evaluateTokens(requestContext, arg) for arg in tokens.call.args]
      return func(requestContext, *args)
    except ValueError:
      log.exception('value error when render') 
      return []

  elif tokens.number:
    if tokens.number.integer:
      return int(tokens.number.integer)
    elif tokens.number.float:
      return float(tokens.number.float)
    elif tokens.number.scientific:
      return float(tokens.number.scientific[0])

  elif tokens.string:
    return tokens.string[1:-1]

  elif tokens.boolean:
    return tokens.boolean[0] == 'true'
Example #9
0
    def test_fetchData(self):
      pathExpr = 'collectd.test-db.load.value'
      startTime=datetime(1970, 1, 1, 0, 10, 0, 0, pytz.timezone(settings.TIME_ZONE))
      endTime=datetime(1970, 1, 1, 0, 20, 0, 0, pytz.timezone(settings.TIME_ZONE))
      requestContext = self._build_requestContext(startTime, endTime)
      requestContext['now'] = endTime
      requestContext['forwardHeaders'] = None

      results = fetchData(requestContext, pathExpr)
      expectedResults = []
      self.assertEqual(results, expectedResults)
Example #10
0
    def test_fetchData(self):
      pathExpr = 'collectd.test-db.load.value'
      startTime=datetime(1970, 1, 1, 0, 10, 0, 0, pytz.timezone(settings.TIME_ZONE))
      endTime=datetime(1970, 1, 1, 0, 20, 0, 0, pytz.timezone(settings.TIME_ZONE))
      requestContext = self._build_requestContext(startTime, endTime)
      requestContext['now'] = endTime
      requestContext['forwardHeaders'] = None

      results = fetchData(requestContext, pathExpr)
      expectedResults = []
      self.assertEqual(results, expectedResults)
Example #11
0
 def _get(from_time):
     series = fetchData({
         'startTime': from_time,
         'endTime': until_time,
         'now': until_time,
         'localOnly': False},
         metric
     )
     try:
         return [k for k in series[0] if k is not None][-1]
     except IndexError:
         return None
Example #12
0
 def _get(from_time):
     series = fetchData(
         {
             'startTime': from_time,
             'endTime': until_time,
             'now': until_time,
             'localOnly': False
         }, metric)
     try:
         return [k for k in series[0] if k is not None][-1]
     except IndexError:
         return None
Example #13
0
 def test_fetchData_wildcard(self):
     pathExpr = 'collectd.test-db.*.value'
     startTime = datetime(1970, 1, 1, 0, 10, 0, 0,
                          pytz.timezone(settings.TIME_ZONE))
     endTime = datetime(1970, 1, 1, 0, 20, 0, 0,
                        pytz.timezone(settings.TIME_ZONE))
     startTime = datetime(2016, 6, 16, 15, 55, 38)
     endTime = datetime(2016, 6, 17, 15, 55, 38)
     requestContext = self._build_requestContext(startTime, endTime)
     requestContext['now'] = endTime
     print("requestContext: {}".format(requestContext))
     results = fetchData(requestContext, pathExpr)
     expectedResults = []
     print("result_fetchdata: {}".format(results))
     print("expr: {}".format(pathExpr))
     self.assertEqual(results, expectedResults)
Example #14
0
    def test_fetchData_failed_fetch(self, log_exception):
        pathExpr = 'collectd.test-db.load.value'
        startTime = datetime(1970, 1, 1, 0, 10, 0, 0,
                             pytz.timezone(settings.TIME_ZONE))
        endTime = datetime(1970, 1, 1, 0, 20, 0, 0,
                           pytz.timezone(settings.TIME_ZONE))
        requestContext = self._build_requestContext(startTime, endTime)
        requestContext['now'] = endTime
        requestContext['forwardHeaders'] = None

        def mock__fetchData(pathExpr, startTime, endTime, now, requestContext,
                            seriesList):
            raise Exception('mock failure')

        with self.assertRaises(Exception):
            with patch('graphite.render.datalib._fetchData', mock__fetchData):
                results = fetchData(requestContext, pathExpr)
def evaluateTokens(requestContext, tokens, replacements=None):
    if tokens.template:
        arglist = dict()
        if tokens.template.kwargs:
            arglist.update(
                dict([(kwarg.argname,
                       evaluateTokens(requestContext, kwarg.args[0]))
                      for kwarg in tokens.template.kwargs]))
        if tokens.template.args:
            arglist.update(
                dict([(str(i + 1), evaluateTokens(requestContext, arg))
                      for i, arg in enumerate(tokens.template.args)]))
        if 'template' in requestContext:
            arglist.update(requestContext['template'])
        return evaluateTokens(requestContext, tokens.template, arglist)

    elif tokens.expression:
        return evaluateTokens(requestContext, tokens.expression, replacements)

    elif tokens.pathExpression:
        expression = tokens.pathExpression
        if replacements:
            for name in replacements:
                if expression == '$' + name:
                    val = replacements[name]
                    if not isinstance(val, str) and not isinstance(
                            val, basestring):
                        return val
                    elif re.match('^-?[\d.]+$', val):
                        return float(val)
                    else:
                        return val
                else:
                    expression = expression.replace('$' + name,
                                                    str(replacements[name]))
        return fetchData(requestContext, expression)

    elif tokens.call:
        if tokens.call.funcname == 'template':
            # if template propagates down here, it means the grammar didn't match the invocation
            # as tokens.template. this generally happens if you try to pass non-numeric/string args
            raise ValueError(
                "invalid template() syntax, only string/numeric arguments are allowed"
            )

        func = SeriesFunctions[tokens.call.funcname]
        args = [
            evaluateTokens(requestContext, arg, replacements)
            for arg in tokens.call.args
        ]
        kwargs = dict([(kwarg.argname,
                        evaluateTokens(requestContext, kwarg.args[0],
                                       replacements))
                       for kwarg in tokens.call.kwargs])
        try:
            return func(requestContext, *args, **kwargs)
        except NormalizeEmptyResultError:
            return []

    elif tokens.number:
        if tokens.number.integer:
            return int(tokens.number.integer)
        elif tokens.number.float:
            return float(tokens.number.float)
        elif tokens.number.scientific:
            return float(tokens.number.scientific[0])

    elif tokens.string:
        return tokens.string[1:-1]

    elif tokens.boolean:
        return tokens.boolean[0] == 'true'

    else:
        raise ValueError("unknown token in target evaluator")
Example #16
0
def evaluateTokens(requestContext, tokens, replacements=None):
    if tokens.template:
        arglist = dict()
        if tokens.template.kwargs:
            arglist.update(dict([(kwarg.argname, evaluateTokens(requestContext, kwarg.args[0])) for kwarg in tokens.template.kwargs]))
        if tokens.template.args:
            arglist.update(dict([(str(i + 1), evaluateTokens(requestContext, arg)) for i, arg in enumerate(tokens.template.args)]))
        if 'template' in requestContext:
            arglist.update(requestContext['template'])
        return evaluateTokens(requestContext, tokens.template, arglist)

    elif tokens.expression:
        return evaluateTokens(requestContext, tokens.expression, replacements)

    elif tokens.pathExpression:
        expression = tokens.pathExpression
        if replacements:
            for name in replacements:
                if expression == '$' + name:
                    val = replacements[name]
                    if not isinstance(val, str) and not isinstance(val, basestring):
                        return val
                    elif re.match('^-?[\d.]+$', val):
                        return float(val)
                    else:
                        return val
                else:
                    expression = expression.replace('$' + name, str(replacements[name]))
        return fetchData(requestContext, expression)

    elif tokens.call:
        if tokens.call.funcname == 'template':
            # if template propagates down here, it means the grammar didn't match the invocation
            # as tokens.template. this generally happens if you try to pass non-numeric/string args
            raise ValueError("invaild template() syntax, only string/numeric arguments are allowed")

        func = SeriesFunctions[tokens.call.funcname]
        args = [evaluateTokens(requestContext, arg, replacements) for arg in tokens.call.args]
        kwargs = dict([(kwarg.argname, evaluateTokens(requestContext, kwarg.args[0], replacements))
                       for kwarg in tokens.call.kwargs])
        try:
            return func(requestContext, *args, **kwargs)
        except NormalizeEmptyResultError:
            return []

    elif tokens.number:
        if tokens.number.integer:
            return int(tokens.number.integer)
        elif tokens.number.float:
            return float(tokens.number.float)
        elif tokens.number.scientific:
            return float(tokens.number.scientific[0])

    elif tokens.string:
        return tokens.string[1:-1]

    elif tokens.boolean:
        return tokens.boolean[0] == 'true'

    else:
        raise ValueError("unknown token in target evaulator")
def evaluateTokens(requestContext, tokens, replacements=None, pipedArg=None):
  if tokens.template:
    arglist = dict()
    if tokens.template.kwargs:
      arglist.update(dict([(kwarg.argname, evaluateScalarTokens(kwarg.args[0])) for kwarg in tokens.template.kwargs]))
    if tokens.template.args:
      arglist.update(dict([(str(i+1), evaluateScalarTokens(arg)) for i, arg in enumerate(tokens.template.args)]))
    if 'template' in requestContext:
      arglist.update(requestContext['template'])
    return evaluateTokens(requestContext, tokens.template, arglist)

  if tokens.expression:
    if tokens.expression.pipedCalls:
      # when the expression has piped calls, we pop the right-most call and pass the remaining
      # expression into it via pipedArg, to get the same result as a nested call
      rightMost = tokens.expression.pipedCalls.pop()
      return evaluateTokens(requestContext, rightMost, replacements, tokens)

    return evaluateTokens(requestContext, tokens.expression, replacements)

  if tokens.pathExpression:
    expression = tokens.pathExpression
    if replacements:
      for name in replacements:
        if expression == '$'+name:
          val = replacements[name]
          if not isinstance(val, six.string_types):
            return val
          elif re.match(r'^-?[\d.]+$', val):
            return float(val)
          else:
            return val
        else:
          expression = expression.replace('$'+name, str(replacements[name]))
    return fetchData(requestContext, expression)

  if tokens.call:
    if tokens.call.funcname == 'template':
      # if template propagates down here, it means the grammar didn't match the invocation
      # as tokens.template. this generally happens if you try to pass non-numeric/string args
      raise InputParameterError("invalid template() syntax, only string/numeric arguments are allowed")

    if tokens.call.funcname == 'seriesByTag':
      return fetchData(requestContext, tokens.call.raw)

    try:
      func = SeriesFunction(tokens.call.funcname)
    except KeyError:
      raise InputParameterError('Received request for unknown function: {func}'.format(func=tokens.call.funcname))

    rawArgs = tokens.call.args or []
    if pipedArg is not None:
      rawArgs.insert(0, pipedArg)
    args = [evaluateTokens(requestContext, arg, replacements) for arg in rawArgs]
    requestContext['args'] = rawArgs
    kwargs = dict([(kwarg.argname, evaluateTokens(requestContext, kwarg.args[0], replacements))
                   for kwarg in tokens.call.kwargs])

    def handleInvalidParameters(e):
      e.setSourceIdHeaders(requestContext.get('sourceIdHeaders', {}))
      e.setTargets(requestContext.get('targets', []))
      e.setFunction(tokens.call.funcname, args, kwargs)

      if settings.ENFORCE_INPUT_VALIDATION:
        raise e

      if not getattr(handleInvalidParameters, 'alreadyLogged', False):
        log.warning('%s', str(e))

        # only log invalid parameters once
        setattr(handleInvalidParameters, 'alreadyLogged', True)

    if hasattr(func, 'params'):
      try:
        (args, kwargs) = validateParams(tokens.call.funcname, func.params, args, kwargs)
      except InputParameterError as e:
        handleInvalidParameters(e)

    try:
      return func(requestContext, *args, **kwargs)
    except NormalizeEmptyResultError:
      return []
    except InputParameterError as e:
      handleInvalidParameters(e)

  return evaluateScalarTokens(tokens)