Example #1
0
func graphiteExtractPlotResult(plots []graphitePlot) ([]*types.PlotResult, error) {
	var min, max, avg, last float64

	result := make([]*types.PlotResult, 0)

	for _, plot := range plots {
		plotResult := &types.PlotResult{Info: make(map[string]types.PlotValue)}

		for _, plotPoint := range plot.Datapoints {
			plotResult.Plots = append(plotResult.Plots, types.PlotValue(plotPoint[0]))
		}

		// Scan the target legend for serie name and plot min/max/avg/last info
		if index := strings.Index(plots[0].Target, "(min"); index > 0 {
			fmt.Sscanf(plot.Target[0:index], "%s ", &plotResult.Name)
			fmt.Sscanf(plot.Target[index:], "(min: %f) (max: %f) (avg: %f) (last: %f)", &min, &max, &avg, &last)
		}

		plotResult.Info["min"] = types.PlotValue(min)
		plotResult.Info["max"] = types.PlotValue(max)
		plotResult.Info["avg"] = types.PlotValue(avg)
		plotResult.Info["last"] = types.PlotValue(last)

		result = append(result, plotResult)
	}

	return result, nil
}
Example #2
0
func rrdParseInfo(info rrd.GraphInfo, data []*types.PlotResult) {
	refMap := make(map[string]*types.PlotResult)

	for _, entry := range data {
		refMap[entry.Name] = entry
	}

	for _, value := range info.Print {
		chunks := strings.SplitN(value, ",", 3)

		chunkFloat, err := strconv.ParseFloat(chunks[2], 64)
		if err != nil {
			chunkFloat = math.NaN()
		}

		if refMap[chunks[0]] == nil {
			plotResult := &types.PlotResult{Info: make(map[string]types.PlotValue)}

			data = append(data, plotResult)
			refMap[chunks[0]] = plotResult
		}

		refMap[chunks[0]].Info[chunks[1]] = types.PlotValue(chunkFloat)
	}
}
Example #3
0
// GetPlots retrieves time series data from origin based on a query and a time interval.
func (connector *RRDConnector) GetPlots(query *types.PlotQuery) ([]*types.PlotResult, error) {
	var xport *rrd.Exporter

	if len(query.Group.Series) == 0 {
		return nil, fmt.Errorf("group has no series")
	} else if query.Group.Type != OperGroupTypeNone && len(query.Group.Series) == 1 {
		query.Group.Type = OperGroupTypeNone
	}

	result := make([]*types.PlotResult, 0)

	stack := make([]string, 0)

	graph := rrd.NewGrapher()

	if connector.daemon != "" {
		graph.SetDaemon(connector.daemon)
	}

	xport = rrd.NewExporter()

	if connector.daemon != "" {
		xport.SetDaemon(connector.daemon)
	}

	count := 0

	switch query.Group.Type {
	case OperGroupTypeNone:
		for _, serie := range query.Group.Series {
			if serie.Metric == nil {
				continue
			}

			itemName := fmt.Sprintf("serie%d", count)
			count += 1

			graph.Def(
				itemName+"-orig0",
				connector.metrics[serie.Metric.Source][serie.Metric.Name].FilePath,
				connector.metrics[serie.Metric.Source][serie.Metric.Name].Dataset,
				"AVERAGE",
			)

			if serie.Scale != 0 {
				graph.CDef(itemName+"-orig1", fmt.Sprintf("%s-orig0,%g,*", itemName, serie.Scale))
			} else {
				graph.CDef(itemName+"-orig1", itemName+"-orig0")
			}

			if query.Group.Scale != 0 {
				graph.CDef(itemName, fmt.Sprintf("%s-orig1,%g,*", itemName, query.Group.Scale))
			} else {
				graph.CDef(itemName, itemName+"-orig1")
			}

			// Set graph information request
			rrdSetGraph(graph, itemName, query.Percentiles)

			// Set plots request
			xport.Def(
				itemName+"-orig0",
				connector.metrics[serie.Metric.Source][serie.Metric.Name].FilePath,
				connector.metrics[serie.Metric.Source][serie.Metric.Name].Dataset,
				"AVERAGE",
			)

			if serie.Scale != 0 {
				xport.CDef(itemName+"-orig1", fmt.Sprintf("%s-orig0,%g,*", itemName, serie.Scale))
			} else {
				xport.CDef(itemName+"-orig1", itemName+"-orig0")
			}

			if query.Group.Scale != 0 {
				xport.CDef(itemName, fmt.Sprintf("%s-orig1,%g,*", itemName, query.Group.Scale))
			} else {
				xport.CDef(itemName, itemName+"-orig1")
			}

			xport.XportDef(itemName, itemName)
		}

	case OperGroupTypeAvg, OperGroupTypeSum:
		itemName := fmt.Sprintf("serie%d", count)
		count += 1

		for index, serie := range query.Group.Series {
			if serie.Metric == nil {
				continue
			}

			serieTemp := itemName + fmt.Sprintf("-tmp%d", index)

			graph.Def(
				serieTemp+"-ori",
				connector.metrics[serie.Metric.Source][serie.Metric.Name].FilePath,
				connector.metrics[serie.Metric.Source][serie.Metric.Name].Dataset,
				"AVERAGE",
			)

			graph.CDef(serieTemp, fmt.Sprintf("%s-ori,UN,0,%s-ori,IF", serieTemp, serieTemp))

			xport.Def(
				serieTemp+"-ori",
				connector.metrics[serie.Metric.Source][serie.Metric.Name].FilePath,
				connector.metrics[serie.Metric.Source][serie.Metric.Name].Dataset,
				"AVERAGE",
			)

			xport.CDef(serieTemp, fmt.Sprintf("%s-ori,UN,0,%s-ori,IF", serieTemp, serieTemp))

			if len(stack) == 0 {
				stack = append(stack, serieTemp)
			} else {
				stack = append(stack, serieTemp, "+")
			}
		}

		if query.Group.Type == OperGroupTypeAvg {
			stack = append(stack, strconv.Itoa(len(query.Group.Series)), "/")
		}

		graph.CDef(itemName+"-orig", strings.Join(stack, ","))

		if query.Group.Scale != 0 {
			graph.CDef(itemName, fmt.Sprintf("%s-orig,%g,*", itemName, query.Group.Scale))
		} else {
			graph.CDef(itemName, itemName+"-orig")
		}

		// Set graph information request
		rrdSetGraph(graph, itemName, query.Percentiles)

		// Set plots request
		xport.CDef(itemName+"-orig", strings.Join(stack, ","))

		if query.Group.Scale != 0 {
			xport.CDef(itemName, fmt.Sprintf("%s-orig,%g,*", itemName, query.Group.Scale))
		} else {
			xport.CDef(itemName, itemName+"-orig")
		}

		xport.XportDef(itemName, itemName)

	default:
		return nil, fmt.Errorf("unknown operator type %d", query.Group.Type)
	}

	// Get plots
	data := rrd.XportResult{}

	data, err := xport.Xport(query.StartTime, query.EndTime, query.Step)
	if err != nil {
		return nil, err
	}

	for index, itemName := range data.Legends {
		plotResult := &types.PlotResult{
			Name: itemName,
			Info: make(map[string]types.PlotValue),
		}

		for i := 0; i < data.RowCnt; i++ {
			plotResult.Plots = append(plotResult.Plots, types.PlotValue(data.ValueAt(index, i)))
		}

		result = append(result, plotResult)
	}

	// Parse graph information
	graphInfo, _, err := graph.Graph(query.StartTime, query.EndTime)
	if err != nil {
		return nil, err
	}

	rrdParseInfo(graphInfo, result)

	data.FreeValues()

	return result, nil
}