SelfServe - Telemetry and Localization improvements (#617)
* made selfServeTelemetry use existing functions * removed "data" from SelfServeTelemetryType * fixed localization bugs * added comment
This commit is contained in:
parent
b150e53814
commit
250faa5206
|
@ -1,8 +1,8 @@
|
||||||
{
|
{
|
||||||
"DedicatedGatewayDescription": "Provision a dedicated gateway cluster for your Azure Cosmos DB account. A dedicated gateway is compute that is a front-end to data in your Azure Cosmos DB account. Your dedicated gateway automatically includes the integrated cache, which can improve read performance.",
|
"DedicatedGatewayDescription": "Provision a dedicated gateway cluster for your Azure Cosmos DB account. A dedicated gateway is compute that is a front-end to data in your Azure Cosmos DB account. Your dedicated gateway automatically includes the integrated cache, which can improve read performance.",
|
||||||
"DedicatedGateway": "Dedicated Gateway",
|
"DedicatedGateway": "Dedicated Gateway",
|
||||||
"Enable": "Enable",
|
"Provisioned": "Provisioned",
|
||||||
"Disable": "Disable",
|
"Deprovisioned": "Deprovisioned",
|
||||||
"LearnAboutDedicatedGateway": "Learn more about dedicated gateway.",
|
"LearnAboutDedicatedGateway": "Learn more about dedicated gateway.",
|
||||||
"DeprovisioningDetailsText": "Learn more about deprovisioning the dedicated gateway.",
|
"DeprovisioningDetailsText": "Learn more about deprovisioning the dedicated gateway.",
|
||||||
"DedicatedGatewayPricing": "Learn more about dedicated gateway pricing.",
|
"DedicatedGatewayPricing": "Learn more about dedicated gateway pricing.",
|
||||||
|
|
|
@ -23,9 +23,11 @@ const loadTranslationFile = async (className: string): Promise<void> => {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
let translations: any;
|
let translations: any;
|
||||||
try {
|
try {
|
||||||
translations = await import(`../Localization/${language}/${fileName}`);
|
translations = await import(
|
||||||
|
/* webpackChunkName: "Localization-[request]" */ `../Localization/${language}/${fileName}`
|
||||||
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
translations = await import(`../Localization/en/${fileName}`);
|
translations = await import(/* webpackChunkName: "Localization-en-[request]" */ `../Localization/en/${fileName}`);
|
||||||
}
|
}
|
||||||
i18n.addResourceBundle(language, className, translations.default, true);
|
i18n.addResourceBundle(language, className, translations.default, true);
|
||||||
};
|
};
|
||||||
|
@ -39,12 +41,12 @@ const getDescriptor = async (selfServeType: SelfServeType): Promise<SelfServeDes
|
||||||
switch (selfServeType) {
|
switch (selfServeType) {
|
||||||
case SelfServeType.example: {
|
case SelfServeType.example: {
|
||||||
const SelfServeExample = await import(/* webpackChunkName: "SelfServeExample" */ "./Example/SelfServeExample");
|
const SelfServeExample = await import(/* webpackChunkName: "SelfServeExample" */ "./Example/SelfServeExample");
|
||||||
await loadTranslations(SelfServeExample.default.name);
|
await loadTranslations("SelfServeExample");
|
||||||
return new SelfServeExample.default().toSelfServeDescriptor();
|
return new SelfServeExample.default().toSelfServeDescriptor();
|
||||||
}
|
}
|
||||||
case SelfServeType.sqlx: {
|
case SelfServeType.sqlx: {
|
||||||
const SqlX = await import(/* webpackChunkName: "SqlX" */ "./SqlX/SqlX");
|
const SqlX = await import(/* webpackChunkName: "SqlX" */ "./SqlX/SqlX");
|
||||||
await loadTranslations(SqlX.default.name);
|
await loadTranslations("SqlX");
|
||||||
return new SqlX.default().toSelfServeDescriptor();
|
return new SqlX.default().toSelfServeDescriptor();
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1,69 +1,24 @@
|
||||||
import { sendMessage } from "../Common/MessageHandler";
|
|
||||||
import { configContext } from "../ConfigContext";
|
|
||||||
import { SelfServeMessageTypes } from "../Contracts/SelfServeContracts";
|
import { SelfServeMessageTypes } from "../Contracts/SelfServeContracts";
|
||||||
import { appInsights } from "../Shared/appInsights";
|
|
||||||
import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants";
|
import { Action, ActionModifiers } from "../Shared/Telemetry/TelemetryConstants";
|
||||||
import { userContext } from "../UserContext";
|
import { trace, traceCancel, traceFailure, traceStart, traceSuccess } from "../Shared/Telemetry/TelemetryProcessor";
|
||||||
import { SelfServeTelemetryMessage } from "./SelfServeTypes";
|
import { SelfServeTelemetryMessage } from "./SelfServeTypes";
|
||||||
|
|
||||||
const action = Action.SelfServe;
|
export const selfServeTrace = (data: SelfServeTelemetryMessage): void => {
|
||||||
|
trace(Action.SelfServe, ActionModifiers.Mark, data, SelfServeMessageTypes.TelemetryInfo);
|
||||||
export const trace = (data: SelfServeTelemetryMessage): void => {
|
|
||||||
sendSelfServeTelemetryMessage(ActionModifiers.Mark, data);
|
|
||||||
appInsights.trackEvent({ name: Action[action] }, decorateData(data, ActionModifiers.Mark));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const traceStart = (data: SelfServeTelemetryMessage): number => {
|
export const selfServeTraceStart = (data: SelfServeTelemetryMessage): number => {
|
||||||
const timestamp: number = Date.now();
|
return traceStart(Action.SelfServe, data, SelfServeMessageTypes.TelemetryInfo);
|
||||||
sendSelfServeTelemetryMessage(ActionModifiers.Start, data);
|
|
||||||
appInsights.startTrackEvent(Action[action]);
|
|
||||||
return timestamp;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const traceSuccess = (data: SelfServeTelemetryMessage, timestamp?: number): void => {
|
export const selfServeTraceSuccess = (data: SelfServeTelemetryMessage, timestamp?: number): void => {
|
||||||
sendSelfServeTelemetryMessage(ActionModifiers.Success, data, timestamp || Date.now());
|
traceSuccess(Action.SelfServe, data, timestamp, SelfServeMessageTypes.TelemetryInfo);
|
||||||
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Success));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const traceFailure = (data: SelfServeTelemetryMessage, timestamp?: number): void => {
|
export const selfServeTraceFailure = (data: SelfServeTelemetryMessage, timestamp?: number): void => {
|
||||||
sendSelfServeTelemetryMessage(ActionModifiers.Failed, data, timestamp || Date.now());
|
traceFailure(Action.SelfServe, data, timestamp, SelfServeMessageTypes.TelemetryInfo);
|
||||||
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Failed));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const traceCancel = (data: SelfServeTelemetryMessage, timestamp?: number): void => {
|
export const selfServeTraceCancel = (data: SelfServeTelemetryMessage, timestamp?: number): void => {
|
||||||
sendSelfServeTelemetryMessage(ActionModifiers.Cancel, data, timestamp || Date.now());
|
traceCancel(Action.SelfServe, data, timestamp, SelfServeMessageTypes.TelemetryInfo);
|
||||||
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Cancel));
|
|
||||||
};
|
|
||||||
|
|
||||||
const sendSelfServeTelemetryMessage = (
|
|
||||||
actionModifier: string,
|
|
||||||
data: SelfServeTelemetryMessage,
|
|
||||||
timeStamp?: number
|
|
||||||
): void => {
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const dataToSend: any = {
|
|
||||||
type: SelfServeMessageTypes.TelemetryInfo,
|
|
||||||
data: {
|
|
||||||
action: Action[action],
|
|
||||||
actionModifier: actionModifier,
|
|
||||||
data: JSON.stringify(decorateData(data)),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
if (timeStamp) {
|
|
||||||
dataToSend.data.timeStamp = timeStamp;
|
|
||||||
}
|
|
||||||
sendMessage(dataToSend);
|
|
||||||
};
|
|
||||||
|
|
||||||
const decorateData = (data: SelfServeTelemetryMessage, actionModifier?: string) => {
|
|
||||||
return {
|
|
||||||
databaseAccountName: userContext.databaseAccount?.name,
|
|
||||||
defaultExperience: userContext.defaultExperience,
|
|
||||||
authType: userContext.authType,
|
|
||||||
subscriptionId: userContext.subscriptionId,
|
|
||||||
platform: configContext.platform,
|
|
||||||
env: process.env.NODE_ENV,
|
|
||||||
actionModifier,
|
|
||||||
...data,
|
|
||||||
} as { [key: string]: string };
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { TelemetryData } from "../Shared/Telemetry/TelemetryProcessor";
|
||||||
|
|
||||||
interface BaseInput {
|
interface BaseInput {
|
||||||
dataFieldName: string;
|
dataFieldName: string;
|
||||||
errorMessage?: string;
|
errorMessage?: string;
|
||||||
|
@ -158,8 +160,6 @@ export interface RefreshParams {
|
||||||
retryIntervalInMs: number;
|
retryIntervalInMs: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SelfServeTelemetryMessage {
|
export interface SelfServeTelemetryMessage extends TelemetryData {
|
||||||
selfServeClassName: string;
|
selfServeClassName: string;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
data?: any;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import { IsDisplayable, OnChange, RefreshOptions, Values } from "../Decorators";
|
import { IsDisplayable, OnChange, RefreshOptions, Values } from "../Decorators";
|
||||||
import { trace } from "../SelfServeTelemetryProcessor";
|
import { selfServeTrace } from "../SelfServeTelemetryProcessor";
|
||||||
import {
|
import {
|
||||||
ChoiceItem,
|
ChoiceItem,
|
||||||
Description,
|
Description,
|
||||||
|
@ -177,7 +177,7 @@ export default class SqlX extends SelfServeBaseClass {
|
||||||
currentValues: Map<string, SmartUiInput>,
|
currentValues: Map<string, SmartUiInput>,
|
||||||
baselineValues: Map<string, SmartUiInput>
|
baselineValues: Map<string, SmartUiInput>
|
||||||
): Promise<OnSaveResult> => {
|
): Promise<OnSaveResult> => {
|
||||||
trace({ selfServeClassName: "SqlX" });
|
selfServeTrace({ selfServeClassName: "SqlX" });
|
||||||
|
|
||||||
const dedicatedGatewayCurrentlyEnabled = currentValues.get("enableDedicatedGateway")?.value as boolean;
|
const dedicatedGatewayCurrentlyEnabled = currentValues.get("enableDedicatedGateway")?.value as boolean;
|
||||||
const dedicatedGatewayOriginallyEnabled = baselineValues.get("enableDedicatedGateway")?.value as boolean;
|
const dedicatedGatewayOriginallyEnabled = baselineValues.get("enableDedicatedGateway")?.value as boolean;
|
||||||
|
@ -234,7 +234,7 @@ export default class SqlX extends SelfServeBaseClass {
|
||||||
portalNotification: {
|
portalNotification: {
|
||||||
initialize: {
|
initialize: {
|
||||||
titleTKey: "CreateInitializeTitle",
|
titleTKey: "CreateInitializeTitle",
|
||||||
messageTKey: "CreateInitializeTitle",
|
messageTKey: "CreateInitializeMessage",
|
||||||
},
|
},
|
||||||
success: {
|
success: {
|
||||||
titleTKey: "CreateSuccessTitle",
|
titleTKey: "CreateSuccessTitle",
|
||||||
|
|
|
@ -1,15 +1,25 @@
|
||||||
import { sendMessage } from "../../Common/MessageHandler";
|
import { sendMessage } from "../../Common/MessageHandler";
|
||||||
import { configContext } from "../../ConfigContext";
|
import { configContext } from "../../ConfigContext";
|
||||||
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
import { MessageTypes } from "../../Contracts/ExplorerContracts";
|
||||||
|
import { SelfServeMessageTypes } from "../../Contracts/SelfServeContracts";
|
||||||
import { userContext } from "../../UserContext";
|
import { userContext } from "../../UserContext";
|
||||||
import { appInsights } from "../appInsights";
|
import { appInsights } from "../appInsights";
|
||||||
import { Action, ActionModifiers } from "./TelemetryConstants";
|
import { Action, ActionModifiers } from "./TelemetryConstants";
|
||||||
|
|
||||||
type TelemetryData = { [key: string]: unknown };
|
// Right now, the ExplorerContracts has MessageTypes as a numeric enum (TelemetryInfo = 0) while the SelfServeContracts
|
||||||
|
// has MessageTypes as a string enum (TelemetryInfo = "TelemetryInfo"). We should move to string enums for all use cases.
|
||||||
|
type TelemetryType = MessageTypes.TelemetryInfo | SelfServeMessageTypes.TelemetryInfo;
|
||||||
|
|
||||||
export function trace(action: Action, actionModifier: string = ActionModifiers.Mark, data: TelemetryData = {}): void {
|
export type TelemetryData = { [key: string]: unknown };
|
||||||
|
|
||||||
|
export function trace(
|
||||||
|
action: Action,
|
||||||
|
actionModifier: string = ActionModifiers.Mark,
|
||||||
|
data: TelemetryData = {},
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): void {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: actionModifier,
|
actionModifier: actionModifier,
|
||||||
|
@ -20,10 +30,14 @@ export function trace(action: Action, actionModifier: string = ActionModifiers.M
|
||||||
appInsights.trackEvent({ name: Action[action] }, decorateData(data, actionModifier));
|
appInsights.trackEvent({ name: Action[action] }, decorateData(data, actionModifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceStart(action: Action, data?: TelemetryData): number {
|
export function traceStart(
|
||||||
|
action: Action,
|
||||||
|
data?: TelemetryData,
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): number {
|
||||||
const timestamp: number = Date.now();
|
const timestamp: number = Date.now();
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: ActionModifiers.Start,
|
actionModifier: ActionModifiers.Start,
|
||||||
|
@ -36,9 +50,14 @@ export function traceStart(action: Action, data?: TelemetryData): number {
|
||||||
return timestamp;
|
return timestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceSuccess(action: Action, data?: TelemetryData, timestamp?: number): void {
|
export function traceSuccess(
|
||||||
|
action: Action,
|
||||||
|
data?: TelemetryData,
|
||||||
|
timestamp?: number,
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): void {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: ActionModifiers.Success,
|
actionModifier: ActionModifiers.Success,
|
||||||
|
@ -50,9 +69,14 @@ export function traceSuccess(action: Action, data?: TelemetryData, timestamp?: n
|
||||||
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Success));
|
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Success));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceFailure(action: Action, data?: TelemetryData, timestamp?: number): void {
|
export function traceFailure(
|
||||||
|
action: Action,
|
||||||
|
data?: TelemetryData,
|
||||||
|
timestamp?: number,
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): void {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: ActionModifiers.Failed,
|
actionModifier: ActionModifiers.Failed,
|
||||||
|
@ -64,9 +88,14 @@ export function traceFailure(action: Action, data?: TelemetryData, timestamp?: n
|
||||||
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Failed));
|
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Failed));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceCancel(action: Action, data?: TelemetryData, timestamp?: number): void {
|
export function traceCancel(
|
||||||
|
action: Action,
|
||||||
|
data?: TelemetryData,
|
||||||
|
timestamp?: number,
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): void {
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: ActionModifiers.Cancel,
|
actionModifier: ActionModifiers.Cancel,
|
||||||
|
@ -78,10 +107,15 @@ export function traceCancel(action: Action, data?: TelemetryData, timestamp?: nu
|
||||||
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Cancel));
|
appInsights.stopTrackEvent(Action[action], decorateData(data, ActionModifiers.Cancel));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceOpen(action: Action, data?: TelemetryData, timestamp?: number): number {
|
export function traceOpen(
|
||||||
|
action: Action,
|
||||||
|
data?: TelemetryData,
|
||||||
|
timestamp?: number,
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): number {
|
||||||
const validTimestamp = timestamp || Date.now();
|
const validTimestamp = timestamp || Date.now();
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: ActionModifiers.Open,
|
actionModifier: ActionModifiers.Open,
|
||||||
|
@ -94,10 +128,15 @@ export function traceOpen(action: Action, data?: TelemetryData, timestamp?: numb
|
||||||
return validTimestamp;
|
return validTimestamp;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function traceMark(action: Action, data?: TelemetryData, timestamp?: number): number {
|
export function traceMark(
|
||||||
|
action: Action,
|
||||||
|
data?: TelemetryData,
|
||||||
|
timestamp?: number,
|
||||||
|
type: TelemetryType = MessageTypes.TelemetryInfo
|
||||||
|
): number {
|
||||||
const validTimestamp = timestamp || Date.now();
|
const validTimestamp = timestamp || Date.now();
|
||||||
sendMessage({
|
sendMessage({
|
||||||
type: MessageTypes.TelemetryInfo,
|
type: type,
|
||||||
data: {
|
data: {
|
||||||
action: Action[action],
|
action: Action[action],
|
||||||
actionModifier: ActionModifiers.Mark,
|
actionModifier: ActionModifiers.Mark,
|
||||||
|
|
Loading…
Reference in New Issue