70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
120 lines
3.5 KiB
TypeScript
120 lines
3.5 KiB
TypeScript
import type { ReadyAnalytics } from "./types";
|
|
|
|
// This will allow us to make breaking changes to the analytic schema
|
|
const VERSION = 1;
|
|
|
|
export enum STATIC_ROUTING_DECISION {
|
|
NOT_PROVIDED = 0,
|
|
NOT_ROUTED = 1,
|
|
ROUTED = 2,
|
|
}
|
|
|
|
export enum DISPATCH_TYPE {
|
|
ASSETS = "asset",
|
|
WORKER = "worker",
|
|
}
|
|
|
|
// When adding new columns please update the schema
|
|
type Data = {
|
|
// -- Indexes --
|
|
accountId?: number;
|
|
scriptId?: number;
|
|
|
|
// -- Doubles --
|
|
// double1 - The time it takes for the whole request to complete in milliseconds
|
|
requestTime?: number;
|
|
// double2 - Colo ID
|
|
coloId?: number;
|
|
// double3 - Metal ID
|
|
metalId?: number;
|
|
// double4 - Colo tier (e.g. tier 1, tier 2, tier 3)
|
|
coloTier?: number;
|
|
// double5 - Run user worker ahead of assets
|
|
userWorkerAhead?: boolean;
|
|
// double6 - Routing performed based on the _routes.json (if provided)
|
|
staticRoutingDecision?: STATIC_ROUTING_DECISION;
|
|
// double7 - Whether the request was blocked by abuse mitigation or not
|
|
abuseMitigationBlocked?: boolean;
|
|
// double8 - User worker invocation denied due to free tier limiting
|
|
userWorkerFreeTierLimiting?: boolean;
|
|
// double9 - The time it takes for the request to be handed off the Asset Worker or user Worker in milliseconds
|
|
timeToDispatch?: number;
|
|
|
|
// -- Blobs --
|
|
// blob1 - Hostname of the request
|
|
hostname?: string;
|
|
// blob2 - Dispatch type - what kind of thing did we dispatch
|
|
dispatchtype?: DISPATCH_TYPE;
|
|
// blob3 - Error message
|
|
error?: string;
|
|
// blob4 - The current version UUID of router-server
|
|
version?: string;
|
|
// blob5 - Region of the colo (e.g. WEUR)
|
|
coloRegion?: string;
|
|
// blob6 - URL for analysis
|
|
abuseMitigationURLHost?: string;
|
|
// blob7 - XSS detection href parameter value
|
|
xssDetectionImageHref?: string;
|
|
// blob8 - cdn-cgi backslash bypass attempt URL
|
|
cdnCgiBackslashBypassUrl?: string;
|
|
};
|
|
|
|
export class Analytics {
|
|
private data: Data = {};
|
|
private readyAnalytics?: ReadyAnalytics;
|
|
private hasWritten: boolean = false;
|
|
|
|
constructor(readyAnalytics?: ReadyAnalytics) {
|
|
this.readyAnalytics = readyAnalytics;
|
|
}
|
|
|
|
setData(newData: Partial<Data>) {
|
|
this.data = { ...this.data, ...newData };
|
|
}
|
|
|
|
getData(key: keyof Data) {
|
|
return this.data[key];
|
|
}
|
|
|
|
write() {
|
|
if (this.hasWritten) {
|
|
// We've already written analytics, don't double send
|
|
return;
|
|
} else if (!this.readyAnalytics) {
|
|
// Local environment, no-op
|
|
return;
|
|
}
|
|
|
|
this.hasWritten = true;
|
|
|
|
this.readyAnalytics.logEvent({
|
|
version: VERSION,
|
|
accountId: this.data.accountId,
|
|
indexId: this.data.scriptId?.toString(),
|
|
doubles: [
|
|
this.data.requestTime ?? -1, // double1
|
|
this.data.coloId ?? -1, // double2
|
|
this.data.metalId ?? -1, // double3
|
|
this.data.coloTier ?? -1, // double4
|
|
this.data.userWorkerAhead === undefined // double5
|
|
? -1
|
|
: Number(this.data.userWorkerAhead),
|
|
this.data.staticRoutingDecision ?? STATIC_ROUTING_DECISION.NOT_PROVIDED, // double6
|
|
this.data.abuseMitigationBlocked ? 1 : 0, // double7
|
|
this.data.userWorkerFreeTierLimiting ? 1 : 0, // double8
|
|
this.data.timeToDispatch ?? -1, // double9
|
|
],
|
|
blobs: [
|
|
this.data.hostname?.substring(0, 256), // blob1 - trim to 256 bytes
|
|
this.data.dispatchtype, // blob2
|
|
this.data.error?.substring(0, 256), // blob3 - trim to 256 bytes
|
|
this.data.version, // blob4
|
|
this.data.coloRegion, // blob5
|
|
this.data.abuseMitigationURLHost, // blob6
|
|
this.data.xssDetectionImageHref, // blob7
|
|
this.data.cdnCgiBackslashBypassUrl?.substring(0, 256), // blob8 - trim to 256 bytes
|
|
],
|
|
});
|
|
}
|
|
}
|