Пример #1
0
// PrepareCollection applies options defaults and fallback values, then filters entries by graphs titles and state.
func (library *Library) PrepareCollection(collection *Collection, filter string) *Collection {
	collectionTemp := &Collection{}
	*collectionTemp = *collection
	collectionTemp.Entries = nil

	refreshInterval, _ := config.GetInt(collectionTemp.Options, "refresh_interval", false)

	for _, entry := range collection.Entries {
		item, err := library.GetItem(entry.ID, LibraryItemGraph)
		if err != nil {
			continue
		}

		graph := item.(*Graph)

		// Initialize options map if needed, then set defaults
		if entry.Options == nil {
			entry.Options = make(map[string]interface{})
			entry.Options["enabled"] = true
		}

		// Check for linked graph
		if graph.Link != "" {
			entry.Options["linked"] = true
		}

		// Retrieve missing title from graph if none provided
		if title, ok := entry.Options["title"]; !ok || title == nil {
			if graph.Title != "" {
				entry.Options["title"] = graph.Title
			} else {
				entry.Options["title"] = graph.Name
			}
		}

		// Get global refresh interval if none provided
		if refreshInterval > 0 {
			if _, err := config.GetInt(entry.Options, "refresh_interval", true); err != nil {
				entry.Options["refresh_interval"] = refreshInterval
			}
		}

		if enabled, err := config.GetBool(entry.Options, "enabled", false); err != nil || !enabled {
			continue
		} else if filter != "" {
			if title, err := config.GetString(entry.Options, "title", false); err != nil ||
				!strings.Contains(strings.ToLower(title), strings.ToLower(filter)) {
				continue
			}
		}

		collectionTemp.Entries = append(collectionTemp.Entries, entry)
	}

	return collectionTemp
}
Пример #2
0
func init() {
	Connectors["facette"] = func(name string, settings map[string]interface{}) (Connector, error) {
		var err error

		c := &FacetteConnector{name: name}

		if c.upstream, err = config.GetString(settings, "upstream", true); err != nil {
			return nil, err
		}

		if c.timeout, err = config.GetInt(settings, "timeout", false); err != nil {
			return nil, err
		}
		if c.timeout <= 0 {
			c.timeout = facetteDefaultTimeout
		}

		if c.insecureTLS, err = config.GetBool(settings, "allow_insecure_tls", false); err != nil {
			return nil, err
		}

		if c.serverID, err = config.GetString(settings, "_id", true); err != nil {
			return nil, err
		}

		return c, nil
	}
}
Пример #3
0
func init() {
	Connectors["graphite"] = func(name string, settings map[string]interface{}) (Connector, error) {
		var (
			pattern string
			err     error
		)

		c := &GraphiteConnector{
			name:   name,
			series: make(map[string]map[string]string),
		}

		if c.url, err = config.GetString(settings, "url", true); err != nil {
			return nil, err
		}

		if c.timeout, err = config.GetInt(settings, "timeout", false); err != nil {
			return nil, err
		}
		if c.timeout <= 0 {
			c.timeout = graphiteDefaultTimeout
		}

		if c.insecureTLS, err = config.GetBool(settings, "allow_insecure_tls", false); err != nil {
			return nil, err
		}

		if pattern, err = config.GetString(settings, "pattern", true); err != nil {
			return nil, err
		}
		if c.re, err = compilePattern(pattern); err != nil {
			return nil, fmt.Errorf("unable to compile regexp pattern: %s", err)
		}

		return c, nil
	}
}
Пример #4
0
func init() {
	Connectors["kairosdb"] = func(name string, settings map[string]interface{}) (Connector, error) {
		var (
			aggregators interface{}
			err         error
		)

		c := &KairosdbConnector{
			name:    name,
			timeout: kairosdbDefaultTimeout,
			series:  make(map[string]map[string]kairosdbSeriesEntry),
		}

		if c.url, err = config.GetString(settings, "url", true); err != nil {
			return nil, err
		}

		if c.timeout, err = config.GetInt(settings, "timeout", false); err != nil {
			return nil, err
		}
		if c.timeout <= 0 {
			c.timeout = kairosdbDefaultTimeout
		}

		if c.insecureTLS, err = config.GetBool(settings, "allow_insecure_tls", false); err != nil {
			return nil, err
		}

		if c.sourceTags, err = config.GetStringSlice(settings, "source_tags", false); err != nil {
			return nil, err
		}

		if c.startAbsolute, err = config.GetInt(settings, "start_absolute", false); err != nil {
			return nil, err
		}
		if c.endAbsolute, err = config.GetInt(settings, "end_absolute", false); err != nil {
			return nil, err
		}

		if c.startRelative, err = config.GetJsonObj(settings, "start_relative", false); err != nil {
			return nil, err
		}
		if c.endRelative, err = config.GetJsonObj(settings, "end_relative", false); err != nil {
			return nil, err
		}

		if c.defaultAggregator, err = config.GetJsonObj(settings, "default_aggregator", false); err != nil {
			return nil, err
		}

		if aggregators, err = config.GetJsonArray(settings, "aggregators", false); err != nil {
			return nil, err
		}

		c.aggregators = compileAggregatorPatterns(aggregators, c.name)

		if c.startAbsolute > 0 && c.startRelative != nil {
			return nil, fmt.Errorf("kairosdb[%s]: start_absolute/start_relative are mutually exclusive", c.name)
		}
		if c.endAbsolute > 0 && c.endRelative != nil {
			return nil, fmt.Errorf("kairosdb[%s]: end_absolute/end_relative are mutually exclusive", c.name)
		}

		// Enforce startRelative defaults
		if c.startAbsolute <= 0 && c.startRelative == nil {
			c.startRelative = map[string]interface{}{"value": 3, "unit": "months"}
		}

		// Enforce sourceTags defaults
		if c.sourceTags == nil {
			c.sourceTags = []string{"host", "server", "device"}
		}

		version, version_array, err := kairosdbGetVersion(c)
		if err != nil {
			return nil, fmt.Errorf("kairosdb[%s]: unable to get KairosDB version: %s", c.name, err)
		}

		if version_array[0] < 1 {
			if version_array[1] <= 9 {
				if version_array[1] < 9 || (version_array[1] == 9 && version_array[2] < 4) {
					return nil, fmt.Errorf(
						"kairosdb[%s]: only KairosDB version 0.9.4 and greater are supported (%s detected)",
						c.name,
						version,
					)
				}
			}
		}

		return c, nil
	}
}
Пример #5
0
func makePlotsResponse(plotSeries map[string][]plot.Series, plotReq *PlotRequest,
	graph *library.Graph) (*PlotResponse, error) {

	response := &PlotResponse{
		ID:          graph.ID,
		Start:       plotReq.startTime.Format(time.RFC3339),
		End:         plotReq.endTime.Format(time.RFC3339),
		Name:        graph.Name,
		Description: graph.Description,
		Title:       graph.Title,
		Type:        graph.Type,
		StackMode:   graph.StackMode,
		UnitType:    graph.UnitType,
		UnitLegend:  graph.UnitLegend,
		Modified:    graph.Modified,
	}

	for _, groupItem := range graph.Groups {
		var (
			groupConsolidate int
			groupSeries      []plot.Series
			err              error
		)

		seriesOptions := make(map[string]map[string]interface{})

		for _, seriesItem := range groupItem.Series {
			if _, ok := plotSeries[seriesItem.Name]; !ok {
				return nil, fmt.Errorf("unable to find plots for `%s' series", seriesItem.Name)
			}

			for _, plotItem := range plotSeries[seriesItem.Name] {
				var optionKey string

				// Apply series scale if any
				if scale, _ := config.GetFloat(seriesItem.Options, "scale", false); scale != 0 {
					plotItem.Scale(plot.Value(scale))
				}

				// Merge options from group and series
				if groupItem.Type == plot.OperTypeAverage || groupItem.Type == plot.OperTypeSum {
					optionKey = groupItem.Name
				} else {
					optionKey = seriesItem.Name
				}

				seriesOptions[optionKey] = make(map[string]interface{})
				for key, value := range groupItem.Options {
					seriesOptions[optionKey][key] = value
				}
				if groupItem.Type != plot.OperTypeAverage && groupItem.Type != plot.OperTypeSum {
					for key, value := range seriesItem.Options {
						seriesOptions[optionKey][key] = value
					}
				}

				groupSeries = append(groupSeries, plotItem)
			}
		}

		if len(groupSeries) == 0 {
			continue
		}

		// Normalize all series plots on the same time step
		groupConsolidate, err = config.GetInt(groupItem.Options, "consolidate", true)
		if err != nil {
			groupConsolidate = plot.ConsolidateAverage
		}

		groupSeries, err = plot.Normalize(
			groupSeries,
			plotReq.startTime,
			plotReq.endTime,
			plotReq.Sample,
			groupConsolidate,
		)
		if err != nil {
			return nil, fmt.Errorf("unable to consolidate series: %s", err)
		}

		// Perform requested series operations
		if groupItem.Type == plot.OperTypeAverage || groupItem.Type == plot.OperTypeSum {
			var (
				operSeries plot.Series
				err        error
			)

			if groupItem.Type == plot.OperTypeAverage {
				operSeries, err = plot.AverageSeries(groupSeries)
				if err != nil {
					return nil, fmt.Errorf("unable to average series: %s", err)
				}
			} else {
				operSeries, err = plot.SumSeries(groupSeries)
				if err != nil {
					return nil, fmt.Errorf("unable to sum series: %s", err)
				}
			}

			operSeries.Name = groupItem.Name

			groupSeries = []plot.Series{operSeries}
		}

		// Apply group scale if any
		if scale, _ := config.GetFloat(groupItem.Options, "scale", false); scale != 0 {
			for _, seriesItem := range groupSeries {
				seriesItem.Scale(plot.Value(scale))
			}
		}

		for _, seriesItem := range groupSeries {
			// Summarize each series (compute min/max/avg/last values)
			seriesItem.Summarize(plotReq.Percentiles)

			response.Series = append(response.Series, &SeriesResponse{
				Name:    seriesItem.Name,
				StackID: groupItem.StackID,
				Plots:   seriesItem.Plots,
				Summary: seriesItem.Summary,
				Options: seriesOptions[seriesItem.Name],
			})
		}
	}

	return response, nil
}