Skip to content

Commit

Permalink
implement logic for manifest telemetry
Browse files Browse the repository at this point in the history
  • Loading branch information
Hweinstock committed Jan 23, 2025
1 parent abdb5fd commit 0aadddf
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 38 deletions.
14 changes: 9 additions & 5 deletions packages/core/src/amazonq/lsp/lspController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,11 +161,7 @@ export class LspController {
}
setImmediate(async () => {
try {
await lspSetupStage('final', async () => {
const installResult = await new WorkspaceLSPResolver().resolve()
await lspSetupStage('launch', async () => activateLsp(context, installResult.resourcePaths))
getLogger().info('LspController: LSP activated')
})
await this.setupLsp(context)
void LspController.instance.buildIndex(buildIndexConfig)
// log the LSP server CPU and Memory usage per 30 minutes.
globals.clock.setInterval(
Expand All @@ -186,4 +182,12 @@ export class LspController {
}
})
}

private async setupLsp(context: vscode.ExtensionContext) {
await lspSetupStage('all', async () => {
const installResult = await new WorkspaceLSPResolver().resolve()
await lspSetupStage('launch', async () => activateLsp(context, installResult.resourcePaths))
getLogger().info('LspController: LSP activated')
})
}
}
39 changes: 34 additions & 5 deletions packages/core/src/amazonq/lsp/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,43 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { LanguageServerSetupStage, telemetry } from '../../shared/telemetry'
import { LanguageServerSetup, LanguageServerSetupStage, telemetry } from '../../shared/telemetry'

export async function lspSetupStage<T>(stageName: LanguageServerSetupStage, stage: () => Promise<T>) {
/**
* Runs the designated stage within a telemetry span and optionally uses the getMetadata extractor to record metadata from the result of the stage.
* @param stageName name of stage for telemetry.
* @param runStage stage to be run.
* @param getMetadata metadata extracter to be applied to result.
* @returns result of stage
*/
export async function lspSetupStage<T>(
stageName: LanguageServerSetupStage,
runStage: () => Promise<T>,
getMetadata?: (result: T) => Partial<LanguageServerSetup>
) {
return await telemetry.languageServer_setup.run(async (span) => {
const startTime = performance.now()
const result = await stage()
const result = await runStage()
span.record({ languageServerSetupStage: stageName })
span.record({ duration: performance.now() - startTime })
if (getMetadata) {
span.record(getMetadata(result))
}
return result
})
}

/**
* Try Functions in the order presented and return the first returned result. If none return, throw the final error.
* @param functions non-empty list of functions to try.
* @returns
*/
export async function tryFunctions<Result>(functions: (() => Promise<Result>)[]): Promise<Result> {
let currentError: Error = new Error('No functions provided')
for (const func of functions) {
try {
return await func()
} catch (e) {
currentError = e as Error
}
}
throw currentError
}
30 changes: 6 additions & 24 deletions packages/core/src/amazonq/lsp/workspaceInstaller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ import { LanguageServerResolver } from '../../shared/lsp/lspResolver'
import { Range } from 'semver'
import { getNodeExecutableName } from '../../shared/lsp/utils/platform'
import { fs } from '../../shared/fs/fs'
import { telemetry } from '../../shared/telemetry'
import { lspSetupStage } from './util'

const manifestUrl = 'https://aws-toolkit-language-servers.amazonaws.com/q-context/manifest.json'
// this LSP client in Q extension is only going to work with these LSP server versions
Expand All @@ -20,28 +18,12 @@ const supportedLspServerVersions = '0.1.32'
export class WorkspaceLSPResolver implements LspResolver {
async resolve(): Promise<LspResolution> {
const name = 'AmazonQ-Workspace'
const manifest = await lspSetupStage('getManifest', async () => {
const result = await new ManifestResolver(manifestUrl, name).resolve()
telemetry.record({
manifestVersion: result.manifestSchemaVersion,
languageServerResourceLocation: result.location ?? 'unknown',
})
return result
})
telemetry.record({
manifestVersion: manifest.manifestSchemaVersion,
})
const installationResult = await lspSetupStage('getServer', async () => {
const result = await new LanguageServerResolver(
manifest,
name,
new Range(supportedLspServerVersions)
).resolve()
telemetry.record({
languageServerResourceLocation: result.location ?? 'unknown',
})
return result
})
const manifest = await new ManifestResolver(manifestUrl, name).resolve()
const installationResult = await new LanguageServerResolver(
manifest,
name,
new Range(supportedLspServerVersions)
).resolve()

const nodeName =
process.platform === 'win32' ? getNodeExecutableName() : `node-${process.platform}-${process.arch}`
Expand Down
16 changes: 12 additions & 4 deletions packages/core/src/shared/lsp/manifestResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { RetryableResourceFetcher } from '../resourcefetcher/httpResourceFetcher
import { Timeout } from '../utilities/timeoutUtils'
import globals from '../extensionGlobals'
import { Manifest } from './types'
import { lspSetupStage, tryFunctions } from '../../amazonq/lsp/util'

const logger = getLogger('lsp')

Expand All @@ -32,10 +33,17 @@ export class ManifestResolver {
* Fetches the latest manifest, falling back to local cache on failure
*/
async resolve(): Promise<Manifest> {
try {
return await this.fetchRemoteManifest()
} catch (error) {
return await this.getLocalManifest()
return await tryFunctions([
async () => await resolveManifestWith(async () => await this.fetchRemoteManifest()),
async () => await resolveManifestWith(async () => await this.getLocalManifest()),
])

async function resolveManifestWith(resolver: () => Promise<Manifest>) {
return await lspSetupStage('getManifest', async () => await resolver(), extractVersionFromResult)
}

function extractVersionFromResult(r: Manifest) {
return { manifestSchemaVersion: r.manifestSchemaVersion }
}
}

Expand Down

0 comments on commit 0aadddf

Please sign in to comment.