github.com/grafana/pyroscope@v1.18.0/pkg/distributor/model/push.go (about) 1 package model 2 3 import ( 4 v1 "github.com/grafana/pyroscope/api/gen/proto/go/types/v1" 5 "github.com/grafana/pyroscope/pkg/distributor/annotation" 6 "github.com/grafana/pyroscope/pkg/distributor/ingestlimits" 7 "github.com/grafana/pyroscope/pkg/distributor/sampling" 8 phlaremodel "github.com/grafana/pyroscope/pkg/model" 9 "github.com/grafana/pyroscope/pkg/pprof" 10 ) 11 12 type RawProfileType string 13 14 const RawProfileTypePPROF = RawProfileType("pprof") 15 const RawProfileTypeJFR = RawProfileType("jfr") 16 const RawProfileTypeOTEL = RawProfileType("otel") 17 18 type PushRequest struct { 19 Series []*ProfileSeries 20 21 ReceivedCompressedProfileSize int 22 RawProfileType RawProfileType 23 } 24 25 // todo better name 26 type ProfileSeries struct { 27 // Caller provided, modified during processing 28 Labels []*v1.LabelPair 29 Profile *pprof.Profile 30 RawProfile []byte // may be nil if the Profile is composed not from pprof ( e.g. jfr) 31 ID string 32 33 // todo split 34 // Transient state 35 TenantID string 36 Language string 37 38 Annotations []*v1.ProfileAnnotation 39 40 // always 1 todo delete 41 TotalProfiles int64 42 TotalBytesUncompressed int64 43 44 DiscardedProfilesRelabeling int64 45 DiscardedBytesRelabeling int64 46 } 47 48 func (req *ProfileSeries) GetLanguage() string { 49 spyName := phlaremodel.Labels(req.Labels).Get(phlaremodel.LabelNamePyroscopeSpy) 50 if spyName != "" { 51 lang := getProfileLanguageFromSpy(spyName) 52 if lang != "" { 53 return lang 54 } 55 } 56 return "" 57 } 58 59 func getProfileLanguageFromSpy(spyName string) string { 60 switch spyName { 61 default: 62 return "" 63 case "dotnetspy": 64 return "dotnet" 65 case "gospy": 66 return "go" 67 case "phpspy": 68 return "php" 69 case "pyspy": 70 return "python" 71 case "rbspy": 72 return "ruby" 73 case "nodespy": 74 return "nodejs" 75 case "javaspy", "grafana-agent.java": 76 return "java" 77 case "pyroscope-rs": 78 return "rust" 79 } 80 } 81 82 func (req *ProfileSeries) Clone() *ProfileSeries { 83 c := &ProfileSeries{ 84 TenantID: req.TenantID, 85 TotalBytesUncompressed: req.TotalBytesUncompressed, 86 Labels: phlaremodel.Labels(req.Labels).Clone(), 87 Profile: &pprof.Profile{Profile: req.Profile.CloneVT()}, 88 RawProfile: nil, 89 ID: req.ID, 90 Language: req.Language, 91 Annotations: req.Annotations, 92 } 93 return c 94 } 95 96 func (req *ProfileSeries) MarkThrottledTenant(l *ingestlimits.Config) error { 97 a, err := annotation.CreateTenantAnnotation(l) 98 if err != nil { 99 return err 100 } 101 req.Annotations = append(req.Annotations, &v1.ProfileAnnotation{ 102 Key: annotation.ProfileAnnotationKeyThrottled, 103 Value: string(a), 104 }) 105 return nil 106 } 107 108 func (req *ProfileSeries) MarkThrottledUsageGroup(l *ingestlimits.Config, usageGroup string) error { 109 a, err := annotation.CreateUsageGroupAnnotation(l, usageGroup) 110 if err != nil { 111 return err 112 } 113 req.Annotations = append(req.Annotations, &v1.ProfileAnnotation{ 114 Key: annotation.ProfileAnnotationKeyThrottled, 115 Value: string(a), 116 }) 117 return nil 118 } 119 120 func (req *ProfileSeries) MarkSampledRequest(source *sampling.Source) error { 121 a, err := annotation.CreateProfileAnnotation(source) 122 if err != nil { 123 return err 124 } 125 req.Annotations = append(req.Annotations, &v1.ProfileAnnotation{ 126 Key: annotation.ProfileAnnotationKeySampled, 127 Value: string(a), 128 }) 129 return nil 130 }