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

Commit 1766c30

Browse files
dadlerjabeatrix
andauthored
Refactor eventlogger and use localstorage for server endpoint (#309)
* Refactor eventlogger so that the "shared" EventLogger.ts file doesn't contain any VSCode-specific logic; move all of that to the "vscode" event-logger.ts file instead * Default to `localStorage.endpoint()` for server endpoint values for logging (`config.serverEndpoint` was deprecated as of 5.1 and now just returns an empty string in most cases) The tsconfig updates were automatic when I compiled... If they shouldn't be included here, please let me know! ## Test plan * run locally * verify payload * test that config updates are caught --------- Co-authored-by: Beatrix <[email protected]>
1 parent 546fcf6 commit 1766c30

File tree

12 files changed

+84
-120
lines changed

12 files changed

+84
-120
lines changed
Lines changed: 42 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,80 +1,31 @@
1-
import * as vscode from 'vscode'
2-
1+
import { ConfigurationWithAccessToken } from '../configuration'
32
import { SourcegraphGraphQLAPIClient } from '../sourcegraph-api/graphql'
43

5-
function getServerEndpointFromConfig(config: vscode.WorkspaceConfiguration): string {
6-
return config.get<string>('cody.serverEndpoint', '')
7-
}
8-
9-
function getUseContextFromConfig(config: vscode.WorkspaceConfiguration): string {
10-
if (!config) {
11-
return ''
12-
}
13-
return config.get<string>('cody.useContext', '')
14-
}
15-
16-
function getChatPredictionsFromConfig(config: vscode.WorkspaceConfiguration): boolean {
17-
if (!config) {
18-
return false
19-
}
20-
return config.get<boolean>('cody.experimental.chatPredictions', false)
21-
}
22-
23-
function getInlineFromConfig(config: vscode.WorkspaceConfiguration): boolean {
24-
if (!config) {
25-
return false
26-
}
27-
return config.get<boolean>('cody.inlineChat.enabled', false)
28-
}
29-
30-
function getNonStopFromConfig(config: vscode.WorkspaceConfiguration): boolean {
31-
if (!config) {
32-
return false
33-
}
34-
return config.get<boolean>('cody.experimental.nonStop', false)
35-
}
36-
37-
function getSuggestionsFromConfig(config: vscode.WorkspaceConfiguration): boolean {
38-
if (!config) {
39-
return false
40-
}
41-
return config.get<boolean>('cody.experimental.suggestions', false)
42-
}
43-
44-
function getGuardrailsFromConfig(config: vscode.WorkspaceConfiguration): boolean {
45-
if (!config) {
46-
return false
47-
}
48-
return config.get<boolean>('cody.experimental.guardrails', false)
4+
export interface ExtensionDetails {
5+
ide: 'VSCode' | 'JetBrains' | 'Neovim' | 'Emacs'
6+
ideExtensionType: 'Cody' | 'CodeSearch'
497
}
508

519
export class EventLogger {
52-
private serverEndpoint = getServerEndpointFromConfig(vscode.workspace.getConfiguration())
53-
private extensionDetails = { ide: 'VSCode', ideExtensionType: 'Cody' }
54-
private constructor(private gqlAPIClient: SourcegraphGraphQLAPIClient) {}
55-
56-
public static create(gqlAPIClient: SourcegraphGraphQLAPIClient): EventLogger {
57-
return new EventLogger(gqlAPIClient)
58-
}
10+
private gqlAPIClient: SourcegraphGraphQLAPIClient
5911

60-
public configurationDetails = {
61-
contextSelection: getUseContextFromConfig(vscode.workspace.getConfiguration()),
62-
chatPredictions: getChatPredictionsFromConfig(vscode.workspace.getConfiguration()),
63-
inline: getInlineFromConfig(vscode.workspace.getConfiguration()),
64-
nonStop: getNonStopFromConfig(vscode.workspace.getConfiguration()),
65-
suggestions: getSuggestionsFromConfig(vscode.workspace.getConfiguration()),
66-
guardrails: getGuardrailsFromConfig(vscode.workspace.getConfiguration()),
12+
constructor(
13+
private serverEndpoint: string,
14+
private extensionDetails: ExtensionDetails,
15+
private config: ConfigurationWithAccessToken
16+
) {
17+
this.gqlAPIClient = new SourcegraphGraphQLAPIClient(this.config)
6718
}
6819

69-
public onConfigurationChange(newconfig: vscode.WorkspaceConfiguration): void {
70-
this.configurationDetails = {
71-
contextSelection: getUseContextFromConfig(newconfig),
72-
chatPredictions: getChatPredictionsFromConfig(newconfig),
73-
inline: getInlineFromConfig(newconfig),
74-
nonStop: getNonStopFromConfig(newconfig),
75-
suggestions: getSuggestionsFromConfig(newconfig),
76-
guardrails: getGuardrailsFromConfig(newconfig),
77-
}
20+
public onConfigurationChange(
21+
newServerEndpoint: string,
22+
newExtensionDetails: ExtensionDetails,
23+
newConfig: ConfigurationWithAccessToken
24+
): void {
25+
this.serverEndpoint = newServerEndpoint
26+
this.extensionDetails = newExtensionDetails
27+
this.config = newConfig
28+
this.gqlAPIClient.onConfigurationChange(newConfig)
7829
}
7930

8031
/**
@@ -91,32 +42,37 @@ export class EventLogger {
9142
* @param publicProperties Public argument information.
9243
*/
9344
public log(eventName: string, anonymousUserID: string, eventProperties?: any, publicProperties?: any): void {
45+
const configurationDetails = {
46+
contextSelection: this.config.useContext,
47+
chatPredictions: this.config.experimentalChatPredictions,
48+
inline: this.config.inlineChat,
49+
nonStop: this.config.experimentalNonStop,
50+
guardrails: this.config.experimentalGuardrails,
51+
}
9452
const argument = {
9553
...eventProperties,
9654
serverEndpoint: this.serverEndpoint,
9755
extensionDetails: this.extensionDetails,
98-
configurationDetails: this.configurationDetails,
56+
configurationDetails,
9957
}
10058
const publicArgument = {
10159
...publicProperties,
10260
serverEndpoint: this.serverEndpoint,
10361
extensionDetails: this.extensionDetails,
104-
configurationDetails: this.configurationDetails,
105-
}
106-
try {
107-
this.gqlAPIClient
108-
.logEvent({
109-
event: eventName,
110-
userCookieID: anonymousUserID,
111-
source: 'IDEEXTENSION',
112-
url: '',
113-
argument: JSON.stringify(argument),
114-
publicArgument: JSON.stringify(publicArgument),
115-
})
116-
.then(() => {})
117-
.catch(() => {})
118-
} catch (error) {
119-
console.log(error)
62+
configurationDetails,
12063
}
64+
this.gqlAPIClient
65+
.logEvent({
66+
event: eventName,
67+
userCookieID: anonymousUserID,
68+
source: 'IDEEXTENSION',
69+
url: '',
70+
argument: JSON.stringify(argument),
71+
publicArgument: JSON.stringify(publicArgument),
72+
})
73+
.then(() => {})
74+
.catch(error => {
75+
console.log(error)
76+
})
12177
}
12278
}

lib/shared/tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@
66
"outDir": "dist",
77
"lib": ["ESNext", "DOM.Iterable"],
88
},
9-
"include": ["src"],
9+
"include": ["src", "src/telemetry/EventLogger.ts"],
1010
"exclude": ["dist"],
1111
}

vscode/src/chat/ChatViewProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,14 @@ import { isError } from '@sourcegraph/cody-shared/src/utils'
2828
import { View } from '../../webviews/NavBar'
2929
import { getFullConfig } from '../configuration'
3030
import { VSCodeEditor } from '../editor/vscode-editor'
31-
import { logEvent } from '../event-logger'
3231
import { FilenameContextFetcher } from '../local-context/filename-context-fetcher'
3332
import { LocalKeywordContextFetcher } from '../local-context/local-keyword-context-fetcher'
3433
import { debug } from '../log'
3534
import { getRerankWithLog } from '../logged-rerank'
3635
import { FixupTask } from '../non-stop/FixupTask'
3736
import { IdleRecipeRunner } from '../non-stop/roles'
3837
import { AuthProvider } from '../services/AuthProvider'
38+
import { logEvent } from '../services/EventLogger'
3939
import { LocalStorage } from '../services/LocalStorageProvider'
4040
import { SecretStorage } from '../services/SecretStorageProvider'
4141
import { TestSupport } from '../test-support'

vscode/src/completions/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import { LRUCache } from 'lru-cache'
22
import * as vscode from 'vscode'
33

44
import { ConfigKeys } from '../configuration-keys'
5-
import { logEvent } from '../event-logger'
65
import { debug } from '../log'
6+
import { logEvent } from '../services/EventLogger'
77

88
interface CompletionEvent {
99
params: {

vscode/src/configuration.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type {
88

99
import { DOTCOM_URL } from './chat/protocol'
1010
import { CONFIG_KEY, ConfigKeys } from './configuration-keys'
11-
import { logEvent } from './event-logger'
11+
import { logEvent } from './services/EventLogger'
1212
import { LocalStorage } from './services/LocalStorageProvider'
1313
import { getAccessToken, SecretStorage } from './services/SecretStorageProvider'
1414

vscode/src/local-context/local-keyword-context-fetcher.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import { ChatClient } from '@sourcegraph/cody-shared/src/chat/chat'
1010
import { Editor } from '@sourcegraph/cody-shared/src/editor'
1111
import { ContextResult, KeywordContextFetcher } from '@sourcegraph/cody-shared/src/local-context'
1212

13-
import { logEvent } from '../event-logger'
1413
import { debug } from '../log'
14+
import { logEvent } from '../services/EventLogger'
1515

1616
/**
1717
* Exclude files without extensions and hidden files (starts with '.')

vscode/src/main.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ import { createProviderConfig as createUnstableCodeGenProviderConfig } from './c
2020
import { createProviderConfig as createUnstableHuggingFaceProviderConfig } from './completions/providers/unstable-huggingface'
2121
import { getConfiguration, getFullConfig, migrateConfiguration } from './configuration'
2222
import { VSCodeEditor } from './editor/vscode-editor'
23-
import { eventLogger, logEvent, updateEventLogger } from './event-logger'
2423
import { configureExternalServices } from './external-services'
2524
import { MyPromptController } from './my-cody/MyPromptController'
2625
import { FixupController } from './non-stop/FixupController'
2726
import { showSetupNotification } from './notifications/setup-notification'
2827
import { getRgPath } from './rg'
2928
import { AuthProvider } from './services/AuthProvider'
29+
import { createOrUpdateEventLogger, logEvent } from './services/EventLogger'
3030
import { showFeedbackSupportQuickPick } from './services/FeedbackOptions'
3131
import { GuardrailsProvider } from './services/GuardrailsProvider'
3232
import { InlineController } from './services/InlineController'
@@ -87,7 +87,7 @@ const register = async (
8787
}> => {
8888
const disposables: vscode.Disposable[] = []
8989

90-
await updateEventLogger(initialConfig, localStorage)
90+
await createOrUpdateEventLogger(initialConfig, localStorage)
9191
// Controller for inline Chat
9292
const commentController = new InlineController(context.extensionPath)
9393

@@ -141,7 +141,9 @@ const register = async (
141141
}),
142142
// Update external services when configurationChangeEvent is fired by chatProvider
143143
chatProvider.configurationChangeEvent.event(async () => {
144-
externalServicesOnDidConfigurationChange(await getFullConfig(secretStorage, localStorage))
144+
const newConfig = await getFullConfig(secretStorage, localStorage)
145+
externalServicesOnDidConfigurationChange(newConfig)
146+
createOrUpdateEventLogger(newConfig, localStorage).catch(error => console.error(error))
145147
})
146148
)
147149

@@ -342,9 +344,7 @@ const register = async (
342344
onConfigurationChange: newConfig => {
343345
chatProvider.onConfigurationChange(newConfig)
344346
externalServicesOnDidConfigurationChange(newConfig)
345-
if (eventLogger) {
346-
eventLogger.onConfigurationChange(vscode.workspace.getConfiguration())
347-
}
347+
void createOrUpdateEventLogger(newConfig, localStorage)
348348
},
349349
}
350350
}

vscode/src/services/AuthProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ import {
1616
unauthenticatedStatus,
1717
} from '../chat/protocol'
1818
import { newAuthStatus } from '../chat/utils'
19-
import { logEvent } from '../event-logger'
2019
import { debug } from '../log'
2120

2221
import { AuthMenu, LoginStepInputBox, TokenInputBox } from './AuthMenus'
22+
import { logEvent } from './EventLogger'
2323
import { LocalAppDetector } from './LocalAppDetector'
2424
import { LocalStorage } from './LocalStorageProvider'
2525
import { SecretStorage } from './SecretStorageProvider'

vscode/src/event-logger.ts renamed to vscode/src/services/EventLogger.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,34 @@
11
import { ConfigurationWithAccessToken } from '@sourcegraph/cody-shared/src/configuration'
2-
import { SourcegraphGraphQLAPIClient } from '@sourcegraph/cody-shared/src/sourcegraph-api/graphql'
3-
import { EventLogger } from '@sourcegraph/cody-shared/src/telemetry/EventLogger'
2+
import { EventLogger, ExtensionDetails } from '@sourcegraph/cody-shared/src/telemetry/EventLogger'
43

5-
import { version as packageVersion } from '../package.json'
4+
import { version as packageVersion } from '../../package.json'
5+
import { debug } from '../log'
66

7-
import { debug } from './log'
8-
import { LocalStorage } from './services/LocalStorageProvider'
7+
import { LocalStorage } from './LocalStorageProvider'
98

10-
let eventLoggerGQLClient: SourcegraphGraphQLAPIClient
119
export let eventLogger: EventLogger | null = null
1210
let anonymousUserID: string
1311

14-
export async function updateEventLogger(
15-
config: Pick<ConfigurationWithAccessToken, 'serverEndpoint' | 'accessToken' | 'customHeaders'>,
12+
const extensionDetails: ExtensionDetails = { ide: 'VSCode', ideExtensionType: 'Cody' }
13+
14+
export async function createOrUpdateEventLogger(
15+
config: ConfigurationWithAccessToken,
1616
localStorage: LocalStorage
1717
): Promise<void> {
1818
const status = await localStorage.setAnonymousUserID()
1919
anonymousUserID = localStorage.getAnonymousUserID() || ''
20-
if (!eventLoggerGQLClient) {
21-
eventLoggerGQLClient = new SourcegraphGraphQLAPIClient(config)
22-
eventLogger = EventLogger.create(eventLoggerGQLClient)
20+
const serverEndpoint = localStorage?.getEndpoint() || config.serverEndpoint
21+
22+
if (!eventLogger) {
23+
eventLogger = new EventLogger(serverEndpoint, extensionDetails, config)
2324
if (status === 'installed') {
2425
logEvent('CodyInstalled')
2526
} else {
2627
logEvent('CodyVSCodeExtension:CodySavedLogin:executed')
2728
}
28-
} else {
29-
eventLoggerGQLClient.onConfigurationChange(config)
29+
return
3030
}
31+
eventLogger?.onConfigurationChange(serverEndpoint, extensionDetails, config)
3132
}
3233

3334
/**

vscode/src/services/InlineController.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ import * as vscode from 'vscode'
44
import { ActiveTextEditorSelection } from '@sourcegraph/cody-shared/src/editor'
55
import { SURROUNDING_LINES } from '@sourcegraph/cody-shared/src/prompt/constants'
66

7-
import { logEvent } from '../event-logger'
87
import { CodyTaskState } from '../non-stop/utils'
98

109
import { CodeLensProvider } from './CodeLensProvider'
10+
import { logEvent } from './EventLogger'
1111
import { editDocByUri, getIconPath, updateRangeOnDocChange } from './InlineAssist'
1212

1313
const initPost = new vscode.Position(0, 0)

0 commit comments

Comments
 (0)