Skip to content

Commit bfa31db

Browse files
authored
Merge pull request #1784 from rosahbruno/1856730-persist-browser-debug-values
2 parents 321bcd7 + dc206b0 commit bfa31db

File tree

3 files changed

+98
-5
lines changed

3 files changed

+98
-5
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
[Full changelog](https://github.com/mozilla/glean.js/compare/v2.0.3...main)
44

55
* [#1772](https://github.com/mozilla/glean.js/pull/1772): Fix bug where `window.Glean` functions were getting set on non-browser properties.
6+
* [#1784](https://github.com/mozilla/glean.js/pull/1784): Store `window.Glean` debugging values in `sessionStorage`. This will set debug options on page init while the current session is still active.
67

78
# v2.0.3 (2023-09-27)
89

glean/src/core/glean/sync.ts

Lines changed: 80 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import type PlatformSync from "../../platform/sync.js";
88
import { CLIENT_INFO_STORAGE, KNOWN_CLIENT_ID } from "../constants.js";
99
import { Configuration } from "../config.js";
1010
import PingUploadManager from "../upload/manager/sync.js";
11-
import { isBoolean, isString, sanitizeApplicationId } from "../utils.js";
11+
import { extractBooleanFromString, isBoolean, isString, isUndefined, sanitizeApplicationId } from "../utils.js";
1212
import { CoreMetricsSync } from "../internal_metrics/sync.js";
1313
import { EventsDatabaseSync } from "../metrics/events_database/sync.js";
1414
import { DatetimeMetric } from "../metrics/types/datetime.js";
@@ -23,6 +23,44 @@ import PingsDatabaseSync from "../pings/database/sync.js";
2323

2424
const LOG_TAG = "core.Glean";
2525

26+
enum DebugOption {
27+
DebugTag = "DebugTag",
28+
SourceTags = "SourceTags",
29+
LogPings = "LogPings"
30+
}
31+
type DebugOptionValue = keyof typeof DebugOption;
32+
33+
/**
34+
* Set the value of a debug option in SessionStorage.
35+
*
36+
* @param option The debug option key to set.
37+
* @param value The value of the debug option.
38+
*/
39+
const setDebugOptionInSessionStorage = (option: DebugOptionValue, value: boolean | string | string[]) => {
40+
const key = `Glean.${option.toString()}`;
41+
42+
switch(option) {
43+
case DebugOption.DebugTag:
44+
sessionStorage.setItem(key, value as string);
45+
break;
46+
case DebugOption.LogPings:
47+
sessionStorage.setItem(key, (value as boolean).toString());
48+
break;
49+
case DebugOption.SourceTags:
50+
sessionStorage.setItem(key, (value as string[]).join(","));
51+
}
52+
};
53+
54+
/**
55+
* Get a debug option value from SessionStorage using the key.
56+
*
57+
* @param option The debug option key to fetch the value of.
58+
* @returns The stringified value.
59+
*/
60+
const getDebugOptionFromSessionStorage = (option: DebugOptionValue): string | undefined => {
61+
return sessionStorage.getItem(`Glean.${option.toString()}`) || undefined;
62+
};
63+
2664
namespace Glean {
2765
// An instance of the ping uploader.
2866
export let pingUploader: PingUploadManager;
@@ -140,6 +178,31 @@ namespace Glean {
140178
Context.uploadEnabled = false;
141179
}
142180

181+
/**
182+
* Fetch debug options from SessionStorage and set the Glean preInit debug options.
183+
*/
184+
function setDebugOptionsFromSessionStorage() {
185+
// If we cannot access browser APIs, we do nothing.
186+
if (isUndefined(window) || isUndefined(window.sessionStorage)) {
187+
return;
188+
}
189+
190+
const logPings = getDebugOptionFromSessionStorage(DebugOption.LogPings);
191+
if (!isUndefined(logPings)) {
192+
preInitLogPings = extractBooleanFromString(logPings);
193+
}
194+
195+
const debugViewTag = getDebugOptionFromSessionStorage(DebugOption.DebugTag);
196+
if (!isUndefined(debugViewTag)) {
197+
preInitDebugViewTag = debugViewTag;
198+
}
199+
200+
const sourceTags = getDebugOptionFromSessionStorage(DebugOption.SourceTags);
201+
if (!isUndefined(sourceTags)) {
202+
preInitSourceTags = sourceTags.split(",");
203+
}
204+
}
205+
143206
/**
144207
* Initialize This method should only be called once, subsequent calls will be no-op.
145208
*
@@ -207,6 +270,9 @@ namespace Glean {
207270
const correctConfig = new Configuration(config);
208271
Context.config = correctConfig;
209272

273+
// Pre-set debug options for Glean from browser SessionStorage values.
274+
setDebugOptionsFromSessionStorage();
275+
210276
if (preInitLogPings) Context.config.logPings = preInitLogPings;
211277
if (preInitDebugViewTag) Context.config.debugViewTag = preInitDebugViewTag;
212278
if (preInitSourceTags) Context.config.sourceTags = preInitSourceTags;
@@ -446,11 +512,20 @@ declare global {
446512
}
447513

448514
// Only set `Glean` values whenever running inside of a browser.
449-
if (typeof window !== "undefined") {
515+
if (!isUndefined(window) && !isUndefined(window.sessionStorage)) {
450516
window.Glean = {
451-
setLogPings: Glean.setLogPings,
452-
setDebugViewTag: Glean.setDebugViewTag,
453-
setSourceTags: Glean.setSourceTags
517+
setLogPings: (flag: boolean) => {
518+
setDebugOptionInSessionStorage(DebugOption.LogPings, flag);
519+
Glean.setLogPings(flag);
520+
},
521+
setDebugViewTag: (value: string) => {
522+
setDebugOptionInSessionStorage(DebugOption.DebugTag, value);
523+
Glean.setDebugViewTag(value);
524+
},
525+
setSourceTags: (value: string[]) => {
526+
setDebugOptionInSessionStorage(DebugOption.SourceTags, value);
527+
Glean.setSourceTags(value);
528+
}
454529
};
455530
}
456531

glean/src/core/utils.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,23 @@ export function isInteger(v: unknown): v is number {
122122
return isNumber(v) && Number.isInteger(v);
123123
}
124124

125+
/**
126+
* Convert a boolean stringified value to a proper boolean.
127+
*
128+
* @param v The value to convert.
129+
* @returns A boolean representing the string or undefined if the string was not a boolean value.
130+
*/
131+
export function extractBooleanFromString(v: string): boolean | undefined {
132+
if (v.toLowerCase() === "true") {
133+
return true;
134+
} else if (v.toLowerCase() === "false") {
135+
return false;
136+
}
137+
138+
// The string is not a boolean value, so we do not return a boolean.
139+
return undefined;
140+
}
141+
125142
/**
126143
* Generates a pipeline-friendly string
127144
* that replaces non alphanumeric characters with dashes.

0 commit comments

Comments
 (0)