func (api *API) dropSeries(r *http.Request) (interface{}, *apiError) { r.ParseForm() if len(r.Form["match[]"]) == 0 { return nil, &apiError{errorBadData, fmt.Errorf("no match[] parameter provided")} } fps := map[model.Fingerprint]struct{}{} for _, lm := range r.Form["match[]"] { matchers, err := promql.ParseMetricSelector(lm) if err != nil { return nil, &apiError{errorBadData, err} } for fp := range api.Storage.MetricsForLabelMatchers(matchers...) { fps[fp] = struct{}{} } } for fp := range fps { api.Storage.DropMetricsForFingerprints(fp) } res := struct { NumDeleted int `json:"numDeleted"` }{ NumDeleted: len(fps), } return res, nil }
func (api *API) series(r *http.Request) (interface{}, *apiError) { r.ParseForm() if len(r.Form["match[]"]) == 0 { return nil, &apiError{errorBadData, fmt.Errorf("no match[] parameter provided")} } fps := map[clientmodel.Fingerprint]struct{}{} for _, lm := range r.Form["match[]"] { matchers, err := promql.ParseMetricSelector(lm) if err != nil { return nil, &apiError{errorBadData, err} } for _, fp := range api.Storage.FingerprintsForLabelMatchers(matchers) { fps[fp] = struct{}{} } } metrics := make([]clientmodel.Metric, 0, len(fps)) for fp := range fps { if met := api.Storage.MetricForFingerprint(fp).Metric; met != nil { metrics = append(metrics, met) } } return metrics, nil }
func (api *API) series(r *http.Request) (interface{}, *apiError) { r.ParseForm() if len(r.Form["match[]"]) == 0 { return nil, &apiError{errorBadData, fmt.Errorf("no match[] parameter provided")} } res := map[model.Fingerprint]metric.Metric{} for _, lm := range r.Form["match[]"] { matchers, err := promql.ParseMetricSelector(lm) if err != nil { return nil, &apiError{errorBadData, err} } for fp, met := range api.Storage.MetricsForLabelMatchers( model.Earliest, model.Latest, // Get every series. matchers..., ) { res[fp] = met } } metrics := make([]model.Metric, 0, len(res)) for _, met := range res { metrics = append(metrics, met.Metric) } return metrics, nil }
func (api *API) dropSeries(r *http.Request) (interface{}, *apiError) { r.ParseForm() if len(r.Form["match[]"]) == 0 { return nil, &apiError{errorBadData, fmt.Errorf("no match[] parameter provided")} } numDeleted := 0 for _, s := range r.Form["match[]"] { matchers, err := promql.ParseMetricSelector(s) if err != nil { return nil, &apiError{errorBadData, err} } n, err := api.Storage.DropMetricsForLabelMatchers(context.TODO(), matchers...) if err != nil { return nil, &apiError{errorExec, err} } numDeleted += n } res := struct { NumDeleted int `json:"numDeleted"` }{ NumDeleted: numDeleted, } return res, nil }
func (fed *Federation) ServeHTTP(w http.ResponseWriter, req *http.Request) { req.ParseForm() metrics := map[model.Fingerprint]metric.Metric{} for _, s := range req.Form["match[]"] { matchers, err := promql.ParseMetricSelector(s) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } for fp, met := range fed.Storage.MetricsForLabelMatchers(matchers...) { metrics[fp] = met } } format := expfmt.Negotiate(req.Header) w.Header().Set("Content-Type", string(format)) enc := expfmt.NewEncoder(w, format) protMetric := &dto.Metric{ Label: []*dto.LabelPair{}, Untyped: &dto.Untyped{}, } protMetricFam := &dto.MetricFamily{ Metric: []*dto.Metric{protMetric}, Type: dto.MetricType_UNTYPED.Enum(), } for fp, met := range metrics { sp := fed.Storage.LastSamplePairForFingerprint(fp) if sp == nil { continue } // Reset label slice. protMetric.Label = protMetric.Label[:0] for ln, lv := range met.Metric { if ln == model.MetricNameLabel { protMetricFam.Name = proto.String(string(lv)) continue } protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) } protMetric.TimestampMs = (*int64)(&sp.Timestamp) protMetric.Untyped.Value = (*float64)(&sp.Value) if err := enc.Encode(protMetricFam); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } }
func (api *API) series(r *http.Request) (interface{}, *apiError) { r.ParseForm() if len(r.Form["match[]"]) == 0 { return nil, &apiError{errorBadData, fmt.Errorf("no match[] parameter provided")} } var start model.Time if t := r.FormValue("start"); t != "" { var err error start, err = parseTime(t) if err != nil { return nil, &apiError{errorBadData, err} } } else { start = model.Earliest } var end model.Time if t := r.FormValue("end"); t != "" { var err error end, err = parseTime(t) if err != nil { return nil, &apiError{errorBadData, err} } } else { end = model.Latest } var matcherSets []metric.LabelMatchers for _, s := range r.Form["match[]"] { matchers, err := promql.ParseMetricSelector(s) if err != nil { return nil, &apiError{errorBadData, err} } matcherSets = append(matcherSets, matchers) } q, err := api.Storage.Querier() if err != nil { return nil, &apiError{errorExec, err} } defer q.Close() res, err := q.MetricsForLabelMatchers(api.context(r), start, end, matcherSets...) if err != nil { return nil, &apiError{errorExec, err} } metrics := make([]model.Metric, 0, len(res)) for _, met := range res { metrics = append(metrics, met.Metric) } return metrics, nil }
func (api *API) series(r *http.Request) (interface{}, *apiError) { r.ParseForm() if len(r.Form["match[]"]) == 0 { return nil, &apiError{errorBadData, fmt.Errorf("no match[] parameter provided")} } var start model.Time if t := r.FormValue("start"); t != "" { var err error start, err = parseTime(t) if err != nil { return nil, &apiError{errorBadData, err} } } else { start = model.Earliest } var end model.Time if t := r.FormValue("end"); t != "" { var err error end, err = parseTime(t) if err != nil { return nil, &apiError{errorBadData, err} } } else { end = model.Latest } res := map[model.Fingerprint]metric.Metric{} for _, lm := range r.Form["match[]"] { matchers, err := promql.ParseMetricSelector(lm) if err != nil { return nil, &apiError{errorBadData, err} } for fp, met := range api.Storage.MetricsForLabelMatchers( start, end, matchers..., ) { res[fp] = met } } metrics := make([]model.Metric, 0, len(res)) for _, met := range res { metrics = append(metrics, met.Metric) } return metrics, nil }
func (h *Handler) federation(w http.ResponseWriter, req *http.Request) { h.mtx.RLock() defer h.mtx.RUnlock() req.ParseForm() var matcherSets []metric.LabelMatchers for _, s := range req.Form["match[]"] { matchers, err := promql.ParseMetricSelector(s) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } matcherSets = append(matcherSets, matchers) } var ( minTimestamp = h.now().Add(-promql.StalenessDelta) format = expfmt.Negotiate(req.Header) enc = expfmt.NewEncoder(w, format) ) w.Header().Set("Content-Type", string(format)) q, err := h.storage.Querier() if err != nil { federationErrors.Inc() http.Error(w, err.Error(), http.StatusInternalServerError) return } defer q.Close() vector, err := q.LastSampleForLabelMatchers(h.context, minTimestamp, matcherSets...) if err != nil { federationErrors.Inc() http.Error(w, err.Error(), http.StatusInternalServerError) return } sort.Sort(byName(vector)) var ( lastMetricName model.LabelValue protMetricFam *dto.MetricFamily ) for _, s := range vector { nameSeen := false globalUsed := map[model.LabelName]struct{}{} protMetric := &dto.Metric{ Untyped: &dto.Untyped{}, } for ln, lv := range s.Metric { if lv == "" { // No value means unset. Never consider those labels. // This is also important to protect against nameless metrics. continue } if ln == model.MetricNameLabel { nameSeen = true if lv == lastMetricName { // We already have the name in the current MetricFamily, // and we ignore nameless metrics. continue } // Need to start a new MetricFamily. Ship off the old one (if any) before // creating the new one. if protMetricFam != nil { if err := enc.Encode(protMetricFam); err != nil { federationErrors.Inc() log.With("err", err).Error("federation failed") return } } protMetricFam = &dto.MetricFamily{ Type: dto.MetricType_UNTYPED.Enum(), Name: proto.String(string(lv)), } lastMetricName = lv continue } protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) if _, ok := h.externalLabels[ln]; ok { globalUsed[ln] = struct{}{} } } if !nameSeen { log.With("metric", s.Metric).Warn("Ignoring nameless metric during federation.") continue } // Attach global labels if they do not exist yet. for ln, lv := range h.externalLabels { if _, ok := globalUsed[ln]; !ok { protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) } } protMetric.TimestampMs = proto.Int64(int64(s.Timestamp)) protMetric.Untyped.Value = proto.Float64(float64(s.Value)) protMetricFam.Metric = append(protMetricFam.Metric, protMetric) } // Still have to ship off the last MetricFamily, if any. if protMetricFam != nil { if err := enc.Encode(protMetricFam); err != nil { federationErrors.Inc() log.With("err", err).Error("federation failed") } } }
func (h *Handler) federation(w http.ResponseWriter, req *http.Request) { h.mtx.RLock() defer h.mtx.RUnlock() req.ParseForm() metrics := map[model.Fingerprint]metric.Metric{} for _, s := range req.Form["match[]"] { matchers, err := promql.ParseMetricSelector(s) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } for fp, met := range h.storage.MetricsForLabelMatchers(matchers...) { metrics[fp] = met } } format := expfmt.Negotiate(req.Header) w.Header().Set("Content-Type", string(format)) enc := expfmt.NewEncoder(w, format) protMetric := &dto.Metric{ Label: []*dto.LabelPair{}, Untyped: &dto.Untyped{}, } protMetricFam := &dto.MetricFamily{ Metric: []*dto.Metric{protMetric}, Type: dto.MetricType_UNTYPED.Enum(), } for fp, met := range metrics { globalUsed := map[model.LabelName]struct{}{} sp := h.storage.LastSamplePairForFingerprint(fp) if sp == nil { continue } // Reset label slice. protMetric.Label = protMetric.Label[:0] for ln, lv := range met.Metric { if ln == model.MetricNameLabel { protMetricFam.Name = proto.String(string(lv)) continue } protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) if _, ok := h.globalLabels[ln]; ok { globalUsed[ln] = struct{}{} } } // Attach global labels if they do not exist yet. for ln, lv := range h.globalLabels { if _, ok := globalUsed[ln]; !ok { protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) } } protMetric.TimestampMs = (*int64)(&sp.Timestamp) protMetric.Untyped.Value = (*float64)(&sp.Value) if err := enc.Encode(protMetricFam); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } }
func (h *Handler) federation(w http.ResponseWriter, req *http.Request) { h.mtx.RLock() defer h.mtx.RUnlock() req.ParseForm() fps := map[model.Fingerprint]struct{}{} for _, s := range req.Form["match[]"] { matchers, err := promql.ParseMetricSelector(s) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return } for fp := range h.storage.MetricsForLabelMatchers( model.Now().Add(-promql.StalenessDelta), model.Latest, matchers..., ) { fps[fp] = struct{}{} } } var ( minTimestamp = model.Now().Add(-promql.StalenessDelta) format = expfmt.Negotiate(req.Header) enc = expfmt.NewEncoder(w, format) ) w.Header().Set("Content-Type", string(format)) protMetric := &dto.Metric{ Label: []*dto.LabelPair{}, Untyped: &dto.Untyped{}, } protMetricFam := &dto.MetricFamily{ Metric: []*dto.Metric{protMetric}, Type: dto.MetricType_UNTYPED.Enum(), } for fp := range fps { globalUsed := map[model.LabelName]struct{}{} s := h.storage.LastSampleForFingerprint(fp) // Discard if sample does not exist or lays before the staleness interval. if s.Timestamp.Before(minTimestamp) { continue } // Reset label slice. protMetric.Label = protMetric.Label[:0] for ln, lv := range s.Metric { if ln == model.MetricNameLabel { protMetricFam.Name = proto.String(string(lv)) continue } protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) if _, ok := h.externalLabels[ln]; ok { globalUsed[ln] = struct{}{} } } // Attach global labels if they do not exist yet. for ln, lv := range h.externalLabels { if _, ok := globalUsed[ln]; !ok { protMetric.Label = append(protMetric.Label, &dto.LabelPair{ Name: proto.String(string(ln)), Value: proto.String(string(lv)), }) } } protMetric.TimestampMs = proto.Int64(int64(s.Timestamp)) protMetric.Untyped.Value = proto.Float64(float64(s.Value)) if err := enc.Encode(protMetricFam); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } } }