Skip to content

Commit 65fff2b

Browse files
committed
Add missing common properties to error report
1 parent a5e3d3b commit 65fff2b

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

src/common/utils.ts

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,33 @@ function _cloneAndChange(obj: any, changer: (orig: any) => any, seen: Set<any>):
179179
return obj;
180180
}
181181

182+
/**
183+
* Copies all properties of source into destination. The optional parameter "overwrite" allows to control
184+
* if existing properties on the destination should be overwritten or not. Defaults to true (overwrite).
185+
*/
186+
export function mixin(destination: any, source: any, overwrite: boolean = true): any {
187+
if (!_isObject(destination)) {
188+
return source;
189+
}
190+
191+
if (_isObject(source)) {
192+
Object.keys(source).forEach(key => {
193+
if (key in destination) {
194+
if (overwrite) {
195+
if (_isObject(destination[key]) && _isObject(source[key])) {
196+
mixin(destination[key], source[key], overwrite);
197+
} else {
198+
destination[key] = source[key];
199+
}
200+
}
201+
} else {
202+
destination[key] = source[key];
203+
}
204+
});
205+
}
206+
return destination;
207+
}
208+
182209
export function getServiceURL(gitpodHost: string): string {
183210
return new URL(gitpodHost).toString().replace(/\/$/, '');
184211
}

src/extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export async function activate(context: vscode.ExtensionContext) {
6262
if (context.storageUri) {
6363
piiPaths.push(context.storageUri.fsPath);
6464
}
65-
telemetryService = new TelemetryService(packageJSON.segmentKey, piiPaths, logger);
65+
telemetryService = new TelemetryService(extensionId, packageJSON.version, packageJSON.segmentKey, piiPaths, logger);
6666

6767
const notificationService = new NotificationService(telemetryService);
6868

src/services/telemetryService.ts

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { Analytics, AnalyticsSettings } from '@segment/analytics-node';
99
import { Disposable } from '../common/dispose';
1010
import { Configuration } from '../configuration';
1111
import { ILogService } from './logService';
12-
import { cloneAndChange, escapeRegExpCharacters } from '../common/utils';
12+
import { cloneAndChange, escapeRegExpCharacters, mixin } from '../common/utils';
1313

1414
const ProductionUntrustedSegmentKey = 'untrusted-dummy-key';
1515

@@ -48,7 +48,7 @@ export class TelemetryService extends Disposable implements ITelemetryService {
4848
private analitycsClients: Map<string, Analytics> = new Map();
4949
private telemetryLogger: vscode.TelemetryLogger;
5050

51-
constructor(segmentKey: string, piiPaths: string[], private readonly logService: ILogService) {
51+
constructor(extensionId: string, extensionVersion: string, segmentKey: string, piiPaths: string[], private readonly logService: ILogService) {
5252
super();
5353

5454
// static cleanup pattern for: `vscode-file:///DANGEROUS/PATH/resources/app/Useful/Information`
@@ -65,6 +65,8 @@ export class TelemetryService extends Disposable implements ITelemetryService {
6565
}
6666
}
6767

68+
const commonProperties = getCommonProperties(extensionId, extensionVersion);
69+
6870
this.telemetryLogger = this._register(vscode.env.createTelemetryLogger(
6971
{
7072
sendEventData: (eventName, data) => {
@@ -92,15 +94,16 @@ export class TelemetryService extends Disposable implements ITelemetryService {
9294
});
9395
},
9496
sendErrorData: (error, data) => {
95-
const properties = cleanData(data ?? {}, cleanupPatterns);
96-
const errorProps = cleanData({ stack: error.stack }, cleanupPatterns);
97+
let properties = cleanData(data ?? {}, cleanupPatterns);
98+
properties = mixin(properties, commonProperties);
99+
const errorProps = cleanData({ message: error.message, stack: error.stack }, cleanupPatterns);
97100

98101
// Unhandled errors have no data so use host from config
99102
const gitpodHost = properties['gitpodHost'] ?? Configuration.getGitpodHost();
100103
const errorMetricsEndpoint = this.getErrorMetricsEndpoint(gitpodHost);
101104

102105
properties['error_name'] = error.name;
103-
properties['error_message'] = error.message;
106+
properties['error_message'] = errorProps.message;
104107
properties['debug_workspace'] = String(properties['debug_workspace'] ?? false);
105108

106109
const workspaceId = properties['workspaceId'] ?? '';
@@ -114,7 +117,7 @@ export class TelemetryService extends Disposable implements ITelemetryService {
114117

115118
const jsonData = {
116119
component: 'vscode-desktop-extension',
117-
errorStack: errorProps.stack || String(error),
120+
errorStack: errorProps.stack || '',
118121
version: properties['common.extversion'],
119122
workspaceId,
120123
instanceId,
@@ -215,6 +218,33 @@ export class TelemetryService extends Disposable implements ITelemetryService {
215218
// Remove when upstream TODO is addressed
216219
// https://github.com/microsoft/vscode/blob/44ef5cc53127cbaa11dee1728bdf8c24522f8fa0/src/vs/workbench/api/common/extHostTelemetry.ts#L278-L279
217220

221+
function getCommonProperties(extensionId: string, extensionVersion: string) {
222+
const commonProperties = Object.create(null);
223+
commonProperties['common.os'] = os.platform();
224+
commonProperties['common.nodeArch'] = os.arch();
225+
commonProperties['common.platformversion'] = os.release().replace(/^(\d+)(\.\d+)?(\.\d+)?(.*)/, '$1$2$3');
226+
commonProperties['common.extname'] = extensionId;
227+
commonProperties['common.extversion'] = extensionVersion;
228+
if (vscode && vscode.env) {
229+
commonProperties['common.vscodemachineid'] = vscode.env.machineId;
230+
commonProperties['common.vscodesessionid'] = vscode.env.sessionId;
231+
commonProperties['common.vscodeversion'] = vscode.version;
232+
commonProperties['common.product'] = vscode.env.appHost;
233+
234+
switch (vscode.env.uiKind) {
235+
case vscode.UIKind.Web:
236+
commonProperties['common.uikind'] = 'web';
237+
break;
238+
case vscode.UIKind.Desktop:
239+
commonProperties['common.uikind'] = 'desktop';
240+
break;
241+
default:
242+
commonProperties['common.uikind'] = 'unknown';
243+
}
244+
}
245+
return commonProperties;
246+
}
247+
218248
function anonymizeFilePaths(stack: string, cleanupPatterns: RegExp[]): string {
219249

220250
// Fast check to see if it is a file path to avoid doing unnecessary heavy regex work

0 commit comments

Comments
 (0)