Documentation
¶
Index ¶
- Constants
- func CompareSampleLabels(a, b []*profilev1.Label) int
- func DropGoTypeParameters(p *profilev1.Profile) *profilev1.Profile
- func FilterLabelsInPlace(labels []*profilev1.Label, keys []int64) int
- func FixGoProfile(p *profilev1.Profile) *profilev1.Profile
- func FromBytes(input []byte, fn func(*profilev1.Profile, int) error) error
- func FromBytesWithLimit(input []byte, maxSize int64, fn func(*profilev1.Profile, int) error) error
- func FromProfile(p *profile.Profile) (*profilev1.Profile, error)
- func FromTree(t *model.FunctionNameTree, ty *typesv1.ProfileType, timeNanos int64) *profilev1.Profile
- func GetLanguage(profile *Profile) string
- func LabelID(p *profilev1.Profile, name string) int64
- func LabelKeysByString(p *profilev1.Profile, keys ...string) []int64
- func LabelKeysMapByString(p *profilev1.Profile, keys ...string) map[string]int64
- func LabelsWithout(labels []*profilev1.Label, keys []int64) []*profilev1.Label
- func Marshal(p *profilev1.Profile, compress bool) ([]byte, error)
- func MustMarshal(p *profilev1.Profile, compress bool) []byte
- func PotentialTruncatedGoStacktraces(p *profilev1.Profile) bool
- func ProfileSpans(p *profilev1.Profile) []uint64
- func ProfileTraceIDs(p *profilev1.Profile) [][16]byte
- func RenameLabel(p *profilev1.Profile, oldName, newName string)
- func RepairGoTruncatedStacktraces(p *profilev1.Profile)
- func RewriteFunctions(p *profilev1.Profile, n []uint32)
- func RewriteLocations(p *profilev1.Profile, n []uint32)
- func RewriteMappings(p *profilev1.Profile, n []uint32)
- func RewriteStrings(p *profilev1.Profile, n []uint32)
- func SetProfileMetadata(p *profilev1.Profile, ty *typesv1.ProfileType, timeNanos int64, period int64)
- func Spans(p *profilev1.Profile, spanIDLabelIdx int64) []uint64
- func TraceIDs(p *profilev1.Profile, traceIDLabelIdx int64) [][16]byte
- func Unmarshal(data []byte, p *profilev1.Profile) error
- func UnmarshalWithLimit(data []byte, p *profilev1.Profile, maxSize int64) error
- func ZeroLabelStrings(p *profilev1.Profile)
- type ErrDecompressedSizeExceedsLimit
- type FunctionKey
- type LabelsByKeyValue
- type LocationKey
- type MappingKey
- type Profile
- type ProfileMerge
- type RewriteTable
- type SampleExporter
- type SampleGroup
- type SampleHasher
- type SampleKey
- type SamplesByLabels
Constants ¶
const ( ProfileIDLabelName = "profile_id" // For compatibility with the existing clients. SpanIDLabelName = "span_id" // Will be supported in the future. TraceIDLabelName = "trace_id" )
Variables ¶
This section is empty.
Functions ¶
func CompareSampleLabels ¶
CompareSampleLabels compares sample label pairs. It's expected that sample labels are sorted. The result will be 0 if a == b, < 0 if a < b, and > 0 if a > b.
func DropGoTypeParameters ¶
DropGoTypeParameters removes of type parameters from Go function names.
In go 1.21 and above, function names include type parameters, however, due to a bug, a function name could include any of the type instances regardless of the call site. Thus, e.g., x[T1].foo and x[T2].foo can't be distinguished in a profile. This leads to incorrect profiles and incorrect flame graphs, and hugely increases cardinality of stack traces.
The function renames x[T1].foo and x[T2].foo to x[...].foo and normalizes the profile, if type parameters are present in the profile. Otherwise, the profile returns unchanged.
func FixGoProfile ¶
FixGoProfile fixes known issues with profiles collected with the standard Go profiler.
Note that the function presumes that p is a Go profile and does not verify this. It is expected that the function is called very early in the profile processing chain and normalized after, regardless of the function outcome.
func FromBytesWithLimit ¶
FromBytesWithLimit reads a profile from bytes with an optional size limit and calls fn with the result. maxSize limits the decompressed size in bytes. Use 0 for no limit. This prevents zip bomb attacks where small compressed data expands to huge sizes.
func FromTree ¶
func FromTree(t *model.FunctionNameTree, ty *typesv1.ProfileType, timeNanos int64) *profilev1.Profile
func GetLanguage ¶
func LabelKeysMapByString ¶
func PotentialTruncatedGoStacktraces ¶
PotentialTruncatedGoStacktraces reports whether there are any chances that the profile may have truncated stack traces.
func ProfileSpans ¶
func ProfileTraceIDs ¶
func RenameLabel ¶
func RepairGoTruncatedStacktraces ¶
RepairGoTruncatedStacktraces repairs truncated stack traces in Go heap profiles.
Go heap profile has a depth limit of 32 frames, which often renders profiles unreadable, and also increases cardinality of stack traces.
The function guesses truncated frames based on neighbors and repairs stack traces if there are high chances that this part is present in the profile. The heuristic is as follows:
For each stack trace S taller than 24 frames: if there is another stack trace R taller than 24 frames that overlaps with the given one by at least 16 frames in a row from the top, and has frames above its root, stack S considered truncated, and the missing part is copied from R.
func RewriteFunctions ¶
func RewriteLocations ¶
func RewriteMappings ¶
func RewriteStrings ¶
func SetProfileMetadata ¶
func SetProfileMetadata(p *profilev1.Profile, ty *typesv1.ProfileType, timeNanos int64, period int64)
SetProfileMetadata sets the metadata on the profile.
func UnmarshalWithLimit ¶
UnmarshalWithLimit unmarshals a profile from bytes with an optional size limit. maxSize limits the decompressed size in bytes. Use 0 for no limit. This prevents zip bomb attacks where small compressed data expands to huge sizes.
func ZeroLabelStrings ¶
Types ¶
type ErrDecompressedSizeExceedsLimit ¶
type ErrDecompressedSizeExceedsLimit struct {
Limit int64
}
func (*ErrDecompressedSizeExceedsLimit) Error ¶
func (e *ErrDecompressedSizeExceedsLimit) Error() string
type FunctionKey ¶
type FunctionKey struct {
// contains filtered or unexported fields
}
func GetFunctionKey ¶
func GetFunctionKey(fn *profilev1.Function) FunctionKey
type LabelsByKeyValue ¶
func (LabelsByKeyValue) Len ¶
func (l LabelsByKeyValue) Len() int
func (LabelsByKeyValue) Less ¶
func (l LabelsByKeyValue) Less(i, j int) bool
func (LabelsByKeyValue) Swap ¶
func (l LabelsByKeyValue) Swap(i, j int)
type LocationKey ¶
type LocationKey struct {
// contains filtered or unexported fields
}
func GetLocationKey ¶
func GetLocationKey(loc *profilev1.Location) LocationKey
type MappingKey ¶
type MappingKey struct {
// contains filtered or unexported fields
}
func GetMappingKey ¶
func GetMappingKey(m *profilev1.Mapping) MappingKey
type Profile ¶
func NewProfile ¶
func NewProfile() *Profile
func RawFromBytes ¶
func RawFromBytesWithLimit ¶
RawFromBytesWithLimit reads a profile from bytes with an optional size limit. maxSize limits the decompressed size in bytes. Use 0 for no limit. This prevents zip bomb attacks where small compressed data expands to huge sizes.
func RawFromProto ¶
func (*Profile) DebugString ¶
func (*Profile) Normalize ¶
func (p *Profile) Normalize()
Normalize normalizes the profile by:
- Removing all duplicate samples (summing their values).
- Removing redundant profile labels (byte => unique of an allocation site) todo: We should reassess if this was a good choice because by merging duplicate stacktrace samples we cannot recompute the allocation per site ("bytes") profile label.
- Removing empty samples.
- Then remove unused references.
- Ensure that the profile has a time_nanos set
- Removes addresses from symbolized profiles.
- Removes elements with invalid references.
- Converts identifiers to indices.
- Ensures that string_table[0] is "".
type ProfileMerge ¶
type ProfileMerge struct {
// contains filtered or unexported fields
}
func (*ProfileMerge) Merge ¶
func (m *ProfileMerge) Merge(p *profilev1.Profile, sanitize bool) error
Merge adds p to the profile merge, cloning new objects. Profile p is modified in place but not retained by the function.
func (*ProfileMerge) MergeBytes ¶
func (m *ProfileMerge) MergeBytes(b []byte, sanitize bool) error
func (*ProfileMerge) Profile ¶
func (m *ProfileMerge) Profile() *profilev1.Profile
type RewriteTable ¶
type RewriteTable[K comparable, V, M any] struct { // contains filtered or unexported fields }
RewriteTable maintains unique values V and their indices. V is never modified nor retained, K and M are kept in memory.
func NewRewriteTable ¶
func NewRewriteTable[K comparable, V, M any]( size int, k func(V) K, v func(V) M, ) RewriteTable[K, V, M]
func (*RewriteTable[K, V, M]) Append ¶
func (t *RewriteTable[K, V, M]) Append(values []V)
func (*RewriteTable[K, V, M]) Index ¶
func (t *RewriteTable[K, V, M]) Index(dst []uint32, values []V)
func (*RewriteTable[K, V, M]) Values ¶
func (t *RewriteTable[K, V, M]) Values() []M
type SampleExporter ¶
type SampleExporter struct {
// contains filtered or unexported fields
}
func NewSampleExporter ¶
func NewSampleExporter(p *profilev1.Profile) *SampleExporter
func (*SampleExporter) ExportSamples ¶
func (e *SampleExporter) ExportSamples(dst *profilev1.Profile, samples []*profilev1.Sample) *profilev1.Profile
ExportSamples creates a new complete profile with the subset of samples provided. It is assumed that those are part of the source profile. Provided samples are modified in place.
The same exporter instance can be used to export non-overlapping sample sets from a single profile.
type SampleGroup ¶
SampleGroup refers to a group of samples that share the same labels. Note that the Span ID label is handled in a special way and is not included in the Labels member but is kept as as a sample label.
func GroupSamplesByLabels ¶
func GroupSamplesByLabels(p *profilev1.Profile) []SampleGroup
GroupSamplesByLabels splits samples into groups by labels. It's expected that sample labels are sorted.
func GroupSamplesWithoutLabels ¶
func GroupSamplesWithoutLabels(p *profilev1.Profile, labels ...string) []SampleGroup
GroupSamplesWithoutLabels splits samples into groups by labels ignoring ones from the list: those are preserved as sample labels. It's expected that sample labels are sorted.
func GroupSamplesWithoutLabelsByKey ¶
func GroupSamplesWithoutLabelsByKey(p *profilev1.Profile, keys []int64) []SampleGroup
type SampleHasher ¶
type SampleHasher struct {
// contains filtered or unexported fields
}
type SampleKey ¶
type SampleKey struct {
// contains filtered or unexported fields
}
func GetSampleKey ¶
type SamplesByLabels ¶
func (SamplesByLabels) Len ¶
func (s SamplesByLabels) Len() int
func (SamplesByLabels) Less ¶
func (s SamplesByLabels) Less(i, j int) bool
func (SamplesByLabels) Swap ¶
func (s SamplesByLabels) Swap(i, j int)