Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion glean/src/core/events/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

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

import { PingPayload } from "../pings/database.js";
import { PingPayload } from "../pings/ping_payload.js";
import { JSONObject } from "../utils.js";

export class CoreEvent<
Expand Down
2 changes: 1 addition & 1 deletion glean/src/core/glean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class Glean {

Glean.instance._db = {
metrics: new MetricsDatabase(Glean.platform.Storage),
events: new EventsDatabase(),
events: new EventsDatabase(Glean.platform.Storage),
pings: new PingsDatabase(Glean.platform.Storage, Glean.pingUploader)
};

Expand Down
10 changes: 3 additions & 7 deletions glean/src/core/metrics/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,12 @@
// * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Store from "../storage/index.js";
import { MetricType, Lifetime, Metric } from "./index.js";
import { MetricType, Lifetime } 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";

export interface Metrics {
[aMetricType: string]: {
[aMetricIdentifier: string]: JSONValue
}
}
import { Metrics } from "./metrics_interface";

/**
* Verifies if a given value is a valid Metrics object.
Expand Down
12 changes: 3 additions & 9 deletions glean/src/core/metrics/events_database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,7 @@
import Store from "../storage/index.js";
import { isUndefined, JSONArray, JSONObject, JSONValue } from "../utils.js";
import EventMetricType from "./types/event.js";
import Glean from "../glean.js";

export interface Metrics {
[aMetricType: string]: {
[aMetricIdentifier: string]: JSONValue
}
}
import { StorageBuilder } from "../../platform/index.js";

// An helper type for the 'extra' map.
export type ExtraMap = Record<string, string>;
Expand Down Expand Up @@ -80,8 +74,8 @@ export class RecordedEvent {
class EventsDatabase {
private eventsStore: Store;

constructor() {
this.eventsStore = new Glean.platform.Storage("events");
constructor(storage: StorageBuilder) {
this.eventsStore = new storage("events");
}

/**
Expand Down
70 changes: 1 addition & 69 deletions glean/src/core/metrics/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,75 +5,7 @@
import { isUndefined, JSONValue } from "../utils.js";
import Glean from "../glean.js";
import LabeledMetricType from "./types/labeled.js";

/**
* The Metric class describes the shared behaviour amongst concrete metrics.
*
* A concrete metric will always have two possible representations:
*
* - `InternalRepresentation`
* - Is the format in which this metric will be stored in memory.
* - This format may contain extra metadata, in order to allow deserializing of this data for testing purposes.
* - `PayloadRepresentation`
* - Is the format in which this metric will be represented in the ping payload.
* - This format must be the exact same as described in [the Glean schema](https://github.com/mozilla-services/mozilla-pipeline-schemas/blob/master/schemas/glean/glean/glean.1.schema.json).
*/
export abstract class Metric<
InternalRepresentation extends JSONValue,
PayloadRepresentation extends JSONValue
> {
protected _inner: InternalRepresentation;

constructor(v: unknown) {
if (!this.validate(v)) {
throw new Error("Unable to create new Metric instance, values is in unexpected format.");
}

this._inner = v;
}

/**
* Gets this metrics value in its internal representation.
*
* @returns The metric value.
*/
get(): InternalRepresentation {
return this._inner;
}

/**
* Sets this metrics value.
*
* @param v The value to set, must be in the exact internal representation of this metric.
*
* @throws In case the metric is not in the expected format.
*/
set(v: unknown): void {
if (!this.validate(v)) {
console.error(`Unable to set metric to ${JSON.stringify(v)}. Value is in unexpected format. Ignoring.`);
return;
}

this._inner = v;
}

/**
* Validates that a given value is in the correct format for this metrics internal representation.
*
* @param v The value to verify.
*
* @returns A special Typescript value (which compiles down to a boolean)
* stating whether `v` is of the correct type.
*/
abstract validate(v: unknown): v is InternalRepresentation;

/**
* Gets this metrics value in its payload representation.
*
* @returns The metric value.
*/
abstract payload(): PayloadRepresentation;
}
import { Metric } from "./metric.js";

/**
* An enum representing the possible metric lifetimes.
Expand Down
75 changes: 75 additions & 0 deletions glean/src/core/metrics/metric.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* 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 { JSONValue } from "../utils.js";

/**
* The Metric class describes the shared behaviour amongst concrete metrics.
*
* A concrete metric will always have two possible representations:
*
* - `InternalRepresentation`
* - Is the format in which this metric will be stored in memory.
* - This format may contain extra metadata, in order to allow deserializing of this data for testing purposes.
* - `PayloadRepresentation`
* - Is the format in which this metric will be represented in the ping payload.
* - This format must be the exact same as described in [the Glean schema](https://github.com/mozilla-services/mozilla-pipeline-schemas/blob/master/schemas/glean/glean/glean.1.schema.json).
*/

export abstract class Metric<
InternalRepresentation extends JSONValue,
PayloadRepresentation extends JSONValue
> {
protected _inner: InternalRepresentation;

constructor(v: unknown) {
if (!this.validate(v)) {
throw new Error("Unable to create new Metric instance, values is in unexpected format.");
}

this._inner = v;
}

/**
* Gets this metrics value in its internal representation.
*
* @returns The metric value.
*/
get(): InternalRepresentation {
return this._inner;
}

/**
* Sets this metrics value.
*
* @param v The value to set, must be in the exact internal representation of this metric.
*
* @throws In case the metric is not in the expected format.
*/
set(v: unknown): void {
if (!this.validate(v)) {
console.error(`Unable to set metric to ${JSON.stringify(v)}. Value is in unexpected format. Ignoring.`);
return;
}

this._inner = v;
}

/**
* Validates that a given value is in the correct format for this metrics internal representation.
*
* @param v The value to verify.
*
* @returns A special Typescript value (which compiles down to a boolean)
* stating whether `v` is of the correct type.
*/
abstract validate(v: unknown): v is InternalRepresentation;

/**
* Gets this metrics value in its payload representation.
*
* @returns The metric value.
*/
abstract payload(): PayloadRepresentation;
}
11 changes: 11 additions & 0 deletions glean/src/core/metrics/metrics_interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/* 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 { JSONValue } from "../utils.js";

export interface Metrics {
[aMetricType: string]: {
[aMetricIdentifier: string]: JSONValue;
};
}
3 changes: 2 additions & 1 deletion glean/src/core/metrics/types/boolean.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* 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, MetricType, CommonMetricData } from "../index.js";
import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import { isBoolean } from "../../utils.js";
import Glean from "../../glean.js";

Expand Down
3 changes: 2 additions & 1 deletion glean/src/core/metrics/types/counter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* 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, MetricType, CommonMetricData } from "../index.js";
import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import { isNumber, isUndefined, JSONValue } from "../../utils.js";
import Glean from "../../glean.js";

Expand Down
3 changes: 2 additions & 1 deletion glean/src/core/metrics/types/datetime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* 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, MetricType, CommonMetricData } from "../index.js";
import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import TimeUnit from "../../metrics/time_unit.js";
import Glean from "../../glean.js";
import { isNumber, isObject, isString } from "../../utils.js";
Expand Down
3 changes: 2 additions & 1 deletion glean/src/core/metrics/types/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* 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, MetricType, CommonMetricData } from "../index.js";
import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import { isString } from "../../utils.js";
import Glean from "../../glean.js";

Expand Down
3 changes: 2 additions & 1 deletion glean/src/core/metrics/types/uuid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
import { validate as UUIDvalidate } from "uuid";

import { KNOWN_CLIENT_ID } from "../../constants.js";
import { Metric, MetricType, CommonMetricData } from "../index.js";
import { MetricType, CommonMetricData } from "../index.js";
import { Metric } from "../metric.js";
import { isString, generateUUIDv4 } from "../../utils.js";
import Glean from "../../glean.js";

Expand Down
3 changes: 2 additions & 1 deletion glean/src/core/metrics/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
* 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, LabeledMetric } from "./index.js";
import { LabeledMetric } from "./index.js";
import { Metric } from "./metric.js";
import { JSONValue } from "../utils.js";

import { BooleanMetric } from "./types/boolean.js";
Expand Down
38 changes: 1 addition & 37 deletions glean/src/core/pings/database.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,45 +3,9 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import Store from "../storage/index.js";
import { Metrics as MetricsPayload } from "../metrics/database.js";
import { isObject, isJSONValue, JSONObject, isString, JSONArray } from "../utils.js";
import { isObject, isJSONValue, JSONObject, isString } from "../utils.js";
import { StorageBuilder } from "../../platform/index.js";

export interface PingInfo extends JSONObject {
seq: number,
start_time: string,
end_time: string,
reason?: string,
}

export interface ClientInfo extends JSONObject {
client_id?: string,
locale?: string,
device_model?: string,
device_manufacturer?: string,
app_channel?: string,
// Even though all the next fields are required by the schema
// we can't guarantee that they will be present.
// Active discussion about this is happening on Bug 1685705.
app_build?: string,
app_display_version?: string,
architecture?: string,
first_run_date?: string,
os?: string,
os_version?: string,
telemetry_sdk_build: string
}

/**
* This definition must be in sync with
* the Glean ping [schema](https://github.com/mozilla-services/mozilla-pipeline-schemas/blob/master/schemas/glean/glean/glean.1.schema.json)
*/
export interface PingPayload extends JSONObject {
ping_info: PingInfo,
client_info: ClientInfo,
metrics?: MetricsPayload,
events?: JSONArray,
}
export interface PingInternalRepresentation extends JSONObject {
path: string,
payload: JSONObject,
Expand Down
2 changes: 1 addition & 1 deletion glean/src/core/pings/maker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CounterMetricType, { CounterMetric } from "../metrics/types/counter.js";
import DatetimeMetricType, { DatetimeMetric } from "../metrics/types/datetime.js";
import { Lifetime } from "../metrics/index.js";
import TimeUnit from "../metrics/time_unit.js";
import { ClientInfo, PingInfo, PingPayload } from "../pings/database.js";
import { ClientInfo, PingInfo, PingPayload } from "../pings/ping_payload.js";
import PingType from "../pings/index.js";
import Glean from "../glean.js";
import CoreEvents from "../events/index.js";
Expand Down
42 changes: 42 additions & 0 deletions glean/src/core/pings/ping_payload.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/* 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 { Metrics } from "../metrics/metrics_interface.js";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen multiple projects that have a types/ folder with all the types. Not for this PR, but I wonder if we could benefit form that. WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it might make sense :)

import { JSONObject, JSONArray } from "../utils.js";

export interface PingInfo extends JSONObject {
seq: number,
start_time: string,
end_time: string,
reason?: string,
}

export interface ClientInfo extends JSONObject {
client_id?: string,
locale?: string,
device_model?: string,
device_manufacturer?: string,
app_channel?: string,
// Even though all the next fields are required by the schema
// we can't guarantee that they will be present.
// Active discussion about this is happening on Bug 1685705.
app_build?: string,
app_display_version?: string,
architecture?: string,
first_run_date?: string,
os?: string,
os_version?: string,
telemetry_sdk_build: string
}

/**
* This definition must be in sync with
* the Glean ping [schema](https://github.com/mozilla-services/mozilla-pipeline-schemas/blob/master/schemas/glean/glean/glean.1.schema.json)
*/
export interface PingPayload extends JSONObject {
ping_info: PingInfo,
client_info: ClientInfo,
metrics?: Metrics,
events?: JSONArray,
}
2 changes: 1 addition & 1 deletion glean/src/plugins/encryption.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import calculateThumbprint from "jose/jwk/thumbprint";
import { JWK } from "jose/types";

import Plugin from "./index.js";
import { PingPayload } from "../core/pings/database.js";
import { PingPayload } from "../core/pings/ping_payload.js";
import { JSONObject } from "../core/utils.js";
import CoreEvents from "../core/events/index.js";

Expand Down
Loading