Skip to content

Commit 5d2066f

Browse files
author
Robert Bartoszewski
committed
Enabled system metrics for App Starts spans
1 parent aedc046 commit 5d2066f

File tree

5 files changed

+54
-1
lines changed

5 files changed

+54
-1
lines changed

Sources/BugsnagPerformance/Private/Core/SpanFactory/AppStartup/AppStartupSpanFactoryImpl.mm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
auto name = isColdLaunch ? @"[AppStart/iOSCold]" : @"[AppStart/iOSWarm]";
2020
SpanOptions options;
2121
options.startTime = startTime;
22+
options.firstClass = BSGTriStateYes;
2223
auto attributes = spanAttributesProvider_->appStartSpanAttributes(firstViewName, isColdLaunch);
2324
return startAppStartSpan(name, options, attributes, @[]);
2425
}

features/default/automatic_spans.feature

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,17 @@ Feature: Automatic instrumentation spans
2323
* a span string attribute "bugsnag.span.category" equals "app_start"
2424
* a span string attribute "bugsnag.span.category" equals "app_start_phase"
2525
* a span string attribute "bugsnag.app_start.first_view_name" equals "Fixture.ViewController"
26-
* every span bool attribute "bugsnag.span.first_class" does not exist
26+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.cpu_measures_total" is not empty
27+
* the span named "[AppStart/iOSCold]" float attribute "bugsnag.system.cpu_mean_total" is greater than 0.0
28+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.cpu_measures_main_thread" is not empty
29+
* the span named "[AppStart/iOSCold]" float attribute "bugsnag.system.cpu_mean_main_thread" is greater than 0.0
30+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.cpu_measures_overhead" is not empty
31+
* the span named "[AppStart/iOSCold]" float attribute "bugsnag.system.cpu_mean_overhead" is greater than 0.0
32+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.memory.timestamps" is not empty
33+
* the span named "[AppStart/iOSCold]" integer attribute "bugsnag.system.memory.spaces.device.size" is greater than 0
34+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.memory.spaces.device.used" is not empty
35+
* the span named "[AppStart/iOSCold]" integer attribute "bugsnag.system.memory.spaces.device.mean" is greater than 0
36+
* a span bool attribute "bugsnag.span.first_class" is true
2737
* the trace payload field "resourceSpans.0.resource" string attribute "service.name" matches the regex "com.bugsnag.fixtures.cocoaperformance(xcframework)?"
2838
* the trace payload field "resourceSpans.0.resource" string attribute "telemetry.sdk.name" equals "bugsnag.performance.cocoa"
2939
* the trace payload field "resourceSpans.0.resource" string attribute "telemetry.sdk.version" matches the regex "[0-9]+\.[0-9]+\.[0-9]+"
@@ -73,6 +83,16 @@ Feature: Automatic instrumentation spans
7383
* a span named "[ViewLoadPhase/viewDidLayoutSubviews]/Fixture.ViewController" is a child of span named "[ViewLoad/UIKit]/Fixture.ViewController"
7484
* a span named "[AppStart/iOSCold]" ended at the same time as a span named "[AppStartPhase/UI init]"
7585
* a span named "[ViewLoad/UIKit]/Fixture.ViewController" ended before a span named "[AppStartPhase/UI init]"
86+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.cpu_measures_total" is not empty
87+
* the span named "[AppStart/iOSCold]" float attribute "bugsnag.system.cpu_mean_total" is greater than 0.0
88+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.cpu_measures_main_thread" is not empty
89+
* the span named "[AppStart/iOSCold]" float attribute "bugsnag.system.cpu_mean_main_thread" is greater than 0.0
90+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.cpu_measures_overhead" is not empty
91+
* the span named "[AppStart/iOSCold]" float attribute "bugsnag.system.cpu_mean_overhead" is greater than 0.0
92+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.memory.timestamps" is not empty
93+
* the span named "[AppStart/iOSCold]" integer attribute "bugsnag.system.memory.spaces.device.size" is greater than 0
94+
* the span named "[AppStart/iOSCold]" array attribute "bugsnag.system.memory.spaces.device.used" is not empty
95+
* the span named "[AppStart/iOSCold]" integer attribute "bugsnag.system.memory.spaces.device.mean" is greater than 0
7696

7797
Scenario: AutoInstrumentViewLoadScenario
7898
Given I run "AutoInstrumentViewLoadScenario"

features/fixtures/ios/Scenarios/AutoInstrumentAppStartsScenario.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ class AutoInstrumentAppStartsScenario: Scenario {
1313
override func setInitialBugsnagConfiguration() {
1414
super.setInitialBugsnagConfiguration()
1515
bugsnagPerfConfig.autoInstrumentAppStarts = true
16+
bugsnagPerfConfig.enabledMetrics.cpu = true
17+
bugsnagPerfConfig.enabledMetrics.memory = true
1618
}
1719

1820
override func run() {

features/fixtures/ios/Scenarios/AutoInstrumentAppStartsWithViewLoadScenario.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ class AutoInstrumentAppStartsWithViewLoadScenario: Scenario {
1414
super.setInitialBugsnagConfiguration()
1515
bugsnagPerfConfig.autoInstrumentAppStarts = true
1616
bugsnagPerfConfig.autoInstrumentViewControllers = true
17+
bugsnagPerfConfig.enabledMetrics.cpu = true
18+
bugsnagPerfConfig.enabledMetrics.memory = true
1719
// This test can generate a variable number of spans depending on the OS version,
1820
// so use a timed send instead.
1921
bugsnagPerfConfig.internal.autoTriggerExportOnBatchSize = 100

features/steps/app_steps.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,13 @@ def run_command(action, args)
179179
attribute_values.map { |v| Maze.check.match pattern, v }
180180
end
181181

182+
Then('the span named {string} integer attribute {string} is greater than {int}') do |spanName, attribute, expected|
183+
spans = spans_from_request_list(Maze::Server.list_for('traces'))
184+
span = spans.find { |span| span['name'] == spanName }
185+
selected_attribute = span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('intValue') }
186+
Maze.check.true(selected_attribute['value']['intValue'].to_f > expected)
187+
end
188+
182189
Then('a span integer attribute {string} is greater than {int}') do |attribute, expected|
183190
spans = spans_from_request_list(Maze::Server.list_for('traces'))
184191
selected_attributes = spans.map { |span| span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('intValue') } }.compact
@@ -200,6 +207,12 @@ def run_command(action, args)
200207
Maze.check.false(attribute_values.empty?)
201208
end
202209

210+
Then('the span named {string} float attribute {string} is greater than {float}') do |spanName, attribute, expected|
211+
spans = spans_from_request_list(Maze::Server.list_for('traces'))
212+
span = spans.find { |span| span['name'] == spanName }
213+
selected_attribute = span['attributes'].find { |a| a['key'].eql?(attribute) && a['value'].has_key?('doubleValue') }
214+
Maze.check.true(selected_attribute['value']['doubleValue'].to_f > expected)
215+
end
203216

204217
Then('a span float attribute {string} is greater than {float}') do |attribute, expected|
205218
spans = spans_from_request_list(Maze::Server.list_for('traces'))
@@ -272,6 +285,21 @@ def get_array_attribute_contents(attribute)
272285
return array_attributes[0]
273286
end
274287

288+
def get_array_attribute_contents(spanName, attribute)
289+
spans = spans_from_request_list(Maze::Server.list_for('traces'))
290+
span = spans.find { |span| span['name'] == spanName }
291+
selected_attribute = span['attributes'].find { |a| a['key'].eql?(attribute) &&
292+
a['value'].has_key?('arrayValue') &&
293+
a['value']['arrayValue'].has_key?('values') }
294+
array_attributes = selected_attribute['value']['arrayValue']['values']
295+
return array_attributes
296+
end
297+
298+
Then('the span named {string} array attribute {string} is not empty') do |name, attribute|
299+
array_contents = get_array_attribute_contents(name, attribute)
300+
Maze.check.false(array_contents.empty?)
301+
end
302+
275303
Then('a span array attribute {string} is empty') do |attribute|
276304
array_contents = get_array_attribute_contents(attribute)
277305
Maze.check.true(array_contents.empty?)

0 commit comments

Comments
 (0)