github.com/alibaba/ilogtail/pkg@v0.0.0-20250526110833-c53b480d046c/helper/profile/meta.go (about) 1 // Copyright 2023 iLogtail Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package profile 16 17 import ( 18 "context" 19 "strings" 20 "time" 21 22 "github.com/gofrs/uuid" 23 24 "github.com/alibaba/ilogtail/pkg/protocol" 25 ) 26 27 type Input struct { 28 Profile RawProfile 29 Metadata Meta 30 } 31 32 type Stack struct { 33 Name string 34 Stack []string 35 } 36 37 type Type struct { 38 Name string 39 Kind string 40 } 41 42 var ( 43 CPUType = Type{Name: "cpu", Kind: "profile_cpu"} 44 MemType = Type{Name: "mem", Kind: "profile_mem"} 45 MutexType = Type{Name: "mutex", Kind: "profile_mutex"} 46 BlockType = Type{Name: "block", Kind: "profile_block"} 47 ExceptionType = Type{Name: "exception", Kind: "profile_exception"} 48 GoroutineType = Type{Name: "goroutines", Kind: "profile_goroutines"} 49 UnknownType = Type{Name: "unknown", Kind: "profile_unknown"} 50 ) 51 52 func IsLegalType(t Type) bool { 53 switch t { 54 case CPUType, MemType, MutexType, BlockType, ExceptionType, GoroutineType: 55 return true 56 default: 57 return false 58 } 59 } 60 61 type Format string 62 63 type CallbackFunc func(id uint64, stack *Stack, vals []uint64, types, units, aggs []string, startTime, endTime int64, labels map[string]string) 64 65 const ( 66 FormatPprof Format = "pprof" 67 FormatJFR Format = "jfr" 68 FormatTrie Format = "trie" 69 FormatTree Format = "tree" 70 FormatLines Format = "lines" 71 FormatGroups Format = "groups" 72 FormatSpeedscope Format = "speedscope" 73 ) 74 75 type Meta struct { 76 StartTime time.Time 77 EndTime time.Time 78 Tags map[string]string 79 SpyName string 80 SampleRate uint32 81 Units Units 82 AggregationType AggType 83 } 84 85 type AggType string 86 87 const ( 88 AvgAggType AggType = "avg" 89 SumAggType AggType = "sum" 90 ) 91 92 type Units string 93 94 const ( 95 SamplesUnits Units = "samples" 96 NanosecondsUnit Units = "nanoseconds" 97 ObjectsUnit Units = "objects" 98 BytesUnit Units = "bytes" 99 GoroutinesUnits Units = "goroutines" 100 LockNanosecondsUnits Units = "lock_nanoseconds" 101 LockSamplesUnits Units = "lock_samples" 102 ) 103 104 func DetectProfileType(valType string) Type { 105 switch valType { 106 case "inuse_space", "inuse_objects", "alloc_space", "alloc_objects", "alloc-size", "alloc-samples", "alloc_in_new_tlab_objects", "alloc_in_new_tlab_bytes", "alloc_outside_tlab_objects", "alloc_outside_tlab_bytes": 107 return MemType 108 case "samples", "cpu", "itimer", "lock_count", "lock_duration", "wall": 109 return CPUType 110 case "mutex_count", "mutex_duration", "block_duration", "block_count", "contentions", "delay", "lock-time", "lock-count": 111 return MutexType 112 case "goroutines", "goroutine": 113 return GoroutineType 114 case "exception": 115 return ExceptionType 116 default: 117 return UnknownType 118 } 119 } 120 121 func GetProfileID(meta *Meta) string { 122 var profileIDStr string 123 if id, ok := meta.Tags["profile_id"]; ok { 124 profileIDStr = id 125 } else { 126 profileID, _ := uuid.NewV4() 127 profileIDStr = profileID.String() 128 } 129 return profileIDStr 130 } 131 132 type FormatType string 133 134 // SequenceMapping demo 135 // nodejs: ./node_modules/express/lib/router/index.js:process_params:338 /app/node_modules/express/lib/router/index.js 136 // golang: compress/flate.NewWriter /usr/local/go/src/compress/flate/deflate.go 137 // rust: backtrace_rs.rs:23 - <pprof::backtrace::backtrace_rs::Trace as pprof::backtrace::Trace>::trace 138 // dotnet: System.Threading.Tasks!Task.InternalWaitCore System.Private.CoreLib 139 // ruby: /usr/local/bundle/gems/pyroscope-0.3.0-x86_64-linux/lib/pyroscope.rb:63 - tag_wrapper 140 // python: lib/utility/utility.py:38 - find_nearest_vehicle 141 // java: libjvm.so.AdvancedThresholdPolicy::method_back_branch_event 142 // ebpf: /usr/lib/systemd/systemd+0x93242 143 // php: <internal> - sleep 144 var sequenceMapping = map[FormatType]SequenceType{ 145 PyroscopeNodeJs: FunctionFirst, 146 PyroscopeGolang: FunctionFirst, 147 PyroscopeRust: PosFirst, 148 PyroscopeDotnet: FunctionFirst, 149 PyroscopeRuby: PosFirst, 150 PyroscopePython: PosFirst, 151 PyroscopeJava: FunctionFirst, 152 PyroscopeEbpf: FunctionFirst, 153 PyroscopePhp: PosFirst, 154 Unknown: FunctionFirst, 155 } 156 157 const ( 158 PyroscopeNodeJs = "node" 159 PyroscopeGolang = "go" 160 PyroscopeRust = "rs" 161 PyroscopeDotnet = "dotnet" 162 PyroscopeRuby = "rb" 163 PyroscopePython = "py" 164 PyroscopeJava = "java" 165 PyroscopeEbpf = "ebpf" 166 PyroscopePhp = "php" 167 Unknown = "unknown" 168 ) 169 170 type SequenceType int 171 172 const ( 173 _ SequenceType = iota 174 PosFirst 175 FunctionFirst 176 ) 177 178 func FormatPositionAndName(str string, t FormatType) string { 179 str = strings.TrimSpace(str) 180 idx := strings.Index(str, " ") 181 if idx < 0 { 182 return str // means no position 183 } 184 joiner := func(name, pos string) string { 185 var b strings.Builder 186 b.Grow(len(name) + len(pos) + 1) 187 b.Write([]byte(name)) 188 b.Write([]byte{' '}) 189 b.Write([]byte(pos)) 190 return b.String() 191 } 192 name := str[:idx] 193 idx = strings.LastIndex(str, " ") 194 pos := str[idx+1:] 195 sequenceType := sequenceMapping[t] 196 switch sequenceType { 197 case PosFirst: 198 return joiner(pos, name) 199 case FunctionFirst: 200 return joiner(name, pos) 201 default: 202 return str 203 } 204 } 205 206 func FormatPostionAndNames(strs []string, t FormatType) []string { 207 for i := range strs { 208 strs[i] = FormatPositionAndName(strs[i], t) 209 } 210 return strs 211 } 212 213 func (u Units) DetectValueType() string { 214 switch u { 215 case NanosecondsUnit, SamplesUnits: 216 return "cpu" 217 case ObjectsUnit, BytesUnit: 218 return "mem" 219 case GoroutinesUnits: 220 return "goroutines" 221 case LockSamplesUnits, LockNanosecondsUnits: 222 return "mutex" 223 } 224 return "unknown" 225 } 226 227 type RawProfile interface { 228 Parse(ctx context.Context, meta *Meta, tags map[string]string) (logs []*protocol.Log, err error) 229 }