Skip to content

Commit

Permalink
Add export logs contribution
Browse files Browse the repository at this point in the history
  • Loading branch information
jeanp413 committed Apr 14, 2022
1 parent 80570bf commit a0aafc1
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 5 deletions.
3 changes: 3 additions & 0 deletions build/.webignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,6 @@ xterm-addon-webgl/out/**

browser-headers/**
google-protobuf/**

@zip.js/**
!@zip.js/zip.js/dist/zip-no-worker-deflate.min.js
15 changes: 13 additions & 2 deletions extensions/gitpod-web/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ export async function activate(context: vscode.ExtensionContext) {
if (!gitpodContext) {
return;
}
registerDesktop(gitpodContext);

logContextInfo(gitpodContext);

registerDesktop();
registerAuth(gitpodContext);
registerPorts(gitpodContext);
registerTasks(gitpodContext, (options, parentTerminal) => {
Expand Down Expand Up @@ -64,6 +67,14 @@ export function deactivate() {
return gitpodContext.dispose();
}

function logContextInfo(context: GitpodExtensionContext) {
const output = context.output;

output.appendLine(`GITPOD_WORKSPACE_CONTEXT_URL: ${context.info.getWorkspaceContextUrl()}`);
output.appendLine(`GITPOD_INSTANCE_ID: ${context.info.getInstanceId()}`);
output.appendLine(`GITPOD_WORKSPACE_URL: ${context.info.getWorkspaceUrl()}`);
}

export function registerAuth(context: GitpodExtensionContext): void {
type Keytar = {
getPassword: typeof keytarType['getPassword'];
Expand Down Expand Up @@ -1196,7 +1207,7 @@ export function registerExtensionManagement(context: GitpodExtensionContext): vo
context.subscriptions.push(vscode.extensions.onDidChange(() => validateGitpodFile()));
}

export async function registerDesktop(_: GitpodExtensionContext): Promise<void> {
async function registerDesktop(): Promise<void> {
const config = vscode.workspace.getConfiguration('gitpod.openInStable');
if (config.get<boolean>('neverPrompt') === true) {
return;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
"@vscode/sqlite3": "5.0.8",
"@vscode/sudo-prompt": "9.3.1",
"@vscode/vscode-languagedetection": "1.0.21",
"@zip.js/zip.js": "^2.4.6",
"applicationinsights": "1.4.2",
"graceful-fs": "4.2.8",
"http-proxy-agent": "^2.1.0",
Expand Down
1 change: 1 addition & 0 deletions remote/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"@microsoft/applicationinsights-web": "^2.6.4",
"@vscode/iconv-lite-umd": "0.7.0",
"@vscode/vscode-languagedetection": "1.0.21",
"@zip.js/zip.js": "^2.4.6",
"jschardet": "3.0.0",
"tas-client-umd": "0.1.4",
"vscode-oniguruma": "1.6.1",
Expand Down
5 changes: 5 additions & 0 deletions remote/web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@
resolved "https://registry.yarnpkg.com/@vscode/vscode-languagedetection/-/vscode-languagedetection-1.0.21.tgz#89b48f293f6aa3341bb888c1118d16ff13b032d3"
integrity sha512-zSUH9HYCw5qsCtd7b31yqkpaCU6jhtkKLkvOOA8yTrIRfBSOFb8PPhgmMicD7B/m+t4PwOJXzU1XDtrM9Fd3/g==

"@zip.js/zip.js@^2.4.6":
version "2.4.6"
resolved "https://registry.yarnpkg.com/@zip.js/zip.js/-/zip.js-2.4.6.tgz#eb284910f4dcbccb267c5ef76950fb84ee43bb74"
integrity sha512-gP13tvMy1bhaTWw5I/Sm3mJAOU7J8S18e4sAcscGzYY8NVUF8FRirfY17eYq+rZhRBk8SNg5bFzzWgFR47qSyw==

browser-headers@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/browser-headers/-/browser-headers-0.4.1.tgz#4308a7ad3b240f4203dbb45acedb38dc2d65dd02"
Expand Down
157 changes: 157 additions & 0 deletions src/vs/gitpod/browser/workbench/contrib/exportLogs.contribution.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
/* eslint-disable code-import-patterns */
/* eslint-disable header/header */
/*---------------------------------------------------------------------------------------------
* Copyright (c) Gitpod. All rights reserved.
*--------------------------------------------------------------------------------------------*/

import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/environment/browser/environmentService';
import { IRemoteAgentService } from 'vs/workbench/services/remote/common/remoteAgentService';
import { IFileService } from 'vs/platform/files/common/files';
import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/actions';
import { CATEGORIES } from 'vs/workbench/common/actions';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { URI } from 'vs/base/common/uri';
import * as resources from 'vs/base/common/resources';
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import type * as zipModule from '@zip.js/zip.js';
import { Schemas } from 'vs/base/common/network';
import { triggerDownload } from 'vs/base/browser/dom';

const getZipModule = (function () {
let zip: typeof zipModule;
return async () => {
if (!zip) {
// when actually importing the module change `zip.js` to `zipjs`
// without the dot because loader.js will do a check for `.js` extension
// and it won't resolve the module path correctly
// @ts-ignore
zip = await import('@zip.js/zipjs');
zip.configure({
useWebWorkers: false
});
}
return zip;
};
})();

registerAction2(class ExportLogsAction extends Action2 {
constructor() {
super({
id: 'gitpod.workbench.exportLogs',
title: { original: 'Export all logs', value: 'Export all logs' },
category: CATEGORIES.Developer,
menu: {
id: MenuId.CommandPalette
}
});
}

async run(accessor: ServicesAccessor): Promise<void> {
const progressService = accessor.get(IProgressService);
const fileService = accessor.get(IFileService);
const environmentService = accessor.get(IBrowserWorkbenchEnvironmentService);
const remoteAgentService = accessor.get(IRemoteAgentService);

const cts = new CancellationTokenSource();
const bufferData = await progressService.withProgress<Uint8Array | undefined>(
{
location: ProgressLocation.Dialog,
title: 'Exporting logs to zip file ...',
cancellable: true,
delay: 1000
},
async progress => {
const token = cts.token;

const zip = await getZipModule();
const uint8ArrayWriter = new zip.Uint8ArrayWriter();
const writer = new zip.ZipWriter(uint8ArrayWriter);

if (token.isCancellationRequested) {
return undefined;
}

const entries: { name: string; resource: URI }[] = [];
const logsPath = URI.file(environmentService.logsPath).with({ scheme: environmentService.logFile.scheme });
const stat = await fileService.resolve(logsPath);
if (stat.children) {
entries.push(...stat.children.filter(stat => !stat.isDirectory).map(stat => ({ name: resources.basename(stat.resource), resource: stat.resource })));
}

if (token.isCancellationRequested) {
return undefined;
}

const remoteEnv = await remoteAgentService.getEnvironment();
const remoteLogsPath = remoteEnv?.logsPath;
if (remoteLogsPath) {
const remoteAgentLogFile = resources.joinPath(remoteLogsPath, 'remoteagent.log');
if (await fileService.exists(remoteAgentLogFile)) {
entries.push({ name: resources.basename(remoteAgentLogFile), resource: remoteAgentLogFile });
}
}

if (token.isCancellationRequested) {
return undefined;
}

const remoteExtHostLogsPath = remoteEnv?.extensionHostLogsPath;
if (remoteExtHostLogsPath) {
const remoteExtHostLogsFile = resources.joinPath(remoteExtHostLogsPath, 'exthost.log');
if (await fileService.exists(remoteExtHostLogsFile)) {
entries.push({ name: resources.basename(remoteExtHostLogsFile), resource: remoteExtHostLogsFile });
}

let stat = await fileService.resolve(remoteExtHostLogsPath);
if (stat.children) {
const ouputLoggingDirs = stat.children.filter(stat => stat.isDirectory);
for (const outLogDir of ouputLoggingDirs) {
if (token.isCancellationRequested) {
return undefined;
}

stat = await fileService.resolve(outLogDir.resource);
if (stat.children) {
entries.push(...stat.children.filter(stat => !stat.isDirectory).map(stat => ({
name: `${resources.basename(outLogDir.resource)}_${resources.basename(stat.resource)}`,
resource: stat.resource
})));
}
}
}
}

if (token.isCancellationRequested) {
return undefined;
}

const credentialHelperPath = URI.file('/tmp/gitpod-git-credential-helper.log').with({ scheme: Schemas.vscodeRemote });
if (await fileService.exists(credentialHelperPath)) {
entries.push({ name: resources.basename(credentialHelperPath), resource: credentialHelperPath });
}

console.log('All log entries', entries);

for (const entry of entries) {
if (token.isCancellationRequested) {
return undefined;
}
const content = await fileService.readFile(entry.resource, { atomic: true }, token);

if (token.isCancellationRequested) {
return undefined;
}
await writer.add(entry.name, new zip.Uint8ArrayReader(content.value.buffer));
}

return writer.close();
},
() => cts.dispose(true)
);

if (bufferData) {
triggerDownload(bufferData, 'vscodeLogs.zip');
}
}
});
5 changes: 3 additions & 2 deletions src/vs/gitpod/browser/workbench/workbench-dev.html
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@
}),
paths: {
...self.webPackagePaths,
'@gitpod/local-app-api-grpcweb': `${window.location.origin}/static/node_modules/@gitpod/local-app-api-grpcweb/lib/localapp.js`,
'@improbable-eng/grpc-web': `${window.location.origin}/static/node_modules/@improbable-eng/grpc-web/dist/grpc-web-client.umd.js`
'@gitpod/local-app-api-grpcweb': `${window.location.origin}/static/remote/web/node_modules/@gitpod/local-app-api-grpcweb/lib/localapp.js`,
'@improbable-eng/grpc-web': `${window.location.origin}/static/remote/web/node_modules/@improbable-eng/grpc-web/dist/grpc-web-client.umd.js`,
'@zip.js/zipjs': `${window.location.origin}/static/remote/web/node_modules/@zip.js/zip.js/dist/zip-no-worker-deflate.min.js`
}
});
</script>
Expand Down
3 changes: 2 additions & 1 deletion src/vs/gitpod/browser/workbench/workbench.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
paths: {
...self.webPackagePaths,
'@gitpod/local-app-api-grpcweb': `${window.location.origin}/static/node_modules/@gitpod/local-app-api-grpcweb/lib/localapp.js`,
'@improbable-eng/grpc-web': `${window.location.origin}/static/node_modules/@improbable-eng/grpc-web/dist/grpc-web-client.umd.js`
'@improbable-eng/grpc-web': `${window.location.origin}/static/node_modules/@improbable-eng/grpc-web/dist/grpc-web-client.umd.js`,
'@zip.js/zipjs': `${window.location.origin}/static/node_modules/@zip.js/zip.js/dist/zip-no-worker-deflate.min.js`
}
});
</script>
Expand Down
4 changes: 4 additions & 0 deletions src/vs/workbench/workbench.web.main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ import 'vs/workbench/contrib/splash/browser/splash.contribution';
// Offline
import 'vs/workbench/contrib/offline/browser/offline.contribution';

// Gitpod: Export Logs command
// eslint-disable-next-line code-import-patterns
import 'vs/gitpod/browser/workbench/contrib/exportLogs.contribution';

//#endregion


Expand Down
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2116,6 +2116,11 @@
resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d"
integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==

"@zip.js/zip.js@^2.4.6":
version "2.4.6"
resolved "https://registry.yarnpkg.com/@zip.js/zip.js/-/zip.js-2.4.6.tgz#eb284910f4dcbccb267c5ef76950fb84ee43bb74"
integrity sha512-gP13tvMy1bhaTWw5I/Sm3mJAOU7J8S18e4sAcscGzYY8NVUF8FRirfY17eYq+rZhRBk8SNg5bFzzWgFR47qSyw==

abbrev@1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8"
Expand Down

0 comments on commit a0aafc1

Please sign in to comment.