Skip to content

Commit 61e389e

Browse files
committed
1) Updated debug log env variable
2) Added build time config for telemetry 3) Fixed status code around bug 4) added important headers in the post request of telemetry events
1 parent 254a59f commit 61e389e

File tree

10 files changed

+187
-82
lines changed

10 files changed

+187
-82
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ build/
66
/nbcode/l10n/locale_zh_CN/release/
77
/nbcode/l10n/locale_ja/nbproject/private/
88
/nbcode/l10n/locale_zh_CN/nbproject/private/
9+
telemetryConfig.json

vscode/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
"preLaunchTask": "${defaultBuildTask}",
3535
"env": {
3636
"nbcode_userdir": "global",
37-
"oracle.oracle-java.enable.debug-logs": "true"
37+
"oracle_oracleJava_enable_debugLogs": "true"
3838
}
3939
},
4040
{

vscode/esbuild.js

Lines changed: 80 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,19 @@ const scriptConfig = {
1515
};
1616

1717
const watchConfig = {
18-
watch: {
19-
onRebuild(error, result) {
20-
console.log("[watch] build started");
21-
if (error) {
22-
error.errors.forEach(error =>
23-
console.error(`> ${error.location.file}:${error.location.line}:${error.location.column}: error: ${error.text}`)
24-
);
25-
} else {
26-
console.log("[watch] build finished");
27-
}
28-
},
18+
watch: {
19+
onRebuild(error, result) {
20+
console.log("[watch] build started");
21+
if (error) {
22+
error.errors.forEach(error =>
23+
console.error(`> ${error.location.file}:${error.location.line}:${error.location.column}: error: ${error.text}`)
24+
);
25+
} else {
26+
console.log("[watch] build finished");
27+
}
2928
},
30-
};
29+
},
30+
};
3131

3232
const NON_NPM_ARTIFACTORY = new RegExp(
3333
String.raw`"resolved"\s*:\s*"http[s]*://(?!registry.npmjs.org)[^"]+"`,
@@ -43,26 +43,74 @@ const checkAritfactoryUrl = () => {
4343
}
4444
}
4545

46-
(async () => {
47-
const args = process.argv.slice(2);
48-
try {
49-
if (args.includes("--watch")) {
50-
// Build and watch source code
51-
console.log("[watch] build started");
52-
await build({
53-
...scriptConfig,
54-
...watchConfig,
46+
const createTelemetryConfig = () => {
47+
const defaultConfig = {
48+
telemetryRetryConfig: {
49+
maxRetries: 6,
50+
baseCapacity: 256,
51+
baseTimer: 5000,
52+
maxDelayMs: 100000,
53+
backoffFactor: 2,
54+
jitterFactor: 0.25
55+
},
56+
telemetryApi: {
57+
baseUrl: null,
58+
baseEndpoint: "/vscode/java/sendTelemetry",
59+
version: "/v1"
60+
}
61+
}
62+
63+
const envConfig = Object.freeze({
64+
telemetryRetryConfig: {
65+
maxRetries: process.env.TELEMETRY_MAX_RETRIES,
66+
baseCapacity: process.env.TELEMETRY_BASE_CAPACITY,
67+
baseTimer: process.env.TELEMETRY_BASE_TIMER,
68+
maxDelayMs: process.env.TELEMETRY_MAX_DELAY,
69+
backoffFactor: process.env.TELEMETRY_BACKOFF_FACTOR,
70+
jitterFactor: process.env.TELEMETRY_JITTER_FACTOR
71+
},
72+
telemetryApi: {
73+
baseUrl: process.env.TELEMETRY_API_BASE_URL,
74+
baseEndpoint: process.env.TELEMETRY_API_ENDPOINT,
75+
version: process.env.TELEMETRY_API_VERSION
76+
}
77+
});
78+
79+
Object.entries(defaultConfig).forEach(([parent, configs]) => {
80+
if (parent in envConfig) {
81+
Object.entries(configs).forEach(([key, _]) => {
82+
if (envConfig[parent]?.[key]) {
83+
defaultConfig[parent][key] = envConfig[parent][key];
84+
}
5585
});
56-
console.log("[watch] build finished");
57-
} else if(args.includes("--artifactory-check")){
58-
checkAritfactoryUrl();
59-
} else {
60-
// Build source code
61-
await build(scriptConfig);
62-
console.log("build complete");
6386
}
64-
} catch (err) {
65-
process.stderr.write(err.message);
66-
process.exit(1);
87+
});
88+
89+
fs.writeFileSync("telemetryConfig.json", JSON.stringify(defaultConfig, null, 4));
90+
console.log("Telemetry config generated successfully.");
91+
}
92+
93+
(async () => {
94+
const args = process.argv.slice(2);
95+
try {
96+
if (args.includes("--watch")) {
97+
// Build and watch source code
98+
console.log("[watch] build started");
99+
await build({
100+
...scriptConfig,
101+
...watchConfig,
102+
});
103+
console.log("[watch] build finished");
104+
} else if (args.includes("--artifactory-check")) {
105+
checkAritfactoryUrl();
106+
} else {
107+
// Build source code
108+
createTelemetryConfig();
109+
await build(scriptConfig);
110+
console.log("build complete");
67111
}
68-
})();
112+
} catch (err) {
113+
process.stderr.write(err.message);
114+
process.exit(1);
115+
}
116+
})();

vscode/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,4 +804,4 @@
804804
"jsonc-parser": "3.3.1",
805805
"vscode-languageclient": "^9.0.1"
806806
}
807-
}
807+
}

vscode/src/logger.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export class ExtensionLogger {
2929

3030
constructor(channelName: string) {
3131
this.outChannel = window.createOutputChannel(channelName);
32-
this.isDebugLogEnabled = process.env['oracle.oracle-java.enable.debug-logs'] === "true";
32+
this.isDebugLogEnabled = process.env['oracle_oracleJava_enable_debugLogs'] === "true";
3333
}
3434

3535
public log(message: string): void {

vscode/src/lsp/nbLanguageClient.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ export class NbLanguageClient extends LanguageClient {
6262
'showHtmlPageSupport': true,
6363
'wantsJavaSupport': true,
6464
'wantsGroovySupport': false,
65-
'wantsTelemetryEnabled': Telemetry.isTelemetryFeatureAvailable,
65+
'wantsTelemetryEnabled': Telemetry.getIsTelemetryFeatureAvailable(),
6666
'commandPrefix': extConstants.COMMAND_PREFIX,
6767
'configurationPrefix': `${extConstants.COMMAND_PREFIX}.`,
6868
'altConfigurationPrefix': `${extConstants.COMMAND_PREFIX}.`

vscode/src/telemetry/config.ts

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
you may not use this file except in compliance with the License.
66
You may obtain a copy of the License at
77
8-
https://www.apache.org/licenses/LICENSE-2.0
8+
https://www.apache.org/licenses/LICENSE-2.0
99
1010
Unless required by applicable law or agreed to in writing, software
1111
distributed under the License is distributed on an "AS IS" BASIS,
@@ -14,18 +14,58 @@
1414
limitations under the License.
1515
*/
1616
import { RetryConfig, TelemetryApi } from "./types";
17+
import * as path from 'path';
18+
import * as fs from 'fs';
19+
import { LOGGER } from "../logger";
1720

18-
export const TELEMETRY_RETRY_CONFIG: RetryConfig = Object.freeze({
19-
maxRetries: 6,
20-
baseCapacity: 256,
21-
baseTimer: 5 * 1000,
22-
maxDelayMs: 100 * 1000,
23-
backoffFactor: 2,
24-
jitterFactor: 0.25
25-
});
26-
27-
export const TELEMETRY_API: TelemetryApi = Object.freeze({
28-
baseUrl: null,
29-
baseEndpoint: "/vscode/java/sendTelemetry",
30-
version: "/v1"
31-
});
21+
export class TelemetryConfiguration {
22+
private static CONFIG_FILE_PATH = path.resolve(__dirname, "..", "..", "telemetryConfig.json");
23+
24+
private static instance: TelemetryConfiguration;
25+
private retryConfig!: RetryConfig;
26+
private apiConfig!: TelemetryApi;
27+
28+
public constructor() {
29+
this.initialize();
30+
}
31+
32+
public static getInstance(): TelemetryConfiguration {
33+
if (!TelemetryConfiguration.instance) {
34+
TelemetryConfiguration.instance = new TelemetryConfiguration();
35+
}
36+
return TelemetryConfiguration.instance;
37+
}
38+
39+
private initialize(): void {
40+
try {
41+
const config = JSON.parse(fs.readFileSync(TelemetryConfiguration.CONFIG_FILE_PATH).toString());
42+
43+
this.retryConfig = Object.freeze({
44+
maxRetries: config.telemetryRetryConfig.maxRetries,
45+
baseCapacity: config.telemetryRetryConfig.baseCapacity,
46+
baseTimer: config.telemetryRetryConfig.baseTimer,
47+
maxDelayMs: config.telemetryRetryConfig.maxDelayMs,
48+
backoffFactor: config.telemetryRetryConfig.backoffFactor,
49+
jitterFactor: config.telemetryRetryConfig.jitterFactor
50+
});
51+
52+
this.apiConfig = Object.freeze({
53+
baseUrl: config.telemetryApi.baseUrl,
54+
baseEndpoint: config.telemetryApi.baseEndpoint,
55+
version: config.telemetryApi.version
56+
});
57+
} catch (error: any) {
58+
LOGGER.error("Error occurred while setting up telemetry config");
59+
LOGGER.error(error.message);
60+
}
61+
}
62+
63+
public getRetryConfig(): Readonly<RetryConfig> {
64+
return this.retryConfig;
65+
}
66+
67+
public getApiConfig(): Readonly<TelemetryApi> {
68+
return this.apiConfig;
69+
}
70+
71+
}

vscode/src/telemetry/impl/postTelemetry.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@
1313
See the License for the specific language governing permissions and
1414
limitations under the License.
1515
*/
16+
import { integer } from "vscode-languageclient";
1617
import { LOGGER } from "../../logger";
17-
import { TELEMETRY_API } from "../config";
18+
import { TelemetryConfiguration } from "../config";
1819
import { BaseEvent } from "../events/baseEvent";
1920

2021
interface TelemetryEventResponse {
@@ -28,9 +29,11 @@ export interface TelemetryPostResponse {
2829
};
2930

3031
export class PostTelemetry {
32+
private TELEMETRY_API = TelemetryConfiguration.getInstance().getApiConfig();
33+
3134
public post = async (events: BaseEvent<any>[]): Promise<TelemetryPostResponse> => {
3235
try {
33-
if (TELEMETRY_API.baseUrl == null) {
36+
if (this.TELEMETRY_API.baseUrl == null) {
3437
return {
3538
success: [],
3639
failures: []
@@ -47,7 +50,7 @@ export class PostTelemetry {
4750
};
4851

4952
private addBaseEndpoint = (endpoint: string) => {
50-
return `${TELEMETRY_API.baseUrl}${TELEMETRY_API.baseEndpoint}${TELEMETRY_API.version}${endpoint}`;
53+
return `${this.TELEMETRY_API.baseUrl}${this.TELEMETRY_API.baseEndpoint}${this.TELEMETRY_API.version}${endpoint}`;
5154
}
5255

5356
private postEvent = (event: BaseEvent<any>): Promise<Response> => {
@@ -57,25 +60,34 @@ export class PostTelemetry {
5760

5861
return fetch(serverEndpoint, {
5962
method: "POST",
60-
body: JSON.stringify(payload)
63+
body: JSON.stringify(payload),
64+
redirect: "follow",
65+
headers: {
66+
"Content-Type": "application/json",
67+
"Accept": "application/json"
68+
}
6169
});
6270
}
6371

6472
private parseTelemetryResponse = (events: BaseEvent<any>[], eventResponses: PromiseSettledResult<Response>[]): TelemetryPostResponse => {
6573
let success: TelemetryEventResponse[] = [], failures: TelemetryEventResponse[] = [];
6674
eventResponses.forEach((eventResponse, index) => {
6775
const event = events[index];
76+
let list: TelemetryEventResponse[] = success;
77+
let statusCode: integer = 0;
6878
if (eventResponse.status === "rejected") {
69-
failures.push({
70-
event,
71-
statusCode: -1
72-
});
79+
list = failures;
80+
statusCode = -1;
7381
} else {
74-
success.push({
75-
statusCode: eventResponse.value.status,
76-
event
77-
});
82+
statusCode = eventResponse.value.status;
83+
if (statusCode <= 0 || statusCode >= 400) {
84+
list = failures;
85+
}
7886
}
87+
list.push({
88+
event,
89+
statusCode
90+
});
7991
});
8092

8193
return {

vscode/src/telemetry/impl/telemetryRetry.ts

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@
1515
*/
1616

1717
import { LOGGER } from "../../logger";
18-
import { TELEMETRY_RETRY_CONFIG } from "../config";
18+
import { TelemetryConfiguration } from "../config";
1919
import { BaseEvent } from "../events/baseEvent";
2020
import { TelemetryPostResponse } from "./postTelemetry";
2121

2222
export class TelemetryRetry {
23-
private timePeriod: number = TELEMETRY_RETRY_CONFIG.baseTimer;
23+
private TELEMETRY_RETRY_CONFIG = TelemetryConfiguration.getInstance().getRetryConfig();
24+
private timePeriod: number = this.TELEMETRY_RETRY_CONFIG?.baseTimer;
2425
private timeout?: NodeJS.Timeout | null;
2526
private numOfAttemptsWhenTimerHits: number = 1;
26-
private queueCapacity: number = TELEMETRY_RETRY_CONFIG.baseCapacity;
27+
private queueCapacity: number = this.TELEMETRY_RETRY_CONFIG?.baseCapacity;
2728
private numOfAttemptsWhenQueueIsFull: number = 1;
2829
private triggeredDueToQueueOverflow: boolean = false;
2930
private callbackHandler?: () => {};
@@ -45,12 +46,12 @@ export class TelemetryRetry {
4546

4647
private resetTimerParameters = () => {
4748
this.numOfAttemptsWhenTimerHits = 1;
48-
this.timePeriod = TELEMETRY_RETRY_CONFIG.baseTimer;
49+
this.timePeriod = this.TELEMETRY_RETRY_CONFIG.baseTimer;
4950
this.clearTimer();
5051
}
5152

5253
private increaseTimePeriod = (): void => {
53-
if (this.numOfAttemptsWhenTimerHits <= TELEMETRY_RETRY_CONFIG.maxRetries) {
54+
if (this.numOfAttemptsWhenTimerHits <= this.TELEMETRY_RETRY_CONFIG.maxRetries) {
5455
this.timePeriod = this.calculateDelay();
5556
this.numOfAttemptsWhenTimerHits++;
5657
return;
@@ -66,26 +67,26 @@ export class TelemetryRetry {
6667
}
6768

6869
private calculateDelay = (): number => {
69-
const baseDelay = TELEMETRY_RETRY_CONFIG.baseTimer *
70-
Math.pow(TELEMETRY_RETRY_CONFIG.backoffFactor, this.numOfAttemptsWhenTimerHits);
70+
const baseDelay = this.TELEMETRY_RETRY_CONFIG.baseTimer *
71+
Math.pow(this.TELEMETRY_RETRY_CONFIG.backoffFactor, this.numOfAttemptsWhenTimerHits);
7172

72-
const cappedDelay = Math.min(baseDelay, TELEMETRY_RETRY_CONFIG.maxDelayMs);
73+
const cappedDelay = Math.min(baseDelay, this.TELEMETRY_RETRY_CONFIG.maxDelayMs);
7374

74-
const jitterMultiplier = 1 + (Math.random() * 2 - 1) * TELEMETRY_RETRY_CONFIG.jitterFactor;
75+
const jitterMultiplier = 1 + (Math.random() * 2 - 1) * this.TELEMETRY_RETRY_CONFIG.jitterFactor;
7576

7677
return Math.floor(cappedDelay * jitterMultiplier);
7778
};
7879

7980
private increaseQueueCapacity = (): void => {
80-
if (this.numOfAttemptsWhenQueueIsFull < TELEMETRY_RETRY_CONFIG.maxRetries) {
81-
this.queueCapacity = TELEMETRY_RETRY_CONFIG.baseCapacity *
82-
Math.pow(TELEMETRY_RETRY_CONFIG.backoffFactor, this.numOfAttemptsWhenQueueIsFull);
81+
if (this.numOfAttemptsWhenQueueIsFull < this.TELEMETRY_RETRY_CONFIG.maxRetries) {
82+
this.queueCapacity = this.TELEMETRY_RETRY_CONFIG.baseCapacity *
83+
Math.pow(this.TELEMETRY_RETRY_CONFIG.backoffFactor, this.numOfAttemptsWhenQueueIsFull);
8384
}
8485
throw new Error("Number of retries exceeded");
8586
}
8687

8788
private resetQueueCapacity = (): void => {
88-
this.queueCapacity = TELEMETRY_RETRY_CONFIG.baseCapacity;
89+
this.queueCapacity = this.TELEMETRY_RETRY_CONFIG.baseCapacity;
8990
this.numOfAttemptsWhenQueueIsFull = 1;
9091
this.triggeredDueToQueueOverflow = false;
9192
}

0 commit comments

Comments
 (0)