import { inject , injectable } from 'inversify' ; import Posthog from 'posthog-node' ; import type * as vscode from 'vscode' ; import { Configuration } from '../configuration' ; import { ILogger } from '../logger' ; import { IConfigurationAccessor } from '../configuration/configurationAccessor' ; import { IEnvironmentInfo } from '../util/environmentInfo' ; import { IDisposable } from '../util/types' ; import { AnalyticsEventDataPoints , AnalyticsEvents } from './events' ; import isBuiltInOperatorName from './isBuiltInOperatorName' ; import { IPosthogConfiguration } from './posthogConfiguration' ; export const IAnalyticsReporter = Symbol ( 'AnalyticsReporter' ) ; type EventToMethodMapping = { 'debug session started' : 'debugSessionStarted' ; 'debug session stopped' : 'debugSessionStopped' ; 'operator log point enabled' : 'operatorLogPointEnabled' ; 'operator log point disabled' : 'operatorLogPointDisabled' ; } ; type CaptureEventMethods = { [ Property in keyof AnalyticsEventDataPoints as `capture${ Capitalize < EventToMethodMapping [ Property ] > }` ] : ( dataPoints : AnalyticsEventDataPoints [ Property ] ) => void ; } ; export interface IAnalyticsReporter extends IDisposable , CaptureEventMethods { } see https @ injectable ( ) export default class PosthogAnalyticsReporter implements IAnalyticsReporter { private postHog : Posthog | null = null ; private readonly onDidChangeTelemetryEnabledDisposable : IDisposable ; constructor ( @ inject ( IPosthogConfiguration ) private readonly posthogConfiguration , @ inject ( IEnvironmentInfo ) private readonly environmentInfo , @ inject ( IConfigurationAccessor ) private readonly configurationAccessor , @ inject ( ILogger ) private readonly logger ) { if ( configurationAccessor . get ( Configuration . EnableAnalytics , false ) ) { this . start ( ) ; } this . onDidChangeTelemetryEnabledDisposable = configurationAccessor . onDidChangeConfiguration ( this . onDidChangeConfiguration , this ) ; } private start ( ) { if ( ! this . postHog ) { this . logger . info ( 'AnalyticsReporter' , 'Starting Reporter' ) ; this . postHog = new Posthog ( this . posthogConfiguration . projectApiKey , { host : this . posthogConfiguration . host } ) ; this . postHog . identify ( { distinctId : this . distinctId , properties : { vscodeVersion : this . environmentInfo . version , vscodeLanguage : this . environmentInfo . language , extensionVersion : this . environmentInfo . extensionVersion , } , } ) ; } } private stop ( ) { if ( this . postHog ) { this . logger . info ( 'AnalyticsReporter' , 'Stopping Reporter' ) ; this . postHog . shutdown ( ) ; this . postHog = null ; } } private capture < E extends AnalyticsEvents > ( event , dataPoints ) { if ( this . postHog ) { this . logger . info ( 'AnalyticsReporter' , `Capture "${ event }" with data points: ${ JSON . stringify ( dataPoints ) }` ) ; this . postHog . capture ( { distinctId : this . distinctId , event , properties : dataPoints , } ) ; } } private onDidChangeConfiguration ( { affectsConfiguration } ) { if ( affectsConfiguration ( Configuration . EnableAnalytics ) ) { const enabled = this . configurationAccessor . get ( Configuration . EnableAnalytics , false ) ; if ( enabled ) { this . start ( ) ; } else { this . stop ( ) ; } } } private get distinctId ( ) : string { return this . environmentInfo . machineId ; } captureOperatorLogPointEnabled ( { operatorName } ) { const dataPoints = operatorName ? ( isBuiltInOperatorName ( operatorName ) ? { operatorName } : { } ) : { } ; this . capture ( 'operator log point enabled' , dataPoints ) ; } captureOperatorLogPointDisabled ( { operatorName } ) { const dataPoints = operatorName ? ( isBuiltInOperatorName ( operatorName ) ? { operatorName } : { } ) : { } ; this . capture ( 'operator log point disabled' , dataPoints ) ; } captureDebugSessionStarted ( dataPoints ) { this . capture ( 'debug session started' , dataPoints ) ; } captureDebugSessionStopped ( ) { this . capture ( 'debug session stopped' , { } ) ; } dispose ( ) { this . onDidChangeTelemetryEnabledDisposable . dispose ( ) ; this . stop ( ) ; } }