| 206 | } |
| 207 | |
| 208 | func convertV2RequestToV1(req *cortexpb.PreallocWriteRequestV2, enableTypeAndUnitLabels bool) (cortexpb.PreallocWriteRequest, error) { |
| 209 | var v1Req cortexpb.PreallocWriteRequest |
| 210 | v1Timeseries := make([]cortexpb.PreallocTimeseries, 0, len(req.Timeseries)) |
| 211 | var v1Metadata []*cortexpb.MetricMetadata |
| 212 | |
| 213 | b := labels.NewScratchBuilder(0) |
| 214 | symbols := req.Symbols |
| 215 | for _, v2Ts := range req.Timeseries { |
| 216 | lbs, err := v2Ts.ToLabels(&b, symbols) |
| 217 | if err != nil { |
| 218 | return v1Req, err |
| 219 | } |
| 220 | |
| 221 | if len(v2Ts.Samples) == 0 && len(v2Ts.Histograms) == 0 { |
| 222 | return v1Req, fmt.Errorf("TimeSeries must contain at least one sample or histogram for series %v", lbs.String()) |
| 223 | } |
| 224 | |
| 225 | if int(v2Ts.Metadata.UnitRef) >= len(symbols) { |
| 226 | return v1Req, fmt.Errorf("invalid UnitRef %d: exceeds symbols length %d", v2Ts.Metadata.UnitRef, len(symbols)) |
| 227 | } |
| 228 | |
| 229 | unit := symbols[v2Ts.Metadata.UnitRef] |
| 230 | metricType := v2Ts.Metadata.Type |
| 231 | shouldAttachTypeAndUnitLabels := enableTypeAndUnitLabels && (metricType != cortexpb.METRIC_TYPE_UNSPECIFIED || unit != "") |
| 232 | if shouldAttachTypeAndUnitLabels { |
| 233 | slb := labels.NewScratchBuilder(lbs.Len() + 2) // for __type__ and __unit__ |
| 234 | lbs.Range(func(l labels.Label) { |
| 235 | // Skip __type__ and __unit__ labels to prevent duplication, |
| 236 | // We append these labels from metadata. |
| 237 | if l.Name != model.MetricTypeLabel && l.Name != model.MetricUnitLabel { |
| 238 | slb.Add(l.Name, l.Value) |
| 239 | } |
| 240 | }) |
| 241 | schema.Metadata{Type: cortexpb.MetadataV2MetricTypeToMetricType(metricType), Unit: unit}.AddToLabels(&slb) |
| 242 | slb.Sort() |
| 243 | lbs = slb.Labels() |
| 244 | } |
| 245 | |
| 246 | exemplars, err := convertV2ToV1Exemplars(&b, symbols, v2Ts.Exemplars) |
| 247 | if err != nil { |
| 248 | return v1Req, err |
| 249 | } |
| 250 | |
| 251 | ts := cortexpb.TimeseriesFromPool() |
| 252 | ts.Labels = cortexpb.FromLabelsToLabelAdapters(lbs) |
| 253 | ts.Samples = append(ts.Samples, v2Ts.Samples...) |
| 254 | ts.Exemplars = exemplars |
| 255 | ts.Histograms = append(ts.Histograms, v2Ts.Histograms...) |
| 256 | |
| 257 | v1Timeseries = append(v1Timeseries, cortexpb.PreallocTimeseries{ |
| 258 | TimeSeries: ts, |
| 259 | }) |
| 260 | |
| 261 | if shouldConvertV2Metadata(v2Ts.Metadata) { |
| 262 | metricName, err := extract.MetricNameFromLabels(lbs) |
| 263 | if err != nil { |
| 264 | return v1Req, err |
| 265 | } |