@@ -46,6 +46,7 @@ import (
4646	distributormodel "github.com/grafana/pyroscope/pkg/distributor/model" 
4747	"github.com/grafana/pyroscope/pkg/distributor/sampling" 
4848	"github.com/grafana/pyroscope/pkg/distributor/writepath" 
49+ 	"github.com/grafana/pyroscope/pkg/featureflags" 
4950	phlaremodel "github.com/grafana/pyroscope/pkg/model" 
5051	"github.com/grafana/pyroscope/pkg/model/pprofsplit" 
5152	"github.com/grafana/pyroscope/pkg/model/relabel" 
@@ -248,7 +249,14 @@ func (d *Distributor) Push(ctx context.Context, grpcReq *connect.Request[pushv1.
248249		Series :         make ([]* distributormodel.ProfileSeries , 0 , len (grpcReq .Msg .Series )),
249250		RawProfileType : distributormodel .RawProfileTypePPROF ,
250251	}
252+ 
251253	allErrors  :=  multierror .New ()
254+ 
255+ 	clientCapabilities , parseErr  :=  featureflags .ParseClientCapabilities (grpcReq .Header ())
256+ 	if  parseErr  !=  nil  {
257+ 		allErrors .Add (parseErr )
258+ 	}
259+ 
252260	for  _ , grpcSeries  :=  range  grpcReq .Msg .Series  {
253261		for  _ , grpcSample  :=  range  grpcSeries .Samples  {
254262			profile , err  :=  pprof .RawFromBytes (grpcSample .RawProfile )
@@ -257,10 +265,11 @@ func (d *Distributor) Push(ctx context.Context, grpcReq *connect.Request[pushv1.
257265				continue 
258266			}
259267			series  :=  & distributormodel.ProfileSeries {
260- 				Labels :     grpcSeries .Labels ,
261- 				Profile :    profile ,
262- 				RawProfile : grpcSample .RawProfile ,
263- 				ID :         grpcSample .ID ,
268+ 				Labels :             grpcSeries .Labels ,
269+ 				Profile :            profile ,
270+ 				RawProfile :         grpcSample .RawProfile ,
271+ 				ID :                 grpcSample .ID ,
272+ 				ClientCapabilities : clientCapabilities ,
264273			}
265274			req .Series  =  append (req .Series , series )
266275		}
@@ -630,10 +639,11 @@ func (d *Distributor) aggregate(ctx context.Context, req *distributormodel.Profi
630639				return  handleErr 
631640			}
632641			aggregated  :=  & distributormodel.ProfileSeries {
633- 				TenantID :    req .TenantID ,
634- 				Labels :      labels ,
635- 				Profile :     pprof .RawFromProto (p .Profile ()),
636- 				Annotations : annotations ,
642+ 				TenantID :           req .TenantID ,
643+ 				Labels :             labels ,
644+ 				Profile :            pprof .RawFromProto (p .Profile ()),
645+ 				Annotations :        annotations ,
646+ 				ClientCapabilities : req .ClientCapabilities ,
637647			}
638648			return  d .router .Send (localCtx , aggregated )
639649		})()
@@ -1132,9 +1142,10 @@ func (d *Distributor) visitSampleSeries(s *distributormodel.ProfileSeries, visit
11321142	var  result  []* distributormodel.ProfileSeries 
11331143	usageGroups  :=  d .usageGroupEvaluator .GetMatch (s .TenantID , usageConfig , s .Labels )
11341144	visitor  :=  & sampleSeriesVisitor {
1135- 		tenantID : s .TenantID ,
1136- 		limits :   d .limits ,
1137- 		profile :  s .Profile ,
1145+ 		tenantID :           s .TenantID ,
1146+ 		limits :             d .limits ,
1147+ 		profile :            s .Profile ,
1148+ 		clientCapabilities : s .ClientCapabilities ,
11381149	}
11391150	if  err  :=  visit (s .Profile .Profile , s .Labels , relabelingRules , visitor ); err  !=  nil  {
11401151		validation .DiscardedProfiles .WithLabelValues (string (validation .ReasonOf (err )), s .TenantID ).Add (float64 (s .TotalProfiles ))
@@ -1164,24 +1175,28 @@ func (d *Distributor) visitSampleSeries(s *distributormodel.ProfileSeries, visit
11641175}
11651176
11661177type  sampleSeriesVisitor  struct  {
1167- 	tenantID  string 
1168- 	limits    Limits 
1169- 	profile   * pprof.Profile 
1170- 	exp       * pprof.SampleExporter 
1171- 	series    []* distributormodel.ProfileSeries 
1178+ 	tenantID            string 
1179+ 	limits              Limits 
1180+ 	profile             * pprof.Profile 
1181+ 	exp                 * pprof.SampleExporter 
1182+ 	series              []* distributormodel.ProfileSeries 
1183+ 	clientCapabilities  []* featureflags.ClientCapability 
11721184
11731185	discardedBytes     int 
11741186	discardedProfiles  int 
11751187}
11761188
11771189func  (v  * sampleSeriesVisitor ) ValidateLabels (labels  phlaremodel.Labels ) error  {
1178- 	return  validation .ValidateLabels (v .limits , v .tenantID , labels )
1190+ 	capability  :=  featureflags .GetClientCapability (v .clientCapabilities , featureflags .AllowUtf8LabelNamesCapabilityName )
1191+ 	utf8LabelNamesEnabled  :=  capability  !=  nil  &&  capability .Value  ==  "true" 
1192+ 	return  validation .ValidateLabels (v .limits , v .tenantID , utf8LabelNamesEnabled , labels )
11791193}
11801194
11811195func  (v  * sampleSeriesVisitor ) VisitProfile (labels  phlaremodel.Labels ) {
11821196	v .series  =  append (v .series , & distributormodel.ProfileSeries {
1183- 		Profile : v .profile ,
1184- 		Labels :  labels ,
1197+ 		Profile :            v .profile ,
1198+ 		Labels :             labels ,
1199+ 		ClientCapabilities : v .clientCapabilities ,
11851200	})
11861201}
11871202
0 commit comments