Skip to content

Commit

Permalink
Merge pull request #1784 from rosahbruno/1856730-persist-browser-debu…
Browse files Browse the repository at this point in the history
…g-values
  • Loading branch information
rosahbruno authored Oct 6, 2023
2 parents 321bcd7 + dc206b0 commit bfa31db
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
[Full changelog](https://github.com/mozilla/glean.js/compare/v2.0.3...main)

* [#1772](https://github.com/mozilla/glean.js/pull/1772): Fix bug where `window.Glean` functions were getting set on non-browser properties.
* [#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.

# v2.0.3 (2023-09-27)

Expand Down
85 changes: 80 additions & 5 deletions glean/src/core/glean/sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type PlatformSync from "../../platform/sync.js";
import { CLIENT_INFO_STORAGE, KNOWN_CLIENT_ID } from "../constants.js";
import { Configuration } from "../config.js";
import PingUploadManager from "../upload/manager/sync.js";
import { isBoolean, isString, sanitizeApplicationId } from "../utils.js";
import { extractBooleanFromString, isBoolean, isString, isUndefined, sanitizeApplicationId } from "../utils.js";
import { CoreMetricsSync } from "../internal_metrics/sync.js";
import { EventsDatabaseSync } from "../metrics/events_database/sync.js";
import { DatetimeMetric } from "../metrics/types/datetime.js";
Expand All @@ -23,6 +23,44 @@ import PingsDatabaseSync from "../pings/database/sync.js";

const LOG_TAG = "core.Glean";

enum DebugOption {
DebugTag = "DebugTag",
SourceTags = "SourceTags",
LogPings = "LogPings"
}
type DebugOptionValue = keyof typeof DebugOption;

/**
* Set the value of a debug option in SessionStorage.
*
* @param option The debug option key to set.
* @param value The value of the debug option.
*/
const setDebugOptionInSessionStorage = (option: DebugOptionValue, value: boolean | string | string[]) => {
const key = `Glean.${option.toString()}`;

switch(option) {
case DebugOption.DebugTag:
sessionStorage.setItem(key, value as string);
break;
case DebugOption.LogPings:
sessionStorage.setItem(key, (value as boolean).toString());
break;
case DebugOption.SourceTags:
sessionStorage.setItem(key, (value as string[]).join(","));
}
};

/**
* Get a debug option value from SessionStorage using the key.
*
* @param option The debug option key to fetch the value of.
* @returns The stringified value.
*/
const getDebugOptionFromSessionStorage = (option: DebugOptionValue): string | undefined => {
return sessionStorage.getItem(`Glean.${option.toString()}`) || undefined;
};

namespace Glean {
// An instance of the ping uploader.
export let pingUploader: PingUploadManager;
Expand Down Expand Up @@ -140,6 +178,31 @@ namespace Glean {
Context.uploadEnabled = false;
}

/**
* Fetch debug options from SessionStorage and set the Glean preInit debug options.
*/
function setDebugOptionsFromSessionStorage() {
// If we cannot access browser APIs, we do nothing.
if (isUndefined(window) || isUndefined(window.sessionStorage)) {
return;
}

const logPings = getDebugOptionFromSessionStorage(DebugOption.LogPings);
if (!isUndefined(logPings)) {
preInitLogPings = extractBooleanFromString(logPings);
}

const debugViewTag = getDebugOptionFromSessionStorage(DebugOption.DebugTag);
if (!isUndefined(debugViewTag)) {
preInitDebugViewTag = debugViewTag;
}

const sourceTags = getDebugOptionFromSessionStorage(DebugOption.SourceTags);
if (!isUndefined(sourceTags)) {
preInitSourceTags = sourceTags.split(",");
}
}

/**
* Initialize This method should only be called once, subsequent calls will be no-op.
*
Expand Down Expand Up @@ -207,6 +270,9 @@ namespace Glean {
const correctConfig = new Configuration(config);
Context.config = correctConfig;

// Pre-set debug options for Glean from browser SessionStorage values.
setDebugOptionsFromSessionStorage();

if (preInitLogPings) Context.config.logPings = preInitLogPings;
if (preInitDebugViewTag) Context.config.debugViewTag = preInitDebugViewTag;
if (preInitSourceTags) Context.config.sourceTags = preInitSourceTags;
Expand Down Expand Up @@ -446,11 +512,20 @@ declare global {
}

// Only set `Glean` values whenever running inside of a browser.
if (typeof window !== "undefined") {
if (!isUndefined(window) && !isUndefined(window.sessionStorage)) {
window.Glean = {
setLogPings: Glean.setLogPings,
setDebugViewTag: Glean.setDebugViewTag,
setSourceTags: Glean.setSourceTags
setLogPings: (flag: boolean) => {
setDebugOptionInSessionStorage(DebugOption.LogPings, flag);
Glean.setLogPings(flag);
},
setDebugViewTag: (value: string) => {
setDebugOptionInSessionStorage(DebugOption.DebugTag, value);
Glean.setDebugViewTag(value);
},
setSourceTags: (value: string[]) => {
setDebugOptionInSessionStorage(DebugOption.SourceTags, value);
Glean.setSourceTags(value);
}
};
}

Expand Down
17 changes: 17 additions & 0 deletions glean/src/core/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ export function isInteger(v: unknown): v is number {
return isNumber(v) && Number.isInteger(v);
}

/**
* Convert a boolean stringified value to a proper boolean.
*
* @param v The value to convert.
* @returns A boolean representing the string or undefined if the string was not a boolean value.
*/
export function extractBooleanFromString(v: string): boolean | undefined {
if (v.toLowerCase() === "true") {
return true;
} else if (v.toLowerCase() === "false") {
return false;
}

// The string is not a boolean value, so we do not return a boolean.
return undefined;
}

/**
* Generates a pipeline-friendly string
* that replaces non alphanumeric characters with dashes.
Expand Down

0 comments on commit bfa31db

Please sign in to comment.