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  }