Exemple #1
0
func (server *Server) serveMetricList(writer http.ResponseWriter, request *http.Request) {
	var offset, limit int

	if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK {
		server.serveResponse(writer, response, status)
		return
	}

	originName := request.FormValue("origin")
	sourceName := request.FormValue("source")

	sourceSet := set.New(set.ThreadSafe)

	if strings.HasPrefix(sourceName, library.LibraryGroupPrefix) {
		for _, entryName := range server.Library.ExpandGroup(
			strings.TrimPrefix(sourceName, library.LibraryGroupPrefix),
			library.LibraryItemSourceGroup,
		) {
			sourceSet.Add(entryName)
		}
	} else if sourceName != "" {
		sourceSet.Add(sourceName)
	}

	metricSet := set.New(set.ThreadSafe)

	for _, origin := range server.Catalog.Origins {
		if originName != "" && origin.Name != originName {
			continue
		}

		for _, source := range origin.Sources {
			if sourceName != "" && sourceSet.IsEmpty() || !sourceSet.IsEmpty() && !sourceSet.Has(source.Name) {
				continue
			}

			for key := range source.Metrics {
				if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), key) {
					continue
				}

				metricSet.Add(key)
			}
		}
	}

	response := &listResponse{
		list:   StringListResponse(set.StringSlice(metricSet)),
		offset: offset,
		limit:  limit,
	}

	server.applyResponseLimit(writer, request, response)

	server.serveResponse(writer, response.list, http.StatusOK)
}
Exemple #2
0
func (server *Server) serveOriginList(writer http.ResponseWriter, request *http.Request) {
	var offset, limit int

	if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK {
		server.serveResponse(writer, response, status)
		return
	}

	originSet := set.New(set.ThreadSafe)

	for _, origin := range server.Catalog.Origins {
		if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), origin.Name) {
			continue
		}

		originSet.Add(origin.Name)
	}

	response := &listResponse{
		list:   StringListResponse(set.StringSlice(originSet)),
		offset: offset,
		limit:  limit,
	}

	server.applyResponseLimit(writer, request, response)

	server.serveResponse(writer, response.list, http.StatusOK)
}
Exemple #3
0
func (server *Server) serveSource(writer http.ResponseWriter, request *http.Request) {
	sourceName := strings.TrimPrefix(request.URL.Path, urlCatalogPath+"sources/")

	if sourceName == "" {
		server.serveSourceList(writer, request)
		return
	} else if response, status := server.parseShowRequest(writer, request); status != http.StatusOK {
		server.serveResponse(writer, response, status)
		return
	}

	originSet := set.New(set.ThreadSafe)

	for _, origin := range server.Catalog.Origins {
		if _, ok := origin.Sources[sourceName]; ok {
			originSet.Add(origin.Name)
		}
	}

	if originSet.Size() == 0 {
		server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound)
		return
	}

	origins := set.StringSlice(originSet)
	sort.Strings(origins)

	response := SourceResponse{
		Name:    sourceName,
		Origins: origins,
	}

	server.serveResponse(writer, response, http.StatusOK)
}
Exemple #4
0
func (server *Server) serveGraphList(writer http.ResponseWriter, request *http.Request) {
	var offset, limit int

	if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK {
		server.serveResponse(writer, response, status)
		return
	}

	graphSet := set.New(set.ThreadSafe)

	// Filter on collection if any
	if request.FormValue("collection") != "" {
		item, err := server.Library.GetItem(request.FormValue("collection"), library.LibraryItemCollection)
		if os.IsNotExist(err) {
			server.serveResponse(writer, serverResponse{mesgResourceNotFound}, http.StatusNotFound)
			return
		} else if err != nil {
			logger.Log(logger.LevelError, "server", "%s", err)
			server.serveResponse(writer, serverResponse{mesgUnhandledError}, http.StatusInternalServerError)
			return
		}

		collection := item.(*library.Collection)

		for _, graph := range collection.Entries {
			graphSet.Add(graph.ID)
		}
	}

	// Fill graphs list
	items := make(ItemListResponse, 0)

	for _, graph := range server.Library.Graphs {
		if !graphSet.IsEmpty() && !graphSet.Has(graph.ID) {
			continue
		}

		if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), graph.Name) {
			continue
		}

		items = append(items, &ItemResponse{
			ID:          graph.ID,
			Name:        graph.Name,
			Description: graph.Description,
			Modified:    graph.Modified.Format(time.RFC3339),
		})
	}

	response := &listResponse{
		list:   items,
		offset: offset,
		limit:  limit,
	}

	server.applyResponseLimit(writer, request, response)

	server.serveResponse(writer, response.list, http.StatusOK)
}
Exemple #5
0
func (server *Server) getStats(writer http.ResponseWriter, request *http.Request) *statsResponse {
	sourceSet := set.New(set.ThreadSafe)
	metricSet := set.New(set.ThreadSafe)

	for _, origin := range server.Catalog.Origins {
		for key, source := range origin.Sources {
			sourceSet.Add(key)

			for key := range source.Metrics {
				metricSet.Add(key)
			}
		}
	}

	return &statsResponse{
		Origins:     len(server.Catalog.Origins),
		Sources:     sourceSet.Size(),
		Metrics:     metricSet.Size(),
		Graphs:      len(server.Library.Graphs),
		Collections: len(server.Library.Collections),
		Groups:      len(server.Library.Groups),
	}
}
Exemple #6
0
// ExpandGroup expands a group returning a list of matching items.
func (library *Library) ExpandGroup(name string, groupType int) []string {

	item, err := library.GetItemByName(name, groupType)
	if err != nil {
		logger.Log(logger.LevelError, "library", "unknown item `%s': %s", name, err)
		return make([]string, 0)
	}

	group := item.(*Group)

	itemSet := set.New(set.ThreadSafe)

	for _, entry := range group.Entries {
		var re *regexp.Regexp

		if strings.HasPrefix(entry.Pattern, LibraryMatchPrefixRegexp) {
			re = regexp.MustCompile(strings.TrimPrefix(entry.Pattern, LibraryMatchPrefixRegexp))
		}

		if _, ok := library.Catalog.Origins[entry.Origin]; !ok {
			logger.Log(logger.LevelError, "library", "unknown group entry `%s'", entry.Origin)
			continue
		}

		if groupType == LibraryItemSourceGroup {
			for _, source := range library.Catalog.Origins[entry.Origin].Sources {
				if strings.HasPrefix(entry.Pattern, LibraryMatchPrefixGlob) {
					if ok, _ := path.Match(strings.TrimPrefix(entry.Pattern, LibraryMatchPrefixGlob),
						source.Name); !ok {
						continue
					}
				} else if strings.HasPrefix(entry.Pattern, LibraryMatchPrefixRegexp) {
					if !re.MatchString(source.Name) {
						continue
					}
				} else if entry.Pattern != source.Name {
					continue
				}

				itemSet.Add(source.Name)
			}
		} else if groupType == LibraryItemMetricGroup {
			for _, source := range library.Catalog.Origins[entry.Origin].Sources {
				for _, metric := range source.Metrics {
					if strings.HasPrefix(entry.Pattern, LibraryMatchPrefixGlob) {
						if ok, _ := path.Match(strings.TrimPrefix(entry.Pattern, LibraryMatchPrefixGlob),
							metric.Name); !ok {
							continue
						}
					} else if strings.HasPrefix(entry.Pattern, LibraryMatchPrefixRegexp) {
						if !re.MatchString(metric.Name) {
							continue
						}
					} else if entry.Pattern != metric.Name {
						continue
					}

					itemSet.Add(metric.Name)
				}
			}
		}
	}

	result := set.StringSlice(itemSet)
	sort.Strings(result)

	return result
}
func (server *Server) serveCollectionList(writer http.ResponseWriter, request *http.Request) {
	var (
		collection    *library.Collection
		offset, limit int
	)

	if response, status := server.parseListRequest(writer, request, &offset, &limit); status != http.StatusOK {
		server.serveResponse(writer, response, status)
		return
	}

	// Check for item exclusion
	excludeSet := set.New(set.ThreadSafe)

	collectionStack := make([]*library.Collection, 0)

	if request.FormValue("exclude") != "" {
		if item, err := server.Library.GetItem(request.FormValue("exclude"), library.LibraryItemCollection); err == nil {
			collectionStack = append(collectionStack, item.(*library.Collection))
		}

		for len(collectionStack) > 0 {
			collection, collectionStack = collectionStack[0], collectionStack[1:]
			excludeSet.Add(collection.ID)
			collectionStack = append(collectionStack, collection.Children...)
		}
	}

	// Fill collections list
	items := make(CollectionListResponse, 0)

	for _, collection := range server.Library.Collections {
		if request.FormValue("parent") != "" && (request.FormValue("parent") == "" &&
			collection.Parent != nil || request.FormValue("parent") != "" &&
			(collection.Parent == nil || collection.Parent.ID != request.FormValue("parent"))) {
			continue
		}

		if request.FormValue("filter") != "" && !utils.FilterMatch(request.FormValue("filter"), collection.Name) {
			continue
		}

		// Skip excluded items
		if excludeSet.Has(collection.ID) {
			continue
		}

		collectionItem := &CollectionResponse{ItemResponse: ItemResponse{
			ID:          collection.ID,
			Name:        collection.Name,
			Description: collection.Description,
			Modified:    collection.Modified.Format(time.RFC3339),
		}, HasChildren: len(collection.Children) > 0}

		if collection.Parent != nil {
			collectionItem.Parent = &collection.Parent.ID
		}

		items = append(items, collectionItem)
	}

	response := &listResponse{
		list:   items,
		offset: offset,
		limit:  limit,
	}

	server.applyResponseLimit(writer, request, response)

	server.serveResponse(writer, response.list, http.StatusOK)
}
Exemple #8
0
// StoreItem stores an item into the library.
func (library *Library) StoreItem(item interface{}, itemType int) error {
	var itemStruct *Item

	switch itemType {
	case LibraryItemSourceGroup, LibraryItemMetricGroup:
		itemStruct = item.(*Group).GetItem()

	case LibraryItemScale:
		itemStruct = item.(*Scale).GetItem()

	case LibraryItemGraph:
		itemStruct = item.(*Graph).GetItem()

	case LibraryItemCollection:
		itemStruct = item.(*Collection).GetItem()

	default:
		return os.ErrInvalid
	}

	if itemStruct.ID == "" {
		uuidTemp, err := uuid.NewV4()
		if err != nil {
			return err
		}

		itemStruct.ID = uuidTemp.String()
	} else if !library.ItemExists(itemStruct.ID, itemType) {
		return os.ErrNotExist
	}

	// Check for name field presence/duplicates
	if itemStruct.Name == "" {
		return os.ErrInvalid
	}

	itemTemp, err := library.GetItemByName(itemStruct.Name, itemType)

	// Item exists, check for duplicates
	if err == nil {
		switch itemType {
		case LibraryItemSourceGroup, LibraryItemMetricGroup:
			if itemTemp.(*Group).ID != itemStruct.ID {
				logger.Log(logger.LevelError, "library", "duplicate group identifier `%s'", itemStruct.ID)
				return os.ErrExist
			}

		case LibraryItemScale:
			if itemTemp.(*Scale).ID != itemStruct.ID {
				logger.Log(logger.LevelError, "library", "duplicate scale identifier `%s'", itemStruct.ID)
				return os.ErrExist
			}

		case LibraryItemGraph:
			if itemTemp.(*Graph).ID != itemStruct.ID {
				logger.Log(logger.LevelError, "library", "duplicate graph identifier `%s'", itemStruct.ID)
				return os.ErrExist
			}

		case LibraryItemCollection:
			if itemTemp.(*Collection).ID != itemStruct.ID {
				logger.Log(logger.LevelError, "library", "duplicate collection identifier `%s'", itemStruct.ID)
				return os.ErrExist
			}
		}
	}

	// Item does not exist, store it into library
	switch itemType {
	case LibraryItemSourceGroup, LibraryItemMetricGroup:
		library.Groups[itemStruct.ID] = item.(*Group)
		library.Groups[itemStruct.ID].ID = itemStruct.ID

	case LibraryItemScale:
		library.Scales[itemStruct.ID] = item.(*Scale)
		library.Scales[itemStruct.ID].ID = itemStruct.ID

	case LibraryItemGraph:
		// Check for definition names duplicates
		groupSet := set.New(set.ThreadSafe)
		serieSet := set.New(set.ThreadSafe)

		for _, group := range item.(*Graph).Groups {
			if group == nil {
				logger.Log(logger.LevelError, "library", "found null group")
				return os.ErrInvalid
			} else if groupSet.Has(group.Name) {
				logger.Log(logger.LevelError, "library", "duplicate group name `%s'", group.Name)
				return os.ErrExist
			}

			groupSet.Add(group.Name)

			for _, serie := range group.Series {
				if serie == nil {
					logger.Log(logger.LevelError, "library", "found null serie in group `%s'", group.Name)
					return os.ErrInvalid
				} else if serieSet.Has(serie.Name) {
					logger.Log(logger.LevelError, "library", "duplicate serie name `%s'", serie.Name)
					return os.ErrExist
				}

				serieSet.Add(serie.Name)
			}
		}

		library.Graphs[itemStruct.ID] = item.(*Graph)
		library.Graphs[itemStruct.ID].ID = itemStruct.ID

	case LibraryItemCollection:
		library.Collections[itemStruct.ID] = item.(*Collection)
		library.Collections[itemStruct.ID].ID = itemStruct.ID
	}

	// Store JSON data
	if err := utils.JSONDump(library.getFilePath(itemStruct.ID, itemType), item, itemStruct.Modified); err != nil {
		return err
	}

	return nil
}