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") } }
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 } }
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 }
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()) } }
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 }
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 } }
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 } }
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) }