Ejemplo n.º 1
0
func SetupLogger() {
	if *Logger == "glog" {
		log.InitLogger(&glog.Logger{})
		log.Infof("Using glog logger")
	} else {
		log.InitLogger(&standard.Logger{standard_log.New(os.Stderr, "", standard_log.LstdFlags)})
		log.Infof("Using standard logger")
	}
}
Ejemplo n.º 2
0
func (q queryHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	err := request.ParseForm()
	if err != nil {
		errorResponse(writer, http.StatusBadRequest, err)
		return
	}
	parsedForm := parseQueryForm(request)
	log.Infof("INPUT: %+v\n", parsedForm)

	cmd, err := query.Parse(parsedForm.input)
	if err != nil {
		errorResponse(writer, http.StatusBadRequest, err)
		return
	}

	cmd, profiler := query.NewProfilingCommand(cmd)
	result, err := cmd.Execute(q.context)
	if err != nil {
		errorResponse(writer, http.StatusInternalServerError, err)
		return
	}
	response := response{
		Body: result,
		Name: cmd.Name(),
	}
	if parsedForm.profile {
		response.Profile = convertProfile(profiler)
	}
	bodyResponse(writer, response)
	if q.hook.OnQuery != nil {
		q.hook.OnQuery <- profiler
	}
}
Ejemplo n.º 3
0
func LoadRules(conversionRulesPath string) (RuleSet, error) {
	ruleSet := RuleSet{
		rules: []Rule{},
	}

	filenames, err := filepath.Glob(filepath.Join(conversionRulesPath, "*.yaml"))
	if err != nil {
		return RuleSet{}, err
	}

	sort.Strings(filenames)

	for _, filename := range filenames {
		log.Infof("Loading rules from %s", filename)
		file, err := os.Open(filename)
		if err != nil {
			return RuleSet{}, err
		}
		defer file.Close()

		bytes, err := ioutil.ReadAll(file)
		if err != nil {
			return RuleSet{}, err
		}

		rs, err := LoadYAML(bytes)
		if err != nil {
			return RuleSet{}, err
		}

		ruleSet.rules = append(ruleSet.rules, rs.rules...)
	}

	return ruleSet, nil
}
Ejemplo n.º 4
0
func startServer(config common.UIConfig, context query.ExecutionContext) {
	httpMux := ui.NewMux(config.Config, context, ui.Hook{})

	server := &http.Server{
		Addr:           fmt.Sprintf(":%d", config.Port),
		Handler:        httpMux,
		ReadTimeout:    time.Duration(config.Timeout) * time.Second,
		WriteTimeout:   time.Duration(config.Timeout) * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	err := server.ListenAndServe()
	if err != nil {
		log.Infof(err.Error())
	}
}
Ejemplo n.º 5
0
func LoadRules(conversionRulesPath string) (RuleSet, error) {
	ruleSet := RuleSet{
		Rules: []Rule{},
	}

	filenames, err := filepath.Glob(filepath.Join(conversionRulesPath, "*.yaml"))
	if err != nil {
		return RuleSet{}, err
	}

	sort.Strings(filenames)

	for _, filename := range filenames {
		log.Infof("Loading rules from %s", filename)
		file, err := os.Open(filename)
		if err != nil {
			return RuleSet{}, fmt.Errorf("error opening file %s: %s", filename, err.Error())
		}
		defer file.Close()

		bytes, err := ioutil.ReadAll(file)
		if err != nil {
			return RuleSet{}, fmt.Errorf("error reading file %s: %s", filename, err.Error())
		}

		rs, err := LoadYAML(bytes)
		if err != nil {
			return RuleSet{}, fmt.Errorf("error loading YAML from file %s: %s", filename, err.Error())
		}

		for i := range rs.Rules {
			rs.Rules[i].file = filename
		}

		ruleSet.Rules = append(ruleSet.Rules, rs.Rules...)
	}

	return ruleSet, nil
}
Ejemplo n.º 6
0
func (q queryHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	err := request.ParseForm()
	if err != nil {
		errorResponse(writer, http.StatusBadRequest, err)
		return
	}
	parsedForm := parseQueryForm(request)
	log.Infof("INPUT: %+v\n", parsedForm)

	cmd, err := query.Parse(parsedForm.input)
	if err != nil {
		errorResponse(writer, http.StatusBadRequest, err)
		return
	}

	cmd, profiler := query.NewProfilingCommand(cmd)
	ctx := q.context
	ctx.UserSpecifiableConfig = api.UserSpecifiableConfig{
		IncludeRawData: parsedForm.includeRaw,
	}
	result, err := cmd.Execute(ctx)
	if err != nil {
		errorResponse(writer, http.StatusInternalServerError, err)
		return
	}
	response := response{
		Body:     result.Body,
		Metadata: result.Metadata,
		Name:     cmd.Name(),
	}
	if parsedForm.profile {
		response.Profile = convertProfile(profiler)
	}
	bodyResponse(writer, request, response)
	if q.hook.OnQuery != nil {
		q.hook.OnQuery <- profiler
	}
}
Ejemplo n.º 7
0
func (b *Blueflood) FetchSingleTimeseries(request api.FetchTimeseriesRequest) (api.Timeseries, error) {
	defer request.Profiler.RecordWithDescription("Blueflood FetchSingleTimeseries", request.Metric.String())()
	sampler, ok := samplerMap[request.SampleMethod]
	if !ok {
		return api.Timeseries{}, fmt.Errorf("unsupported SampleMethod %s", request.SampleMethod.String())
	}
	queryResolution := b.config.bluefloodResolution(
		request.Timerange.Resolution(),
		request.Timerange.Start(),
	)
	log.Debugf("Blueflood resolution: %s\n", queryResolution.String())

	// Sample the data at the given `queryResolution`
	queryUrl, err := b.constructURL(request, sampler, queryResolution)
	if err != nil {
		return api.Timeseries{}, err
	}

	rawResults := make([][]byte, 1)
	parsedResult, rawResult, err := b.fetch(request, queryUrl)
	rawResults[0] = rawResult
	if err != nil {
		return api.Timeseries{}, err
	}

	// combinedResult contains the requested data, along with higher-resolution data intended to fill in gaps.
	combinedResult := parsedResult.Values

	// Sample the data at the FULL resolution.
	// We clip the timerange so that it's only #{config.FullResolutionOverlap} seconds long.
	// This limits the amount of data to be fetched.
	fullResolutionParsedResult := func() []metricPoint {
		// If an error occurs, we just return nothing. We don't return the error.
		// This is so that errors while fetching the FULL-resolution data don't impact the requested data.
		fullResolutionRequest := request // Copy the request
		if request.Timerange.End()-request.Timerange.Start() > b.config.FullResolutionOverlap*1000 {
			// Clip the timerange
			newTimerange, err := api.NewSnappedTimerange(request.Timerange.End()-b.config.FullResolutionOverlap*1000, request.Timerange.End(), request.Timerange.ResolutionMillis())
			if err != nil {
				log.Infof("FULL resolution data errored while building timerange: %s", err.Error())
				return nil
			}
			fullResolutionRequest.Timerange = newTimerange
		}
		fullResolutionQueryURL, err := b.constructURL(fullResolutionRequest, sampler, ResolutionFull)
		if err != nil {
			log.Infof("FULL resolution data errored while building url: %s", err.Error())
			return nil
		}
		fullResolutionParsedResult, rawResult, err := b.fetch(request, fullResolutionQueryURL)
		rawResults = append(rawResults, rawResult)
		if err != nil {
			log.Infof("FULL resolution data errored while parsing result: %s", err.Error())
			return nil
		}
		// The higher-resolution data will likely overlap with the requested data.
		// This isn't a problem - the requested, higher-resolution data will be downsampled by this code.
		// This downsampling should arrive at the same answer as Blueflood's built-in rollups.
		return fullResolutionParsedResult.Values
	}()

	combinedResult = append(combinedResult, fullResolutionParsedResult...)

	values := processResult(combinedResult, request.Timerange, sampler, queryResolution)
	log.Debugf("Constructed timeseries from result: %v", values)

	if request.UserSpecifiableConfig.IncludeRawData {
		return api.Timeseries{
			Values: values,
			TagSet: request.Metric.TagSet,
			Raw:    rawResults,
		}, nil
	} else {
		return api.Timeseries{
			Values: values,
			TagSet: request.Metric.TagSet,
		}, nil
	}

}
Ejemplo n.º 8
0
func (h staticHandler) ServeHTTP(writer http.ResponseWriter, request *http.Request) {
	res := h.Directory + request.URL.Path[len(h.StaticPath):]
	log.Infof("url.path=%s, resource=%s\n", request.URL.Path, res)
	http.ServeFile(writer, request, res)
}