@@ -58,7 +58,7 @@ func testNodeJSTraces(t *testing.T) {
5858 var selectedTrace * ptrace.Traces
5959
6060 require .Eventually (t , func () bool {
61- for i := len (tracesConsumer .AllTraces ()) - 1 ; i > 0 ; i -- {
61+ for i := len (tracesConsumer .AllTraces ()) - 1 ; i >= 0 ; i -- {
6262 trace := tracesConsumer .AllTraces ()[i ]
6363 if val , ok := trace .ResourceSpans ().At (0 ).Resource ().Attributes ().Get ("telemetry.sdk.language" ); ok && strings .Contains (val .Str (), "nodejs" ) {
6464 if expectedTraces .SpanCount () == trace .SpanCount () && expectedTraces .ResourceSpans ().Len () == trace .ResourceSpans ().Len () {
@@ -127,7 +127,7 @@ func testPythonTraces(t *testing.T) {
127127
128128 read := 0
129129 require .Eventually (t , func () bool {
130- for i := len (tracesConsumer .AllTraces ()) - 1 ; i > read ; i -- {
130+ for i := len (tracesConsumer .AllTraces ()) - 1 ; i >= read ; i -- {
131131 trace := tracesConsumer .AllTraces ()[i ]
132132 if val , ok := trace .ResourceSpans ().At (0 ).Resource ().Attributes ().Get ("telemetry.sdk.language" ); ok && strings .Contains (val .Str (), "python" ) {
133133 if expectedTraces .SpanCount () == trace .SpanCount () && expectedTraces .ResourceSpans ().Len () == trace .ResourceSpans ().Len () {
@@ -196,7 +196,7 @@ func testJavaTraces(t *testing.T) {
196196 var selectedTrace * ptrace.Traces
197197
198198 require .Eventually (t , func () bool {
199- for i := len (tracesConsumer .AllTraces ()) - 1 ; i > 0 ; i -- {
199+ for i := len (tracesConsumer .AllTraces ()) - 1 ; i >= 0 ; i -- {
200200 trace := tracesConsumer .AllTraces ()[i ]
201201 if val , ok := trace .ResourceSpans ().At (0 ).Resource ().Attributes ().Get ("telemetry.sdk.language" ); ok && strings .Contains (val .Str (), "java" ) {
202202 if expectedTraces .SpanCount () == trace .SpanCount () && expectedTraces .ResourceSpans ().Len () == trace .ResourceSpans ().Len () {
@@ -261,7 +261,7 @@ func testDotNetTraces(t *testing.T) {
261261 var selectedTrace * ptrace.Traces
262262
263263 require .Eventually (t , func () bool {
264- for i := len (tracesConsumer .AllTraces ()) - 1 ; i > 0 ; i -- {
264+ for i := len (tracesConsumer .AllTraces ()) - 1 ; i >= 0 ; i -- {
265265 trace := tracesConsumer .AllTraces ()[i ]
266266 if val , ok := trace .ResourceSpans ().At (0 ).Resource ().Attributes ().Get ("telemetry.sdk.language" ); ok && strings .Contains (val .Str (), "dotnet" ) {
267267 if expectedTraces .SpanCount () == trace .SpanCount () && expectedTraces .ResourceSpans ().Len () == trace .ResourceSpans ().Len () {
@@ -339,8 +339,13 @@ func testPythonMetrics(t *testing.T) {
339339 })
340340}
341341
342- // Profiling tests — look for com.splunk.sourcetype=otel.profiling* logs
343- // carrying the expected telemetry.sdk.language + service.name.
342+ // Profiling tests — verify both CPU and memory/allocation profiling logs arrive
343+ // with com.splunk.sourcetype=otel.profiling for the expected app identity.
344+ //
345+ // The HEC exporter identifies profiling data by instrumentation scope name
346+ // ("otel.profiling"), not by sourcetype. After the HEC round-trip:
347+ // - com.splunk.sourcetype, telemetry.sdk.language, service.name → resource attributes
348+ // - profiling.data.type (cpu|allocation) → log record attributes
344349
345350func testJavaProfiling (t * testing.T ) { checkProfilingFromApp (t , "java" , "java-test" ) }
346351func testNodeJSProfiling (t * testing.T ) { checkProfilingFromApp (t , "nodejs" , "nodejs-test" ) }
@@ -350,34 +355,34 @@ func testPythonProfiling(t *testing.T) { checkProfilingFromApp(t, "python", "pyt
350355func checkProfilingFromApp (t * testing.T , sdkLanguage , serviceName string ) {
351356 lc := globalSinks .logsConsumer
352357 label := sdkLanguage + "/" + serviceName
353- require .Eventuallyf (t , func () bool {
354- return hasProfilingFromApp (lc , sdkLanguage , serviceName )
355- }, 3 * time .Minute , 5 * time .Second ,
356- "no profiling logs (otel.profiling*) for %s within timeout" , label )
357- t .Logf ("Received profiling logs from %s" , label )
358+ profilingTypes := []string {"cpu" , "allocation" }
359+ for _ , pt := range profilingTypes {
360+ t .Run (pt , func (t * testing.T ) {
361+ require .Eventuallyf (t , func () bool {
362+ return hasProfilingFromApp (lc , sdkLanguage , serviceName , pt )
363+ }, 3 * time .Minute , 5 * time .Second ,
364+ "no %s profiling logs for %s within timeout" , pt , label )
365+ t .Logf ("Received %s profiling logs from %s" , pt , label )
366+ })
367+ }
358368}
359369
360- // hasProfilingFromApp checks the logs sink for profiling entries matching the app.
361- // After the HEC round-trip, identity attrs may appear at the resource or log record level.
362- func hasProfilingFromApp (lc * consumertest.LogsSink , sdkLanguage , serviceName string ) bool {
363- matchIdentity := func (attrs pcommon.Map ) bool {
364- return hasAttrMatch (attrs , "telemetry.sdk.language" , sdkLanguage ) &&
365- hasAttrMatch (attrs , "service.name" , serviceName )
366- }
370+ func hasProfilingFromApp (lc * consumertest.LogsSink , sdkLanguage , serviceName , profilingType string ) bool {
367371 for _ , logs := range lc .AllLogs () {
368372 for i := 0 ; i < logs .ResourceLogs ().Len (); i ++ {
369373 rl := logs .ResourceLogs ().At (i )
370374 resAttrs := rl .Resource ().Attributes ()
371- stVal , stOk := resAttrs .Get ("com.splunk.sourcetype" )
372- if ! stOk || ! strings .HasPrefix (stVal .Str (), "otel.profiling" ) {
375+ if ! hasAttrMatch (resAttrs , "com.splunk.sourcetype" , "otel.profiling" ) {
373376 continue
374377 }
375- if matchIdentity (resAttrs ) {
376- return true
378+ if ! hasAttrMatch (resAttrs , "telemetry.sdk.language" , sdkLanguage ) ||
379+ ! hasAttrMatch (resAttrs , "service.name" , serviceName ) {
380+ continue
377381 }
378382 for j := 0 ; j < rl .ScopeLogs ().Len (); j ++ {
379383 for k := 0 ; k < rl .ScopeLogs ().At (j ).LogRecords ().Len (); k ++ {
380- if matchIdentity (rl .ScopeLogs ().At (j ).LogRecords ().At (k ).Attributes ()) {
384+ recAttrs := rl .ScopeLogs ().At (j ).LogRecords ().At (k ).Attributes ()
385+ if hasAttrMatch (recAttrs , "profiling.data.type" , profilingType ) {
381386 return true
382387 }
383388 }
0 commit comments