Skip to content
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

* [#173](https://github.com/mozilla/glean.js/pull/173): Drop Node.js support from webext entry points
* [#155](https://github.com/mozilla/glean.js/pull/155): Allow to define custom uploaders in the configuration.
* [#184](https://github.com/mozilla/glean.js/pull/184): Correctly report `appBuild` and `appDisplayVersion` if provided by the user.

# v0.7.0 (2021-03-26)

Expand Down
8 changes: 8 additions & 0 deletions glean/.madgerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"tsConfig": "tsConfig/base.json",
"detectiveOptions": {
"ts": {
"skipTypeImports": true
}
}
}
2 changes: 1 addition & 1 deletion glean/src/core/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Plugin from "../../plugins/index.js";
import type Plugin from "../../plugins/index.js";

import { PingPayload } from "../pings/ping_payload.js";
import { JSONObject } from "../utils.js";
Expand Down
26 changes: 11 additions & 15 deletions glean/src/core/glean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@ import PingsDatabase from "./pings/database.js";
import PingUploader from "./upload/index.js";
import { isUndefined, sanitizeApplicationId } from "./utils.js";
import { CoreMetrics } from "./internal_metrics.js";
import { Lifetime } from "./metrics/index.js";
import EventsDatabase from "./metrics/events_database.js";
import UUIDMetricType from "./metrics/types/uuid.js";
import DatetimeMetricType, { DatetimeMetric } from "./metrics/types/datetime.js";
import DatetimeMetricType from "./metrics/types/datetime.js";
import { DatetimeMetric } from "./metrics/types/datetime_metric.js";
import Dispatcher from "./dispatcher.js";
import CorePings from "./internal_pings.js";
import { registerPluginToEvent, testResetEvents } from "./events/utils.js";

import Platform from "../platform/index.js";
import TestPlatform from "../platform/test/index.js";
import { DebugOptions } from "./debug_options.js";
import { Lifetime } from "./metrics/lifetime.js";

class Glean {
// The Glean singleton.
Expand Down Expand Up @@ -48,7 +49,7 @@ class Glean {
// Whether or not to record metrics.
private _uploadEnabled?: boolean;
// The Glean configuration object.
private _config?: Configuration;
private _config!: Configuration;
// The metrics and pings databases.
private _db?: {
metrics: MetricsDatabase,
Expand Down Expand Up @@ -81,7 +82,7 @@ class Glean {
return Glean.instance._pingUploader;
}

private static get coreMetrics(): CoreMetrics {
static get coreMetrics(): CoreMetrics {
return Glean.instance._coreMetrics;
}

Expand All @@ -106,7 +107,7 @@ class Glean {
*/
private static async onUploadEnabled(): Promise<void> {
Glean.uploadEnabled = true;
await Glean.coreMetrics.initialize();
await Glean.coreMetrics.initialize(Glean.instance._config, Glean.platform, Glean.metricsDatabase);
}

/**
Expand Down Expand Up @@ -424,8 +425,7 @@ class Glean {
*/
static setLogPings(flag: boolean): void {
Glean.dispatcher.launch(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Glean.instance._config!.debug.logPings = flag;
Glean.instance._config.debug.logPings = flag;

// The dispatcher requires that dispatched functions return promises.
return Promise.resolve();
Expand All @@ -450,8 +450,7 @@ class Glean {
}

Glean.dispatcher.launch(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Glean.instance._config!.debug.debugViewTag = value;
Glean.instance._config.debug.debugViewTag = value;

// The dispatcher requires that dispatched functions return promises.
return Promise.resolve();
Expand All @@ -465,8 +464,7 @@ class Glean {
*/
static unsetDebugViewTag(): void {
Glean.dispatcher.launch(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
delete Glean.instance._config!.debug.debugViewTag;
delete Glean.instance._config.debug.debugViewTag;
return Promise.resolve();
});
}
Expand All @@ -490,8 +488,7 @@ class Glean {
}

Glean.dispatcher.launch(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Glean.instance._config!.debug.sourceTags = value;
Glean.instance._config.debug.sourceTags = value;

// The dispatcher requires that dispatched functions return promises.
return Promise.resolve();
Expand All @@ -505,8 +502,7 @@ class Glean {
*/
static unsetSourceTags(): void {
Glean.dispatcher.launch(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
delete Glean.instance._config!.debug.sourceTags;
delete Glean.instance._config.debug.sourceTags;
return Promise.resolve();
});
}
Expand Down
64 changes: 21 additions & 43 deletions glean/src/core/internal_metrics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ import DatetimeMetricType from "./metrics/types/datetime.js";
import StringMetricType from "./metrics/types/string.js";
import { createMetric } from "./metrics/utils.js";
import TimeUnit from "./metrics/time_unit.js";
import { Lifetime } from "./metrics/index.js";
import { generateUUIDv4 } from "./utils.js";
import Glean from "./glean.js";
import { ConfigurationInterface } from "./config.js";
import Platform from "../platform/index.js";
import MetricsDatabase from "./metrics/database.js";
import { Lifetime } from "./metrics/lifetime.js";

/**
* Glean internal metrics.
Expand Down Expand Up @@ -95,24 +97,26 @@ export class CoreMetrics {
});
}

async initialize(appBuild?: string, appDisplayVersion?: string): Promise<void> {
await this.initializeClientId();
await this.initializeFirstRunDate();
await this.initializeOs();
await this.initializeOsVersion();
await this.initializeArchitecture();
await this.initializeLocale();
await StringMetricType._private_setUndispatched(this.appBuild, appBuild || "Unknown");
await StringMetricType._private_setUndispatched(this.appDisplayVersion, appDisplayVersion || "Unknown");
async initialize(config: ConfigurationInterface, platform: Platform, metricsDatabase: MetricsDatabase): Promise<void> {
await this.initializeClientId(metricsDatabase);
await this.initializeFirstRunDate(metricsDatabase);
await StringMetricType._private_setUndispatched(this.os, await platform.info.os());
await StringMetricType._private_setUndispatched(this.osVersion, await platform.info.osVersion());
await StringMetricType._private_setUndispatched(this.architecture, await platform.info.arch());
await StringMetricType._private_setUndispatched(this.locale, await platform.info.locale());
await StringMetricType._private_setUndispatched(this.appBuild, config.appBuild || "Unknown");
await StringMetricType._private_setUndispatched(this.appDisplayVersion, config.appDisplayVersion || "Unknown");
}

/**
* Generates and sets the client_id if it is not set,
* or if the current value is currepted.
*
* @param metricsDatabase The metrics database.
*/
private async initializeClientId(): Promise<void> {
private async initializeClientId(metricsDatabase: MetricsDatabase): Promise<void> {
let needNewClientId = false;
const clientIdData = await Glean.metricsDatabase.getMetric(CLIENT_INFO_STORAGE, this.clientId);
const clientIdData = await metricsDatabase.getMetric(CLIENT_INFO_STORAGE, this.clientId);
if (clientIdData) {
try {
const currentClientId = createMetric("uuid", clientIdData);
Expand All @@ -134,9 +138,11 @@ export class CoreMetrics {

/**
* Generates and sets the first_run_date if it is not set.
*
* @param metricsDatabase The metrics database.
*/
private async initializeFirstRunDate(): Promise<void> {
const firstRunDate = await Glean.metricsDatabase.getMetric(
private async initializeFirstRunDate(metricsDatabase: MetricsDatabase): Promise<void> {
const firstRunDate = await metricsDatabase.getMetric(
CLIENT_INFO_STORAGE,
this.firstRunDate
);
Expand All @@ -145,32 +151,4 @@ export class CoreMetrics {
await DatetimeMetricType._private_setUndispatched(this.firstRunDate);
}
}

/**
* Gets and sets the os.
*/
async initializeOs(): Promise<void> {
await StringMetricType._private_setUndispatched(this.os, await Glean.platform.info.os());
}

/**
* Gets and sets the os.
*/
async initializeOsVersion(): Promise<void> {
await StringMetricType._private_setUndispatched(this.osVersion, await Glean.platform.info.osVersion());
}

/**
* Gets and sets the system architecture.
*/
async initializeArchitecture(): Promise<void> {
await StringMetricType._private_setUndispatched(this.architecture, await Glean.platform.info.arch());
}

/**
* Gets and sets the system / browser locale.
*/
async initializeLocale(): Promise<void> {
await StringMetricType._private_setUndispatched(this.locale, await Glean.platform.info.locale());
}
}
3 changes: 2 additions & 1 deletion glean/src/core/metrics/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
// * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Store from "../storage/index.js";
import { MetricType, Lifetime } from "./index.js";
import { MetricType } from "./index.js";
import { Metric } from "./metric.js";
import { createMetric, validateMetricInternalRepresentation } from "./utils.js";
import { isObject, isUndefined, JSONObject, JSONValue } from "../utils.js";
import { StorageBuilder } from "../../platform/index.js";
import { Metrics } from "./metrics_interface";
import { Lifetime } from "./lifetime.js";

/**
* Verifies if a given value is a valid Metrics object.
Expand Down
2 changes: 1 addition & 1 deletion glean/src/core/metrics/events_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

import Store from "../storage/index.js";
import { isUndefined, JSONArray, JSONObject, JSONValue } from "../utils.js";
import EventMetricType from "./types/event.js";
import type EventMetricType from "./types/event.js";
import { StorageBuilder } from "../../platform/index.js";

// An helper type for the 'extra' map.
Expand Down
21 changes: 6 additions & 15 deletions glean/src/core/metrics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { isUndefined, JSONValue } from "../utils.js";
import Glean from "../glean.js";
import LabeledMetricType from "./types/labeled.js";
import { Metric } from "./metric.js";

/**
* An enum representing the possible metric lifetimes.
*/
export const enum Lifetime {
// The metric is reset with each sent ping
Ping = "ping",
// The metric is reset on application restart
Application = "application",
// The metric is reset with each user profile
User = "user",
}
import { Lifetime } from "./lifetime.js";

/**
* The common set of data shared across all different metric types.
Expand Down Expand Up @@ -102,10 +90,13 @@ export abstract class MetricType implements CommonMetricData {
/**
* Verify whether or not this metric instance should be recorded.
*
* @param uploadEnabled Whether or not global upload is enabled or
* disabled.
*
* @returns Whether or not this metric instance should be recorded.
*/
shouldRecord(): boolean {
return (Glean.isUploadEnabled() && !this.disabled);
shouldRecord(uploadEnabled: boolean): boolean {
return (uploadEnabled && !this.disabled);
}
}

Expand Down
15 changes: 15 additions & 0 deletions glean/src/core/metrics/lifetime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/**
* An enum representing the possible metric lifetimes.
*/
export const enum Lifetime {
// The metric is reset with each sent ping
Ping = "ping",
// The metric is reset on application restart
Application = "application",
// The metric is reset with each user profile
User = "user",
}
18 changes: 2 additions & 16 deletions glean/src/core/metrics/types/boolean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,8 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import { isBoolean } from "../../utils.js";
import Glean from "../../glean.js";

export class BooleanMetric extends Metric<boolean, boolean> {
constructor(v: unknown) {
super(v);
}

validate(v: unknown): v is boolean {
return isBoolean(v);
}
payload(): boolean {
return this._inner;
}
}
import { BooleanMetric } from "./boolean_metric.js";

/**
* A boolean metric.
Expand All @@ -37,7 +23,7 @@ class BooleanMetricType extends MetricType {
*/
set(value: boolean): void {
Glean.dispatcher.launch(async () => {
if (!this.shouldRecord()) {
if (!this.shouldRecord(Glean.isUploadEnabled())) {
return;
}

Expand Down
19 changes: 19 additions & 0 deletions glean/src/core/metrics/types/boolean_metric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { Metric } from "../metric.js";
import { isBoolean } from "../../utils.js";

export class BooleanMetric extends Metric<boolean, boolean> {
constructor(v: unknown) {
super(v);
}

validate(v: unknown): v is boolean {
return isBoolean(v);
}
payload(): boolean {
return this._inner;
}
}
28 changes: 3 additions & 25 deletions glean/src/core/metrics/types/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import { isNumber, isUndefined, JSONValue } from "../../utils.js";
import { isUndefined, JSONValue } from "../../utils.js";
import Glean from "../../glean.js";

export class CounterMetric extends Metric<number, number> {
constructor(v: unknown) {
super(v);
}

validate(v: unknown): v is number {
if (!isNumber(v)) {
return false;
}

if (v <= 0) {
return false;
}

return true;
}

payload(): number {
return this._inner;
}
}
import { CounterMetric } from "./counter_metric.js";

/**
* A counter metric.
Expand All @@ -53,7 +31,7 @@ class CounterMetricType extends MetricType {
* @param amount The amount we want to add.
*/
static async _private_addUndispatched(instance: CounterMetricType, amount?: number): Promise<void> {
if (!instance.shouldRecord()) {
if (!instance.shouldRecord(Glean.isUploadEnabled())) {
return;
}

Expand Down
Loading