@@ -19,6 +19,7 @@ package profilingmetricsconnector // import "github.com/elastic/opentelemetry-co
1919
2020import (
2121 "fmt"
22+ "log/slog"
2223 "regexp"
2324
2425 "go.opentelemetry.io/collector/pdata/pcommon"
@@ -44,19 +45,20 @@ const (
4445)
4546
4647var (
47- metricUser = metric {name : "samples.user.count" , desc : "Number of samples executing userspace code (self)" }
48- metricKernel = metric {name : "samples.kernel.count" , desc : "Number of samples executing kernel code (self)" }
49- metricNative = metric {name : "samples.native.count" , desc : "Number of samples executing native code (self)" }
50- metricJVM = metric {name : "samples.jvm.count" , desc : "Number of samples executing HotSpot code (self)" }
51- metricPython = metric {name : "samples.cpython.count" , desc : "Number of samples executing Python code (self)" }
52- metricGo = metric {name : "samples.go.count" , desc : "Number of samples executing Go code (self)" }
53- metricV8JS = metric {name : "samples.v8js.count" , desc : "Number of samples executing V8 JS code (self)" }
54- metricPHP = metric {name : "samples.php.count" , desc : "Number of samples executing PHP code (self)" }
55- metricPerl = metric {name : "samples.perl.count" , desc : "Number of samples executing Perl code (self)" }
56- metricRuby = metric {name : "samples.ruby.count" , desc : "Number of samples executing Ruby code (self)" }
57- metricDotnet = metric {name : "samples.dotnet.count" , desc : "Number of samples executing Dotnet code (self)" }
58- metricRust = metric {name : "samples.rust.count" , desc : "Number of samples executing Rust code (self)" }
59- metricBeam = metric {name : "samples.beam.count" , desc : "Number of samples executing Beam code (self)" }
48+ metricUser = metric {name : "samples.user.count" , desc : "Number of samples executing userspace code (self)" }
49+ metricKernel = metric {name : "samples.kernel.count" , desc : "Number of samples executing kernel code (self)" }
50+ metricSyscall = metric {name : "samples.syscall.count" , desc : "Number of samples executing syscall code (self)" }
51+ metricNative = metric {name : "samples.native.count" , desc : "Number of samples executing native code (self)" }
52+ metricJVM = metric {name : "samples.jvm.count" , desc : "Number of samples executing HotSpot code (self)" }
53+ metricPython = metric {name : "samples.cpython.count" , desc : "Number of samples executing Python code (self)" }
54+ metricGo = metric {name : "samples.go.count" , desc : "Number of samples executing Go code (self)" }
55+ metricV8JS = metric {name : "samples.v8js.count" , desc : "Number of samples executing V8 JS code (self)" }
56+ metricPHP = metric {name : "samples.php.count" , desc : "Number of samples executing PHP code (self)" }
57+ metricPerl = metric {name : "samples.perl.count" , desc : "Number of samples executing Perl code (self)" }
58+ metricRuby = metric {name : "samples.ruby.count" , desc : "Number of samples executing Ruby code (self)" }
59+ metricDotnet = metric {name : "samples.dotnet.count" , desc : "Number of samples executing Dotnet code (self)" }
60+ metricRust = metric {name : "samples.rust.count" , desc : "Number of samples executing Rust code (self)" }
61+ metricBeam = metric {name : "samples.beam.count" , desc : "Number of samples executing Beam code (self)" }
6062
6163 allowedFrameTypes = map [string ]metric {
6264 frameTypeNative : metricNative ,
7779 rx = regexp .MustCompile (`(?:.*/)?(.+)\.so` )
7880
7981 // match syscalls
80- syscallRx = regexp .MustCompile (`^__ (?:x64|arm64)_sys_ (\w+)` )
82+ syscallRx = regexp .MustCompile (`^(?:__x64_sys|__arm64_sys|ksys)_ (\w+)` )
8183)
8284
8385func fetchLeafFrameInfo (dictionary pprofile.ProfilesDictionary ,
@@ -155,10 +157,8 @@ func fetchLeafFrameInfo(dictionary pprofile.ProfilesDictionary,
155157// classifyFrame classifies sample into one or more categories based on frame type.
156158// This takes place by incrementing the associated metric count.
157159func classifyFrame (dictionary pprofile.ProfilesDictionary ,
158- locationIndices pcommon.Int32Slice ,
159- sample pprofile.Sample ,
160- counts map [metric ]int64 ,
161- nativeCounts map [string ]int64 ,
160+ locationIndices pcommon.Int32Slice , sample pprofile.Sample ,
161+ counts map [metric ]int64 , nativeCounts map [string ]int64 ,
162162) error {
163163 leaf , err := fetchLeafFrameInfo (dictionary , locationIndices , 0 )
164164 if err != nil {
@@ -196,11 +196,8 @@ func classifyFrame(dictionary pprofile.ProfilesDictionary,
196196// identifySyscall walks the frames and extracts the syscall information.
197197func identifySyscall (dictionary pprofile.ProfilesDictionary ,
198198 locationIndices pcommon.Int32Slice ,
199- syscallCounts map [string ]int64 ,
199+ syscallCounts map [string ]int64 , multiplier int64 ,
200200) error {
201- // TODO: Scale syscallCounts by number of events in each Sample. Currently,
202- // this logic assumes 1 event per Sample (thus the increments by 1 below),
203- // which isn't necessarily the case.
204201 attrTable := dictionary .AttributeTable ()
205202 locationTable := dictionary .LocationTable ()
206203 strTable := dictionary .StringTable ()
@@ -213,18 +210,21 @@ func identifySyscall(dictionary pprofile.ProfilesDictionary,
213210
214211 for _ , li := range locationIndices .All () {
215212 if li >= int32 (locTblLen ) {
216- // log error
213+ slog .Error ("identifySyscall" , slog .Any ("li" , li ),
214+ slog .Any ("locTblLen" , locTblLen ))
217215 continue
218216 }
219217 loc := locationTable .At (int (li ))
220218 for _ , attrIdx := range loc .AttributeIndices ().All () {
221219 if attrIdx >= int32 (attrTblLen ) {
222- // log error
220+ slog .Error ("identifySyscall" , slog .Any ("attrIdx" , attrIdx ),
221+ slog .Any ("attrTblLen" , attrTblLen ))
223222 continue
224223 }
225224 attr := attrTable .At (int (attrIdx ))
226225 if int (attr .KeyStrindex ()) >= strTblLen {
227- // log error
226+ slog .Error ("identifySyscall" , slog .Any ("attr.KeyStrindex()" , attr .KeyStrindex ()),
227+ slog .Any ("strTblLen" , strTblLen ))
228228 continue
229229 }
230230
@@ -233,12 +233,14 @@ func identifySyscall(dictionary pprofile.ProfilesDictionary,
233233 if frameType == frameTypeKernel {
234234 for _ , ln := range loc .Line ().All () {
235235 if ln .FunctionIndex () >= int32 (funcTblLen ) {
236- // log error
236+ slog .Error ("identifySyscall" , slog .Any ("ln.FunctionIndex()" , ln .FunctionIndex ()),
237+ slog .Any ("funcTblLen" , funcTblLen ))
237238 continue
238239 }
239240 fn := funcTable .At (int (ln .FunctionIndex ()))
240241 if fn .NameStrindex () >= int32 (strTblLen ) {
241- // log error
242+ slog .Error ("identifySyscall" , slog .Any ("fn.NameStrindex()" , fn .NameStrindex ()),
243+ slog .Any ("strTblLen" , strTblLen ))
242244 continue
243245 }
244246 fnName := strTable .At (int (fn .NameStrindex ()))
@@ -247,16 +249,14 @@ func identifySyscall(dictionary pprofile.ProfilesDictionary,
247249 indices := syscallRx .FindStringSubmatchIndex (fnName )
248250 if len (indices ) == 4 {
249251 syscall := fnName [indices [2 ]:indices [3 ]]
250- syscallCounts [syscall ]++
252+ syscallCounts [syscall ] += multiplier
251253 return nil
252254 }
253255 }
254256
255257 }
256258 }
257-
258259 }
259-
260260 }
261261 return nil
262262}
@@ -272,17 +272,18 @@ func (c *profilesToMetricsConnector) addFrameMetrics(dictionary pprofile.Profile
272272
273273 // Process all samples and extract metric counts
274274 for _ , sample := range profile .Sample ().All () {
275+ multiplier := int64 (sample .TimestampsUnixNano ().Len ())
275276 stack := stackTable .At (int (sample .StackIndex ()))
276277 if err := classifyFrame (dictionary , stack .LocationIndices (),
277278 sample , counts , nativeCounts ); err != nil {
278279 // Should not happen with well-formed profile data
279- // TODO: Add error metric or log error
280+ slog . Error ( "classifyFrame" , slog . Any ( " error" , err ))
280281 }
281282
282283 if err := identifySyscall (dictionary , stack .LocationIndices (),
283- syscallCounts ); err != nil {
284+ syscallCounts , multiplier ); err != nil {
284285 // Should not happen with well-formed profile data
285- // TODO: Add error metric or log error
286+ slog . Error ( "identifySyscall" , slog . Any ( " error" , err ))
286287 }
287288 }
288289
@@ -320,8 +321,8 @@ func (c *profilesToMetricsConnector) addFrameMetrics(dictionary pprofile.Profile
320321
321322 for sysCall , count := range syscallCounts {
322323 m := scopeMetrics .Metrics ().AppendEmpty ()
323- m .SetName (c .config .MetricsPrefix + metricNative .name )
324- m .SetDescription (metricNative .desc )
324+ m .SetName (c .config .MetricsPrefix + metricSyscall .name )
325+ m .SetDescription (metricSyscall .desc )
325326 m .SetUnit ("1" )
326327
327328 sum := m .SetEmptySum ()
0 commit comments