Skip to content
This repository was archived by the owner on Nov 1, 2022. It is now read-only.

Conversation

mhammond
Copy link
Contributor

@mhammond mhammond commented Jul 4, 2020

application-services needs to be closely involved in creating the
data to be recorded in telemetry - however, we are trying to avoid
exposing this telemetry directly to the android-components "concepts"
or "features" - for example, the part of android-components that sends
a tab ideally wouldn't have to deal with any interface changes just because
telemetry is being sent or changed - otherwise new/changed telemetry is always
a "breaking change"

In the future, we expect the rust components to interact directly with Glean,
and consumers like android-components wouldn't need to get involved at all.
However, until then...

The idea with this PR is that there's one new public account function,
processPendingTelemetry(), which should be called whenever something is
done which might record telemetry. However, it doesn't need to know
what is actually recorded - that knowledge is only in the telemetry
code - the code that is tightly bound to glean.

This hasn't been tested yet - but it builds :) I'm soliciting feedback on
the general shape of this before I invest too much more in tests etc.

I also considered trying to do with Observers(), but that didn't seem
any easier. I'm obviously open to alternative approaches!

See also mozilla/application-services#3308


CC @grigoryk @linacambridge @rfk

Pull Request checklist

  • Quality: This PR builds and passes detekt/ktlint checks (A pre-push hook is recommended)
  • Tests: This PR includes thorough tests or an explanation of why it does not
  • Changelog: This PR includes a changelog entry or does not need one
  • Accessibility: The code in this PR follows accessibility best practices or does not include any user facing features

After merge

  • Milestone: Make sure issues closed by this pull request are added to the milestone of the version currently in development.
  • Breaking Changes: If this is a breaking change, please push a draft PR on Reference Browser to address the breaking issues.

Copy link
Contributor

@grigoryk grigoryk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this can be simpler, without any changes to the account manager.

* While this is an async function, it is "fire and forget" - there's no
* need to await.
*/
fun processPendingTelemetry()
Copy link
Contributor

@grigoryk grigoryk Jul 21, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if this was named gatherTelemetry and just returned an opaque string or JSON object, instead? Then you'd just pass that along directly to processFxaTelemetry whenever you'd currently call processPendingTelemetry.

If you're doing something that has a by-product of needing to send/set some fxa telemetry, you have an account instance. So you don't need to make any changes to the account manager, you can just directly grab telemetry from the account and pass it along to SyncTelemetry.processFxaTelemetry which knows about what's in the telemetry blob.

Alternatively, SyncTelemetry.processFxaTelemetry can just take an account reference as well, which would make sending a tab something like this:

account.sendSingleTab(targetDeviceId, outgoingCommand.title, outgoingCommand.url)
SyncTelemetry.processFxaTelemetry(account)

We can also rename SyncTelemetry to something more general, perhaps.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's much simpler - I failed to see the wood for the trees :) I didn't rename SyncTelemetry but let me know if you would like me to.

@mhammond mhammond requested a review from grigoryk July 23, 2020 05:42
Copy link
Contributor

@grigoryk grigoryk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that's the right shape! Just a concern about creating a blind spot around telemetry failures.

@@ -284,4 +287,42 @@ object SyncTelemetry {
val message = reason.message ?: "Unexpected error: ${reason.code}"
metric.set(message.take(MAX_FAILURE_REASON_LENGTH))
}

fun processFxaTelemetry(jsonStr: String) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe you could link to wherever this schema is defined in the app-services repo? It'll be nice to have that handy here.

import mozilla.components.support.sync.telemetry.GleanMetrics.HistorySync
import mozilla.components.support.sync.telemetry.GleanMetrics.LoginsSync
import mozilla.components.support.sync.telemetry.GleanMetrics.Sync
import mozilla.components.support.sync.telemetry.GleanMetrics.Pings

const val MAX_FAILURE_REASON_LENGTH = 100

// The exceptions we report to the crash reporter, but otherwise don't escape this module.
sealed class InvalidTelemetryException(cause: Exception) : Exception(cause) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: could be internal so that it doesn't into the public API (and linter won't force you to write kdocs).

@grigoryk
Copy link
Contributor

grigoryk commented Jul 28, 2020

Overall this looks good to me! I guess you should mark it as ready for a review at some point :-)

@mhammond
Copy link
Contributor Author

Overall this looks good to me! I guess you should mark it as ready for a review at some point :-)

Thanks - the app-services part is yet to land :/ Once that does I'll see about making a new release etc and marking this ready.

@grigoryk
Copy link
Contributor

@mhammond I think this can go ahead now that mozilla/application-services#3308 landed?

@mhammond mhammond marked this pull request as ready for review August 10, 2020 22:08
@mhammond mhammond changed the title A WIP for recording send-tab telemetry for Fenix. Record send-tab telemetry for Fenix. Aug 13, 2020
@@ -1015,7 +1015,7 @@ open class FxaAccountManager(

@VisibleForTesting
open fun createAccount(config: ServerConfig): OAuthAccount {
return FirefoxAccount(config)
return FirefoxAccount(config, null, crashReporter)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused by why the PersistCallback is being passed as null here - is there maybe some other creator of a FirefoxAccount which is passed a non-null PersistCallback but will now be getting a null crashReporter?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as mentioned on slack, this should be fine, just a bad API for FirefoxAccount. It will register a persist callback internally regardless of what you pass in here.

@mhammond
Copy link
Contributor Author

That taskcluster failure looks unrelated to this change

@@ -111,6 +114,7 @@ class FxaDeviceConstellation(
when (outgoingCommand) {
is DeviceCommandOutgoing.SendTab -> {
account.sendSingleTab(targetDeviceId, outgoingCommand.title, outgoingCommand.url)
SyncTelemetry.processFxaTelemetry(account.gatherTelemetry())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're not passing in crashReporter to processFxaTelemetry

@@ -27,7 +28,8 @@ typealias PersistCallback = mozilla.appservices.fxaclient.FirefoxAccount.Persist
*/
@Suppress("TooManyFunctions")
class FirefoxAccount internal constructor(
private val inner: InternalFxAcct
private val inner: InternalFxAcct,
private val crashReporter: CrashReporting? = null
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to use this for the FxaDeviceConstellation constructor?

@@ -1015,7 +1015,7 @@ open class FxaAccountManager(

@VisibleForTesting
open fun createAccount(config: ServerConfig): OAuthAccount {
return FirefoxAccount(config)
return FirefoxAccount(config, null, crashReporter)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as mentioned on slack, this should be fine, just a bad API for FirefoxAccount. It will register a persist callback internally regardless of what you pass in here.

application-services needs to be closely involved in creating the
data to be recorded in telemetry, which passes it back to Android Components
as a JSON string. SyncTelemetry.kt is the only thing that needs to know
what's in that JSON, so it pull it apart and calls the relevant glean
functions.

See also mozilla/application-services#3308
@grigoryk
Copy link
Contributor

bors r+

bors bot pushed a commit that referenced this pull request Aug 20, 2020
7618: Record send-tab telemetry for Fenix. r=grigoryk a=mhammond

application-services needs to be closely involved in creating the
data to be recorded in telemetry - however, we are trying to avoid
exposing this telemetry directly to the android-components "concepts"
or "features" - for example, the part of android-components that sends
a tab ideally wouldn't have to deal with any interface changes just because
telemetry is being sent or changed - otherwise new/changed telemetry is always
a "breaking change"

In the future, we expect the rust components to interact directly with Glean,
and consumers like android-components wouldn't need to get involved at all.
However, until then...

The idea with this PR is that there's one new public account function,
`processPendingTelemetry()`, which should be called whenever something is
done which might record telemetry. However, it doesn't need to know
what is actually recorded - that knowledge is only in the telemetry
code - the code that is tightly bound to glean.

This hasn't been tested yet - but it builds :) I'm soliciting feedback on
the general shape of this before I invest too much more in tests etc.

I also considered trying to do with Observers(), but that didn't seem
any easier. I'm obviously open to alternative approaches!

See also mozilla/application-services#3308



Co-authored-by: Mark Hammond <[email protected]>
@bors
Copy link

bors bot commented Aug 20, 2020

Timed out.

@grigoryk
Copy link
Contributor

bors retry

@bors
Copy link

bors bot commented Aug 20, 2020

Build succeeded:

@bors bors bot merged commit e4d377a into mozilla-mobile:master Aug 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants