You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This simplifies things be handling opt-in/opt-out and ensuring no user info leaks into the data. Adopting it requires bumping he required VS Code version though.
since our Analytics class has many different methods/events, but TelemetrySender has only 2 generic methods (sendEventData and sendErrorData), would it be ok if each Analytics method is turned into an event? What do you think?
Those methods are just helpers for stronger typing from the calling code. They all call an event() method which converts everything into a map anyway.
So I think the Analytics class (which should take the TelemetryLogger returned from createTelemetryLogger()) should remain, and it should retain its logXxx methods, but the implementation of the current event() method would now call telemetryLogger.logUsage() instead of sending directly to GA.
Then the TelemetrySender (which was passed to createTelemetryLogger()) in its sendEventData method, would have the implementation of sending to GA.
By keeping the Analytics wrapper and having specific logXxx wrapper methods, it's easy to see exactly what analytics are being captured just from that one class, rather than lots of logUsage() calls scattered around the extension.
@aitor-gomila I'm not sure exactly which method you mean. The idea I had (but I haven't tried it out) was something like this:
class Analytics {
constructor(private readonly telemetryLogger: TelemetryLogger) {}
// existing public methods
public logFoo() {
this.event(Category.Extension, EventAction.Activated);
}
private event(category: Category, action: Action) {
// This now calls the telemetry logger instead of doing the HTTP request itself
this.telemetryLogger.logUsage(
category,
{
"action": action,
// + other fields currently added by Analytics.send() (settings etc.)
},
);
}
}
// New sender class that does the HTTP requests
class GoogleAnalyticsTelemetrySender extends TelemetrySender {
public sendEventData(eventName: string, data?: Record<string, any>) {
// existing code that's currently in Analytics.send() that
// does the HTTP request, but is only using data supplied in this method
// it doesn't read any config etc. (that's all done in Analytics.event() above
// so that if VS Code shows the data to the user, they see the full set of data
// being recorded)
}
}
/// setup in extension.ts
const analytics = new Analytics(createTelemetryLogger(new GoogleAnalyticsTelemetrySender()));
analytics.logFoo();
We could still have a private method instead TelemetrySender that both sendEventData and sendErrorData could call.
However, we don't actually use errors anymore. The only code that calls to log errors is in the legacy analysis server protocol, which is hardly used for anyone. I would just leave sendErrorData empty and not implement anything for errors. You can delete the logError method from Analytics and the single line that calls it :-)
Tried to create a private send method inside TelemetrySender but the compiler complained.
Odd. I tested it here and this seemed ok:
classFooimplementsTelemetrySender{publicsendEventData(eventName: string,data?: Record<string,any>|undefined): void{thrownewError("Method not implemented.");}publicsendErrorData(error: Error,data?: Record<string,any>|undefined): void{thrownewError("Method not implemented.");}privatefoo(){}}constsender=newFoo();constlogger=env.createTelemetryLogger(sender);
If you have issues though, let me know (although it's probably not important now if we just put the sending in sendEventData for now).
I actually think not logging errors is not a bad idea, but if we ever need them, we'll need to think about this issue, or just add an additional event type for errors.
Yeah, this can be something to consider for later. Right now we're not really capturing them so we shouldn't hold up migrating to the new APIs to change that.
Activity
DanTup commentedon Mar 9, 2023
Those methods are just helpers for stronger typing from the calling code. They all call an
event()method which converts everything into a map anyway.So I think the
Analyticsclass (which should take theTelemetryLoggerreturned fromcreateTelemetryLogger()) should remain, and it should retain itslogXxxmethods, but the implementation of the currentevent()method would now calltelemetryLogger.logUsage()instead of sending directly to GA.Then the
TelemetrySender(which was passed tocreateTelemetryLogger()) in its sendEventData method, would have the implementation of sending to GA.By keeping the
Analyticswrapper and having specificlogXxxwrapper methods, it's easy to see exactly what analytics are being captured just from that one class, rather than lots oflogUsage()calls scattered around the extension.DanTup commentedon Mar 23, 2023
@aitor-gomila I'm not sure exactly which method you mean. The idea I had (but I haven't tried it out) was something like this:
Does this seem feasible?
DanTup commentedon Mar 23, 2023
We could still have a private method instead
TelemetrySenderthat bothsendEventDataandsendErrorDatacould call.However, we don't actually use errors anymore. The only code that calls to log errors is in the legacy analysis server protocol, which is hardly used for anyone. I would just leave
sendErrorDataempty and not implement anything for errors. You can delete thelogErrormethod fromAnalyticsand the single line that calls it :-)DanTup commentedon Mar 23, 2023
Odd. I tested it here and this seemed ok:
If you have issues though, let me know (although it's probably not important now if we just put the sending in
sendEventDatafor now).Yeah, this can be something to consider for later. Right now we're not really capturing them so we shouldn't hold up migrating to the new APIs to change that.
DanTup commentedon Mar 23, 2023
Yep, I initially had errors because I was trying to
extendinstead ofimplementbut it's only aninterface.DanTup commentedon Mar 29, 2023
Done via #4457 :-)