Conversation
|
Could you give guidance on what you're looking back in terms of feedback? My assumptions are, at minimum you're looking for: For context, in the future, a review ask might also include "can you dogfood this" or "can you test this thoroughly" |
jasonrudolph
left a comment
There was a problem hiding this comment.
👋 Hi @annthurium: Thanks for getting this going. ⚡
I took a first pass through this diff, and I've offered some suggestions and noted a few questions below. I hope this helps.
lib/reporter.js
Outdated
| } | ||
|
|
||
| this.send(params) | ||
| // todo (tt, 6/2018): send timing to telemetry. |
There was a problem hiding this comment.
Is this something that will be implemented in this pull request? Or would it happen in a follow-up pull request?
There was a problem hiding this comment.
this is something that would happen in a follow up pull request. If you think it's better not to track things like that in TODOs I'd be happy to remove it.
There was a problem hiding this comment.
@annthurium: As a general guideline, my personal preference is to track TODOs in issues, as opposed to code comments. 😺
There was a problem hiding this comment.
cool. I sometimes add TODOs if I think other folks reading/modifying this code would want to be aware of imminent changes. Fine with removing this though.
lib/reporter.js
Outdated
| const eventName = 'appview' | ||
| const params = { | ||
| t: 'appview', | ||
| t: eventName, |
There was a problem hiding this comment.
In Google Analytics terms, t refers to the "hit type". Possible values are pageview, event, exception, timing, and just a few others.
With that in mind, I'd recommend renaming eventName to eventType to convey that it's a fairly course-grained/high-level concept, whereas eventName might imply something much more granular (e.g., commit, consent-change, etc.).
lib/reporter.js
Outdated
| ev: this.commandCount[commandName] | ||
| } | ||
|
|
||
| this.addCustomEvent(params, 'command') |
There was a problem hiding this comment.
I feel rotten bringing this up again, but I keep finding myself confused by this interface. (Sorry! 😦) Here, I was expecting the event name to be the first arg, followed by the event metadata, but I see that the order is the opposite.
We talked about an alternative interface in atom/telemetry#12 (comment), and you mentioned plans to run this API few some more folks for feedback. Did you have a chance to do so?
There was a problem hiding this comment.
I agree, having the event name first makes more sense to me and seems to be common practice in API design. Typically my principle for argument ordering is "most important/relevant parameter first" and I think in this case the event name is the most important parameter.
There was a problem hiding this comment.
sure thing! can make the event name first.
package-lock.json
Outdated
| "dev": true | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
For consistency with the other packages, would you mind deleting this file and adding package-lock.json to .gitignore?
A couple threads for reference:
There was a problem hiding this comment.
oh, thanks! I had no idea I was not supposed to check in package.lock files for Atom packages.
There was a problem hiding this comment.
Since apm currently ignores them they aren't giving us any benefit right now, and simply add a bunch of extra maintenance work at the moment.
spec/metrics-spec.js
Outdated
|
|
||
| atom.commands.dispatch(workspaceElement, 'editor:move-to-end-of-line', null) | ||
| expect(Reporter.request).not.toHaveBeenCalled() | ||
| assertNotCalledHelper('core:move-up') |
There was a problem hiding this comment.
To make this more expressive, I recommend renaming assertNotCalledHelper to assertCommandNotReported. I think that would more clearly convey the intent. (The fact that the method is a helper is an implementation detail that I don't think we need to expose in the name of the method.)
| spyOn(store, 'setOptOut') | ||
| spyOn(Reporter, 'sendEvent') | ||
| await atom.config.set('core.telemetryConsent', 'limited') | ||
|
|
There was a problem hiding this comment.
Tiny observation/question: Is the whitespace in this test intentionally different from the whitespace in the previous test? If not, can I talk you using the same whitespace in both tests?
|
|
||
| const {mainModule} = atom.packages.getLoadedPackage('metrics') | ||
| mainModule.shouldIncludePanesAndCommands = true | ||
| Reporter.addCustomEvent.reset() |
There was a problem hiding this comment.
Given that we're calling this in the afterEach function for all tests in this file, can we remove this line, or do we need it?
There was a problem hiding this comment.
Removed the reset from all tests in this file, as it's unnecessary, and left it here.
spec/metrics-spec.js
Outdated
| }) | ||
|
|
||
| it('will not report pane items', async () => { | ||
| Reporter.addCustomEvent.reset() |
There was a problem hiding this comment.
Given that we're calling this in the afterEach function for all tests in this file, can we remove this line, or do we need it?
There was a problem hiding this comment.
ah, these were some debug code trying to get to the bottom of my comment re file open events. Will remove them.
| describe('when there are paths in the exception', () => { | ||
| it('strips unix paths surrounded in quotes', () => { | ||
| let message = "Error: ENOENT, unlink '/Users/someguy/path/file.js'" | ||
| let message = "Error: ENOENT, unlink '/Users/someuser/path/file.js'" |
| static addCustomEvent (event, eventName) { | ||
| store.addCustomEvent(event, eventName) | ||
| } | ||
| static sendEvent (category, action, label, value) { |
There was a problem hiding this comment.
I'm guessing that you'd want anyone writing new code to use addCustomEvent instead of sendEvent. Is that correct? If so, I'd recommend marking sendEvent as deprecated [example]. What do you think?
There was a problem hiding this comment.
Also, could/should it be called sendCustomEvent? To me, add sounds like we're registering an event type rather than sending some information
There was a problem hiding this comment.
ah, good call. Will change this too.
|
@sguthals you asked to be added to code reviews as a non blocking reviewer awhile back. I didn't have specific feedback I wanted from you with regards to this pull request, as I know I can count on @jasonrudolph for a thorough code review. 😄 |
|
Awesome! That is what I assumed 😄 In general, I'd like to get in the habit of including in the PR description what you're looking for in terms of feedback. At some point it will be nice to provide feedback on things like usability) and if we get in the habit of being specific about the type of feedback we're looking for I think both pr author and reviewer will be happier 👍 |
daviwil
left a comment
There was a problem hiding this comment.
Looking good! I've added some feedback and +1'ed some of Jason's comments
lib/reporter.js
Outdated
| ev: this.commandCount[commandName] | ||
| } | ||
|
|
||
| this.addCustomEvent(params, 'command') |
There was a problem hiding this comment.
I agree, having the event name first makes more sense to me and seems to be common practice in API design. Typically my principle for argument ordering is "most important/relevant parameter first" and I think in this case the event name is the most important parameter.
lib/store.js
Outdated
| @@ -0,0 +1,7 @@ | |||
| const telemetry = require('telemetry-github') | |||
|
|
|||
| const store = new telemetry.StatsStore('atom', atom.getVersion(), atom.inDevMode(), () => '') | |||
There was a problem hiding this comment.
I'd also make that parameter optional and do the "right thing" when the user doesn't pass anything.
| static addCustomEvent (event, eventName) { | ||
| store.addCustomEvent(event, eventName) | ||
| } | ||
| static sendEvent (category, action, label, value) { |
There was a problem hiding this comment.
Also, could/should it be called sendCustomEvent? To me, add sounds like we're registering an event type rather than sending some information
annthurium
left a comment
There was a problem hiding this comment.
still working on some things - thanks for the feedback!
spec/metrics-spec.js
Outdated
|
|
||
| atom.commands.dispatch(workspaceElement, 'editor:move-to-end-of-line', null) | ||
| expect(Reporter.request).not.toHaveBeenCalled() | ||
| assertNotCalledHelper('core:move-up') |
| static addCustomEvent (event, eventName) { | ||
| store.addCustomEvent(event, eventName) | ||
| } | ||
| static sendEvent (category, action, label, value) { |
lib/reporter.js
Outdated
| } | ||
|
|
||
| this.send(params) | ||
| // todo (tt, 6/2018): send timing to telemetry. |
There was a problem hiding this comment.
this is something that would happen in a follow up pull request. If you think it's better not to track things like that in TODOs I'd be happy to remove it.
| spyOn(store, 'setOptOut') | ||
| spyOn(Reporter, 'sendEvent') | ||
| await atom.config.set('core.telemetryConsent', 'limited') | ||
|
|
|
|
||
| const {mainModule} = atom.packages.getLoadedPackage('metrics') | ||
| mainModule.shouldIncludePanesAndCommands = true | ||
| Reporter.addCustomEvent.reset() |
spec/metrics-spec.js
Outdated
|
|
||
| atom.commands.dispatch(workspaceElement, 'editor:move-to-end-of-line', null) | ||
| expect(Reporter.request).not.toHaveBeenCalled() | ||
| assertNotCalledHelper('core:move-up') |
spec/metrics-spec.js
Outdated
| }) | ||
|
|
||
| it('will not report pane items', async () => { | ||
| Reporter.addCustomEvent.reset() |
There was a problem hiding this comment.
ah, these were some debug code trying to get to the bottom of my comment re file open events. Will remove them.
|
|
||
| const {mainModule} = atom.packages.getLoadedPackage('metrics') | ||
| mainModule.shouldIncludePanesAndCommands = true | ||
| Reporter.addCustomEvent.reset() |
There was a problem hiding this comment.
Removed the reset from all tests in this file, as it's unnecessary, and left it here.
lib/store.js
Outdated
| const telemetry = require('telemetry-github') | ||
|
|
||
| const store = new telemetry.StatsStore('atom', atom.getVersion(), atom.inDevMode(), () => '') | ||
| const hasOptedOut = atom.config.get('core.telemetryConsent') !== 'limited' |
There was a problem hiding this comment.
I could call it notOptedIn because that's really what telemetry cares about. Will update.
lib/reporter.js
Outdated
| const eventName = 'appview' | ||
| const params = { | ||
| t: 'appview', | ||
| t: eventName, |
…cs into tt-18-jun-integrate-telemetry
…n a file open event.
|
@jasonrudolph : I believe I've addressed all the comments. Thank you for your feedback! Would you be willing to take a second pass through this? Given that this code is important and I'm still new, I'd like an explicit 👍 before I merge. As far as what kind of feedback I'm looking for:
|
| @@ -18,7 +18,8 @@ | |||
| "dependencies": { | |||
| "fs-plus": "^3.0.0", | |||
| "grim": "^2.0.1", | |||
There was a problem hiding this comment.
@jasonrudolph : I'm assuming that I don't need to increment the version of metrics-reporter in providedServices here since I'm just adding new methods and the old ones are still supported. Is that the case?
There was a problem hiding this comment.
Since this is an additive change, I think it makes sense to increment the version from 1.0.0 to 1.1.0.
Since the new methods didn't exist in version 1.0.0 of the service, and since you want a way for packages to consume the new methods, those packages need to be able to declare a dependency on a version of the service that includes the new methods. By incrementing the version to 1.1.0, existing consumers (e.g., the welcome package) should continue to work, and packages that want to use the new methods can declare a minimum dependency of 1.1.0.
Does that sound reasonable?
There was a problem hiding this comment.
got it, thanks! Have incremented the provideReporter version here.
jasonrudolph
left a comment
There was a problem hiding this comment.
As far as what kind of feedback I'm looking for:
Thanks for enumerating the kind of feedback you're looking for! 😻
does my naming make sense?
It makes sense to me.
are there any style nits that would enhance readability / consistency?
I noted a couple tiny suggestions inline below.
is there anything I should be unit testing but I'm not?
I don't think so.
is there anything missing from the manual testing plan?
A few questions:
- All of the stated steps call for using Atom in dev mode. Is there something noteworthy about dev mode as it relates to testing this functionality? Or would you expect these verification steps to also succeed when running Atom in normal (non-dev) mode?
- As far as I can tell, there's no production code that currently uses
incrementCounter. Will you manually invokeincrementCounterand verify that it has the desired effect? - Am I correct in thinking that
sendExceptionwill continue to send info only to Google Analytics, and will intentionally not send data to Telemetry?
lib/reporter.js
Outdated
| } | ||
|
|
||
| // Deprecated: this is the old API that was used to send events to Google Analytics. | ||
| // new callers should use addCustomEvent instead. |
There was a problem hiding this comment.
are there any style nits that would enhance readability / consistency?
For style consistency with other deprecation comments (e.g., https://git.io/f4b4H), I'd recommend writing this as:
// Deprecated: Use addCustomEvent instead.
lib/reporter.js
Outdated
| } | ||
|
|
||
| // Deprecated: this is the old API that was used to send events to Google Analytics. | ||
| // new callers should use addTiming instead. |
There was a problem hiding this comment.
are there any style nits that would enhance readability / consistency?
For style consistency with other deprecation comments (e.g., https://git.io/f4b4H), I'd recommend writing this as:
// Deprecated: Use addCustomEvent instead.| } | ||
|
|
||
| static addCustomEvent (eventType, event) { | ||
| store.addCustomEvent(eventType, event) |
There was a problem hiding this comment.
Today, if you call sendEvent, sendTiming, sendPaneItem, sendCommand, the package automatically gathers a handful of dimensions defined in consentedParams and includes those dimensions when reporting the metric to Google Analytics:
Lines 163 to 175 in 6a5833e
I'm thinking that any metrics sent via Telemetry should also automatically include those dimensions. What do you think?
There was a problem hiding this comment.
hmmm. I think having that data would be ideal, but I worry about request size.
The max size of the post body in a request in Rails is 2GB. So we have a lot of characters to go through before we hit the size limit. (Although, depending on how long a request takes to process, we might well run into timeout problems before we bump up against size limits.)
Anyway, let's try sending the data with the request and see how it goes. We can always revisit in the future if it becomes a problem.
when calling `addCustomEvent` or `addTiming`, send the same metadata to the store that we send to Google Analytics (processor, etc.)
…cs into tt-18-jun-integrate-telemetry
|
Thanks for the second pass, @jasonrudolph! To answer your questions about the test plan:
Correct - these steps would also succeed in non-dev mode. I suppose specifying that I tested in dev mode was rather pedantic of me. 😛 I am happy to change it if you think it could be confusing.
Correct, I will manually invoke incrementCounter.
That is also correct - |
jasonrudolph
left a comment
There was a problem hiding this comment.
@annthurium: Thanks for the clarifications and for the latest code updates. 👍
|
yay, it works, it works!! thanks again @jasonrudolph for all your help with this! |


this pull request integrates the new
telemetrypackage for sending metrics to GitHub's internal analytics pipeline, rather than Google Analytics. For more context on this project: http://blog.atom.io/2018/06/20/atom-metrics.htmlMore specifically:
telemetrylib as a dependency.StatsStoreto hold data which will eventually be sent to GitHub's internal analytics piepline.telemetryapis directly so that other Atom packages can consume them.telemetry. The plan is, for a while we'll be in a state where we are sending data to both Google Analytics and the internal pipeline. That way, we can cross check both sources. When we are confident that the internal pipeline data is solid, we will deprecate sending data to Google Analytics.Manual testing plan:
incrementCounterandaddCustomEventfrom the console. Manually callstore.reportStats()and verify that the stats are successfully sent tocentral.