예제 #1
0
// Converts the value to a duration in the given units
func (*duration) Call(args ...interface{}) (v interface{}, err error) {
	if len(args) != 1 && len(args) != 2 {
		return time.Duration(0), errors.New("duration expects one or two arguments duration(value, unit) where unit is optional depending on the type of value.")
	}

	getUnit := func() (time.Duration, error) {
		if len(args) != 2 {
			return 0, errors.New("duration expects unit argument for int and float values")
		}
		unit, ok := args[1].(time.Duration)
		if !ok {
			return 0, fmt.Errorf("invalid duration unit type: %T", args[1])
		}
		return unit, nil
	}
	var unit time.Duration
	switch a := args[0].(type) {
	case time.Duration:
		v = a
	case int64:
		unit, err = getUnit()
		v = time.Duration(a) * unit
	case float64:
		unit, err = getUnit()
		v = time.Duration(a * float64(unit))
	case string:
		v, err = influxql.ParseDuration(a)
		if err != nil {
			err = fmt.Errorf("invalid duration string %q", a)
		}
	default:
		err = fmt.Errorf("cannot convert %T to duration", a)
	}
	return
}
예제 #2
0
파일: node.go 프로젝트: yuanwr/kapacitor
// create a new number from a text string
func newDur(p int, text string) (*DurationNode, error) {
	n := &DurationNode{
		pos: pos(p),
	}
	d, err := influxql.ParseDuration(text)
	if err != nil {
		return nil, err
	}
	n.Dur = d
	return n, nil
}
예제 #3
0
// create a new number from a text string
func newDur(p position, text string, c *CommentNode) (*DurationNode, error) {
	n := &DurationNode{
		position: p,
		Comment:  c,
		Literal:  text,
	}
	d, err := influxql.ParseDuration(text)
	if err != nil {
		return nil, err
	}
	n.Dur = d
	return n, nil
}
예제 #4
0
func (vs *Vars) UnmarshalJSON(b []byte) error {
	dec := json.NewDecoder(bytes.NewReader(b))
	dec.UseNumber()
	data := make(map[string]Var)
	err := dec.Decode(&data)
	if err != nil {
		return err
	}
	*vs = make(Vars)
	for name, v := range data {
		if v.Value != nil {
			switch v.Type {
			case VarDuration:
				switch value := v.Value.(type) {
				case json.Number:
					i, err := value.Int64()
					if err != nil {
						return errors.Wrapf(err, "invalid var %v", v)
					}
					v.Value = time.Duration(i)
				case string:
					d, err := influxql.ParseDuration(value)
					if err != nil {
						return errors.Wrapf(err, "invalid duration string for var %s", v)
					}
					v.Value = d
				default:
					return fmt.Errorf("invalid var %v: expected int or string value", v)
				}
			case VarInt:
				n, ok := v.Value.(json.Number)
				if !ok {
					return fmt.Errorf("invalid var %v: expected int value", v)
				}
				v.Value, err = n.Int64()
				if err != nil {
					return errors.Wrapf(err, "invalid var %v", v)
				}
			case VarFloat:
				n, ok := v.Value.(json.Number)
				if !ok {
					return fmt.Errorf("invalid var %v: expected float value", v)
				}
				v.Value, err = n.Float64()
				if err != nil {
					return errors.Wrapf(err, "invalid var %v", v)
				}
			case VarList:
				values, ok := v.Value.([]interface{})
				if !ok {
					return fmt.Errorf("invalid var %v: expected list of vars", v)
				}
				vars := make([]Var, len(values))
				for i := range values {
					m, ok := values[i].(map[string]interface{})
					if !ok {
						return fmt.Errorf("invalid var %v: expected list of vars", v)
					}
					if typeText, ok := m["type"]; ok {
						err := vars[i].Type.UnmarshalText([]byte(typeText.(string)))
						if err != nil {
							return err
						}
					} else {
						return fmt.Errorf("invalid var %v: expected list type key in object", v)
					}
					if value, ok := m["value"]; ok {
						vars[i].Value = value
					} else {
						return fmt.Errorf("invalid var %v: expected list value key in object", v)
					}
				}
				v.Value = vars
			}
		}
		(*vs)[name] = v
	}
	return nil
}
예제 #5
0
파일: main.go 프로젝트: wutaizeng/kapacitor
func doReplayLive(args []string) error {
	var replay client.Replay
	var err error

	noWait := false

	switch args[0] {
	case "batch":
		replayLiveBatchFlags.Parse(args[1:])
		if *rlbTask == "" {
			replayLiveBatchFlags.Usage()
			return errors.New("task is required")
		}
		if *rlbStart == "" && *rlbPast == "" {
			replayLiveBatchFlags.Usage()
			return errors.New("must set one of start or past flags.")
		}
		if *rlbStart != "" && *rlbPast != "" {
			replayLiveBatchFlags.Usage()
			return errors.New("cannot set both start and past flags.")
		}
		start, stop := time.Time{}, time.Now()
		if *rlbStart != "" {
			start, err = time.Parse(time.RFC3339Nano, *rlbStart)
			if err != nil {
				return err
			}
		}
		if *rlbStop != "" {
			stop, err = time.Parse(time.RFC3339Nano, *rlbStop)
			if err != nil {
				return err
			}
		}
		if *rlbPast != "" {
			past, err := influxql.ParseDuration(*rlbPast)
			if err != nil {
				return err
			}
			start = stop.Add(-1 * past)
		}
		noWait = *rlbNowait
		clk := client.Fast
		if *rlbReal {
			clk = client.Real
		}
		replay, err = cli.ReplayBatch(client.ReplayBatchOptions{
			ID:            *rlbId,
			Task:          *rlbTask,
			Start:         start,
			Stop:          stop,
			RecordingTime: *rlbRec,
			Clock:         clk,
		})
		if err != nil {
			return err
		}
	case "query":
		replayLiveQueryFlags.Parse(args[1:])
		if *rlqQuery == "" || *rlqTask == "" {
			replayLiveQueryFlags.Usage()
			return errors.New("both query and task are required")
		}
		noWait = *rlqNowait
		clk := client.Fast
		if *rlqReal {
			clk = client.Real
		}
		replay, err = cli.ReplayQuery(client.ReplayQueryOptions{
			ID:            *rlqId,
			Task:          *rlqTask,
			Query:         *rlqQuery,
			Cluster:       *rlqCluster,
			RecordingTime: *rlqRec,
			Clock:         clk,
		})
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("Unknown replay-live type %q, expected 'batch' or 'query'", args[0])
	}
	if noWait {
		fmt.Println(replay.ID)
		return nil
	}
	for replay.Status == client.Running {
		time.Sleep(500 * time.Millisecond)
		replay, err = cli.Replay(replay.Link)
		if err != nil {
			return err
		}
	}
	fmt.Println(replay.ID)
	if replay.Status == client.Failed {
		if replay.Error == "" {
			replay.Error = "replay failed: unknown reason"
		}
		return errors.New(replay.Error)
	}
	return nil
}
예제 #6
0
파일: main.go 프로젝트: wutaizeng/kapacitor
func doRecord(args []string) error {
	var recording client.Recording
	var err error

	noWait := false

	switch args[0] {
	case "stream":
		recordStreamFlags.Parse(args[1:])
		if *rsTask == "" || *rsDur == "" {
			recordStreamFlags.Usage()
			return errors.New("both task and duration are required")
		}
		var duration time.Duration
		duration, err = influxql.ParseDuration(*rsDur)
		if err != nil {
			return err
		}
		noWait = *rsNowait
		recording, err = cli.RecordStream(client.RecordStreamOptions{
			ID:   *rsId,
			Task: *rsTask,
			Stop: time.Now().Add(duration),
		})
		if err != nil {
			return err
		}
	case "batch":
		recordBatchFlags.Parse(args[1:])
		if *rbTask == "" {
			recordBatchFlags.Usage()
			return errors.New("task is required")
		}
		if *rbStart == "" && *rbPast == "" {
			recordBatchFlags.Usage()
			return errors.New("must set one of start or past flags.")
		}
		if *rbStart != "" && *rbPast != "" {
			recordBatchFlags.Usage()
			return errors.New("cannot set both start and past flags.")
		}
		start, stop := time.Time{}, time.Now()
		if *rbStart != "" {
			start, err = time.Parse(time.RFC3339Nano, *rbStart)
			if err != nil {
				return err
			}
		}
		if *rbStop != "" {
			stop, err = time.Parse(time.RFC3339Nano, *rbStop)
			if err != nil {
				return err
			}
		}
		if *rbPast != "" {
			past, err := influxql.ParseDuration(*rbPast)
			if err != nil {
				return err
			}
			start = stop.Add(-1 * past)
		}
		noWait = *rbNowait
		recording, err = cli.RecordBatch(client.RecordBatchOptions{
			ID:    *rbId,
			Task:  *rbTask,
			Start: start,
			Stop:  stop,
		})
		if err != nil {
			return err
		}
	case "query":
		recordQueryFlags.Parse(args[1:])
		if *rqQuery == "" || *rqType == "" {
			recordQueryFlags.Usage()
			return errors.New("both query and type are required")
		}
		var typ client.TaskType
		switch *rqType {
		case "stream":
			typ = client.StreamTask
		case "batch":
			typ = client.BatchTask
		}
		noWait = *rqNowait
		recording, err = cli.RecordQuery(client.RecordQueryOptions{
			ID:      *rqId,
			Query:   *rqQuery,
			Type:    typ,
			Cluster: *rqCluster,
		})
		if err != nil {
			return err
		}
	default:
		return fmt.Errorf("Unknown record type %q, expected 'stream', 'batch' or 'query'", args[0])
	}
	if noWait {
		fmt.Println(recording.ID)
		return nil
	}
	for recording.Status == client.Running {
		time.Sleep(500 * time.Millisecond)
		recording, err = cli.Recording(recording.Link)
		if err != nil {
			return err
		}
	}
	fmt.Println(recording.ID)
	if recording.Status == client.Failed {
		if recording.Error == "" {
			recording.Error = "recording failed: unknown reason"
		}
		return errors.New(recording.Error)
	}
	return nil
}