Skip to content

Commit

Permalink
Bug 1628057: Include app lifetime metrics in dirty_startup baseline p…
Browse files Browse the repository at this point in the history
…ings
  • Loading branch information
mdboom committed Apr 7, 2020
1 parent 5935b4b commit 6acfa00
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[Full changelog](https://github.com/mozilla/glean/compare/v26.0.0...master)

* General:
* BUGFIX: baseline pings sent at startup with the `dirty_startup` reason will now include application lifetime metrics.
* Glean will now detect when the upload enabled flag changes outside of the application, for example due to a change in a config file. This means that if upload is disabled while the application wasn't running (e.g. between the runs of a Python command using the Glean SDK), the database is correctly cleared and a deletion request ping is sent. See [#791](https://github.com/mozilla/glean/pull/791).
* The `events` ping now includes a reason code: `startup`, `background` or `max_capacity`.
* iOS:
Expand Down
20 changes: 10 additions & 10 deletions glean-core/android/src/main/java/mozilla/telemetry/glean/Glean.kt
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,16 @@ open class GleanInternalAPI internal constructor () {
metricsPingScheduler = MetricsPingScheduler(applicationContext)
metricsPingScheduler.schedule()

// Check if the "dirty flag" is set. That means the product was probably
// force-closed. If that's the case, submit a 'baseline' ping with the
// reason "dirty_startup". We only do that from the second run.
if (!isFirstRun && LibGleanFFI.INSTANCE.glean_is_dirty_flag_set().toBoolean()) {
submitPingByNameSync("baseline", "dirty_startup")
// Note: while in theory we should set the "dirty flag" to true
// here, in practice it's not needed: if it hits this branch, it
// means the value was `true` and nothing needs to be done.
}

// From the second time we run, after all startup pings are generated,
// make sure to clear `lifetime: application` metrics and set them again.
// Any new value will be sent in newly generated pings after startup.
Expand All @@ -200,16 +210,6 @@ open class GleanInternalAPI internal constructor () {
// Signal Dispatcher that init is complete
Dispatchers.API.flushQueuedInitialTasks()

// Check if the "dirty flag" is set. That means the product was probably
// force-closed. If that's the case, submit a 'baseline' ping with the
// reason "dirty_startup". We only do that from the second run.
if (!isFirstRun && LibGleanFFI.INSTANCE.glean_is_dirty_flag_set().toBoolean()) {
submitPingByNameSync("baseline", "dirty_startup")
// Note: while in theory we should set the "dirty flag" to true
// here, in practice it's not needed: if it hits this branch, it
// means the value was `true` and nothing needs to be done.
}

// At this point, all metrics and events can be recorded.
// This should only be called from the main thread. This is enforced by
// the @MainThread decorator and the `assertOnUiThread` call.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -701,4 +701,46 @@ class GleanTest {

assertEquals(0, server.requestCount)
}

@Test
fun `test sending of startup baseline ping with application lifetime metric`() {
// Set the dirty flag.
LibGleanFFI.INSTANCE.glean_set_dirty_flag(true.toByte())

val stringMetric = StringMetricType(
disabled = false,
category = "telemetry",
lifetime = Lifetime.Application,
name = "app_lifetime",
sendInPings = listOf("baseline")
)
stringMetric.set("HELLOOOOO!")

// Restart glean and don't clear the stores.
val server = getMockWebServer()
val context = getContextWithMockedInfo()
resetGlean(context, Glean.configuration.copy(
serverEndpoint = "http://" + server.hostName + ":" + server.port,
logPings = true
), false)

try {
// Trigger worker task to upload the pings in the background
triggerWorkManager(context)

val request = server.takeRequest(20L, TimeUnit.SECONDS)
val docType = request.path.split("/")[3]
assertEquals("The received ping must be a 'baseline' ping", "baseline", docType)

val baselineJson = JSONObject(request.body.readUtf8())
assertEquals("dirty_startup", baselineJson.getJSONObject("ping_info")["reason"])
checkPingSchema(baselineJson)

val appLifetimeMetricsObject = baselineJson.getJSONObject("metrics")
val appLifetimeStringMetrics = appLifetimeMetricsObject.getJSONObject("string")
assertEquals("HELLOOOOO!", appLifetimeStringMetrics.get("telemetry.app_lifetime"))
} finally {
server.shutdown()
}
}
}

0 comments on commit 6acfa00

Please sign in to comment.